6 个版本
0.2.2 | 2021 年 9 月 23 日 |
---|---|
0.2.1 | 2021 年 9 月 23 日 |
0.2.0 | 2021 年 3 月 20 日 |
0.1.1 | 2021 年 3 月 15 日 |
0.0.0 |
|
#1215 in Rust 模式
33KB
696 行
Genesis - 一个 ECS 生成库
概述
genesis
提供了一个 ECS 生成宏。
与其他在运行时进行动态借用检查的 ECS 库和框架不同,你事先定义所有组件,生成一个完全静态类型的 ECS,借用检查在编译时进行。
不再需要在函数间传递 World,以避免遇到动态借用检查问题!
genesis
是一个轻量级的 ECS 库,不提供任何调度功能。相反,你可以直接查询每个组件类型的存储。
use genesis::*;
#[derive(Clone, Debug, Eq, PartialEq)]
struct IndexComponent {
index: usize,
}
#[derive(Clone, Debug, Eq, PartialEq)]
struct NameComponent {
name: String,
}
#[derive(Clone, Debug, Eq, PartialEq)]
struct RareComponent {
data: u32,
}
#[world(MyComponent, Template)]
#[derive(Clone, Debug, Eq, PartialEq)]
struct World {
#[component(vec)] //default, optional
#[template_name(index)]
indices: IndexComponent,
#[template_name(name)]
names: NameComponent,
#[component(map)]
rare_data: RareComponent,
}
fn main() -> Result<(), NoSuchEntity> {
let initial_capacity = 1024;
let mut world = World::new(initial_capacity);
// spawn an entity
let id_a = world.spawn();
// set the components directly on the corresponding storage
world.indices.set(id_a, IndexComponent { index: 42 })?;
// spawn another entity
let id_b = world.spawn();
// alternative way to set components: using the utility trait Register<T>.
world.register(id_b, IndexComponent { index: 0 })?;
world.register(
id_b,
NameComponent {
name: String::from("B"),
},
)?;
let id_c = world.spawn();
// third way of setting components: using the generated Template struct.
world.register(
id_c,
Template {
index: Some(IndexComponent { index: 100 }),
..Default::default()
},
)?;
if let Some(a_index) = world.indices.get(id_a) {
println!("first entity has index {:?}", a_index);
}
for id in world.entities.read().unwrap().iter() {
if let Some(index) = world.indices.get(id) {
println!("entity {:?} has index {:?}", id, index);
}
}
Ok(())
}
目标
genesis
的主要目标是提供一个具有编译时借用检查的类型安全 ECS。
这有助于避免编写在循环遍历实体时传递 ECS 世界到另一个函数,同时保留调用函数中的可变引用的代码,这会导致运行时借用检查问题。
其他 ECS
Rust 中有很多不同的 ECS,各有优缺点。特别是检查这些
基准测试
性能不是 genesis
的主要目标;ECS 的主要优势是这种范式所支持的数据建模。
如果你有严重的时间限制,并且需要遍历数十万个实体,你应该考虑使用像 hecs
这样的架构 ECS,以获得更好的迭代速度,这是通过更好的数据局部性和缓存友好性实现的。请注意,基于架构的 ECS 通常在添加/删除组件方面以更差的性能换取更好的迭代时间,与像 specs
或 genesis
这样的 ECS 相比,它们有不同的存储。有关更多信息,请参阅 基准测试。
许可
许可协议
- MIT 许可证
- Apache 许可证 2.0
贡献
欢迎贡献!除非明确说明,否则你的贡献将被假设为与 genesis
相同的许可证(见上方)。
依赖项
~1.5MB
~41K SLoC