Bevy Entity 实体设计
ZoOL 对 Bevy Entity 结构的源码级解读,解释分代索引如何解决 ECS 中的 ABA 问题。
源码结构
pub struct Entity {
index: u32,
generation: NonZeroU32,
}打印输出示例: 1v1 = index 1, generation 1
问题来源: ABA 问题
ECS 架构会涉及大量实体创建/销毁,需要回收 ID。仅用 usize 索引会导致 ABA 问题:
1. 创建 A, index=0
2. 创建 B, index=1
3. A 保存了 B 的索引 1
4. 删除 B
5. 创建 C, 回收了 index=1
6. A 用 index=1 查询,以为是 B,实际是 C → 错误
解决方案: 分代索引 (Generational Indices)
复合索引,由两部分组成:
- Index: 唯一标识符,用于快速查找
- Generation: 计数器,区分同一索引在不同时间点上引用的对象
生命周期
创建 A → key(0, gen=1)
删除 A → 条目 gen 增至 2
回收创建 B → key(0, gen=2) → 新生成
A 的旧引用 → key(0, gen=1) → 与条目 gen=2 不匹配 → 返回空/无效
关键设计决策
NonZeroU32用于 generation — 允许Option<Entity>使用 niche optimization,节省空间- u32 不是 usize — 64 位平台上仍保持 8 字节,但尝试减小内存占用
- index 重用、generation 递增 — 确保旧引用失效
参考资料
文件位置
/Users/zool/workspace/ZoOL's Valut/Bevy Entity 实体设计.md