Skip to main content

Crate renew_ecs

Crate renew_ecs 

Source
Expand description

Entities and component storage, with a defined iteration order.

Two pieces. Entities hands out and recycles entity handles; Store<T> holds components of one type, addressed by entity slot. A caller keeps one store per component type and joins them with join.

§Contract

  • Every query iterates in ascending entity-slot order. This is a promise, not an artifact of the representation, and it is the reason the storage was chosen the way it was. A system’s result therefore cannot depend on the order components happened to be inserted or removed in, which is what makes determinism structural rather than a rule every future contributor must remember.
  • A stale handle is dead, not dangerous. An entity is a slot plus a generation; reusing a slot bumps its generation, so a handle to a despawned entity fails Entities::is_alive instead of quietly naming whatever took its place.
  • Ordered iteration costs the gaps. It walks slots, so it is proportional to the highest occupied slot rather than to the number of components. Entities::spawn reuses low slots first to keep that range tight, and Store::iter_unordered exists for systems that genuinely do not care.

§What this is not

There is no type map: a caller holds its stores explicitly rather than asking a world for Store<Position> by type. That is a real feature and it is deliberately absent — it needs a design for how systems declare what they touch, and there is no system yet to design against. Nothing here allocates from an engine allocator, spawns a thread, or reads a clock.

§Example

use renew_ecs::{Entities, Store, join};

let mut entities = Entities::new();
let mut position = Store::new();
let mut health = Store::new();

let hero = entities.spawn();
let rock = entities.spawn();
position.insert(hero.index(), (0_i32, 0_i32));
position.insert(rock.index(), (5, 5));
health.insert(hero.index(), 100_u32);

// Only the hero has both, and joins always run in slot order.
let both: Vec<u32> = join(&position, &health).map(|(slot, _, _)| slot).collect();
assert_eq!(both, vec![hero.index()]);

Structs§

Entities
Hands out entity slots and recycles them.
Entity
A handle to an entity, valid only while its generation matches.
Store
Components of one type, addressed by entity slot.

Functions§

join
Every entity present in both stores, in ascending slot order.