26个版本
0.5.10 | 2022年4月8日 |
---|---|
0.5.8 | 2022年3月31日 |
0.3.3 | 2021年10月21日 |
541 在 游戏开发
每月 99 次下载
在 4 crates 中使用
170KB
3.5K SLoC
XECS
一个实体-组件-系统库
简单示例
// Define two components struct
// Component is Send + Sync + 'static
#[derive(Debug,Copy)]
struct Position{
x : f32,
y : f32
};
struct Hidden;
// create an empty world
let mut world = World::new();
// generate 10 entities
for _ in 0..10 {
let x = random();
lety = random();
// andomly generate the positions
world.create_entity()
.attach(Position { x,y });
}
// print all postions
for pos in world.query::<&Position>() {
print!("{:?}",pos)
}
// filter some entities need to be hidden
let ids = world.query::<&Position>()
.with_id()
.filter(|(_,_)|random())
.map(|(id,_)|id)
.collect::<Vec<_>>();
// attach hidden to id
for id in ids {
world.attach_component(id,Hidden);
}
// make a full-owning group to accelerate the query
world.make_group(full_owning::<Hidden,Position>());
// only print postions with id that is not hidden
for (id,data) in world.query::<&Position,Without<&Hidden>>() {
print!("{}:{:?}",id,data);
}
关于实体
在XECS中,实体只是一个数字ID。在XECS中,它只是一个 NonZeroUsize。ID由世界自动分配,从1开始。通过 Option<EntityId>,
id=0
代表一个没有其他标记的回收ID。
ID回收
当你调用 world.create_entity()
时,会自动分配一个ID。如果你调用 world.remove_entity(id)
,这个ID将成为一个空位。如果下一个 world.create_entity()
被调用,它将分配这个ID来填充空位。由于使用了稀疏集合,无论ID多么随机,迭代所有组件仍然很快。
并发安全性
因为 组件 只是 T : Send + Sync
。 世界 可以使用 RwLock 来确保所有组件的借用检查关系。并且 世界 也可以是 Send + Sync
。因此,所有其他世界状态都可以由 RwLock 保护。所以我们可以通过 RwLock<World>
在并发环境中使用世界。
XECS中的系统
系统是一个以 World 为上下文的 Stream。由于 Stream 在 std 中不稳定,XECS使用 futures::Stream 代替。
运行系统
依赖项
~1–6MB
~27K SLoC