9个版本 (5个破坏性更新)

0.6.0 2024年5月19日
0.5.0 2024年4月7日
0.4.2 2024年3月25日
0.3.0 2024年2月14日
0.1.0 2023年11月4日

#173 in 游戏开发

每月下载量 26

MIT许可证

340KB
7K SLoC

Evenio

evenio 是一个基于原型的 实体组件系统 框架,用于构建事件驱动的程序。它旨在提供一组小巧但功能强大的特性,易于使用且效率高。

特性

  • 除了常见的实体、组件和系统之外,evenio 引入了事件作为一等公民。而不是限制系统按固定顺序每帧/更新运行一次,系统被泛化为事件处理器。整个程序的流程控制由处理器之间的事件流定义。
  • 世界的结构变化(如实体销毁、组件添加/删除等)由事件中介,允许处理器钩入其发生。
  • 目标事件使处理器能够根据查询有效地过滤事件。
  • 组件类型、事件类型和处理器与代数索引相关联,允许它们动态地添加和删除。
  • Rayon 并行执行查询。
  • 世界数据没有 SendSync 要求。
  • no_std 支持。

有关完整介绍,请阅读 教程书籍 📚

示例

以下是我们在 evenio 中创建简单游戏循环的方式

use evenio::prelude::*;

// Define position and velocity components.
#[derive(Component)]
struct Position {
    x: f32,
    y: f32,
}

#[derive(Component)]
struct Velocity {
    x: f32,
    y: f32,
}

// Events can carry data, but for this example we only need a unit struct.
#[derive(GlobalEvent)]
struct Tick;

pub fn main() {
    // Create a new `World` to store all our data.
    let mut world = World::new();

    // Spawn a new entity and add the `Position` and `Velocity` components to it.
    // We'll store the entity's ID in a variable for later use.
    let e = world.spawn();
    world.insert(e, Position { x: 0.0, y: 0.0 });
    world.insert(e, Velocity { x: 1.0, y: 0.4 });

    // Add our event handler to the world.
    world.add_handler(update_positions);

    // Run our fake "game loop" by sending the `Tick` event every update.
    for _ in 0..50 {
        world.send(Tick);
    }

    // Get the `Position` component from the entity we added earlier.
    let pos = world.get::<Position>(e).unwrap();

    println!("Final position of the entity: ({}, {})", pos.x, pos.y);
}

// The `Receiver<Tick>` parameter tells our handler to listen for the `Tick` event.
fn update_positions(_: Receiver<Tick>, entities: Fetcher<(&mut Position, &Velocity)>) {
    // Loop over all entities with both the `Position` and `Velocity` components, and update their positions.
    for (pos, vel) in entities {
        pos.x += vel.x;
        pos.y += vel.y;
    }
}

功能标志

  • std (默认启用):启用对标准库的支持。没有这个,evenio 仅依赖于 corealloc
  • rayon:为 Fetcher 添加并行迭代器支持。使用 Rayon 库。

依赖

~1.8–3MB
~53K SLoC