Tiny ECS
The intention of this crate is that a basic ECS is provided, where
you will be required to exercise a little additional control.
Where most other ECS crates provide a mechanism for inserting "systems"
in to the ECS to run against entities, this one leaves it out - you can
think of it as a "system for entity/components". You will need to create
external systems; these can be a function, a loop, or anything else.
Internally this ECS is the use of bitmasks. Each entity ID is in
practice an internal index number in to an array which contains bitmasks.
The bitmasks themselves keep track of what components the entity has.
Note: borrows of Persist are checked at runtime, but there are also
some unchecked borrows provided.
Examples
Demonstrating use
use tiny_ecs::Entities;
use tiny_ecs::ECSError;
struct Vector1 {
x: i32,
}
struct Vector2 {
x: i32,
y: i32,
}
struct Vector3 {
x: i32,
y: i32,
z: i32,
}
# fn main() -> Result<(), ECSError> {
let mut entities = Entities::new(Some(3), Some(3));
let entity_1 = entities.new_entity()
.with(Vector1 { x: 42 })?
.with(Vector3 { x: 3, y: 10, z: -12 })?
.finalise()?;
assert_eq!(entity_1, 0);
entities.new_entity()
.with(Vector2 { x: 66, y: 6 })?
.with(Vector1 { x: 6 })?
.finalise()?;
# Ok(())
# }
Access an entities part of type <T>
# use tiny_ecs::Entities;
# use tiny_ecs::ECSError;
# fn main() -> Result<(), ECSError> {
struct Vector3 {x: i32, y: i32, z: i32 }
# let mut entities = Entities::new(Some(3), Some(3));
# let entity_1 = entities.new_entity()
# .with(Vector3 { x: 3, y: 10, z: -12 })?
# .finalise()?;
let mut components = entities
.borrow_mut::<Vector3>()?;
let mut part = components.get_mut(entity_1).unwrap();
assert_eq!(part.z, -12);
# Ok(())
# }
Check if Entity contains a part type + remove part
# use tiny_ecs::Entities;
# use tiny_ecs::ECSError;
# fn main() -> Result<(), ECSError> {
struct Vector1 {x: i32 }
# let mut entities = Entities::new(Some(3), Some(3));
let entity_1 = entities.new_entity()
.with(Vector1 { x: 3 })?
.finalise()?;
if entities.entity_contains::<Vector1>(entity_1) {
assert!(entities.rm_component_from::<Vector1>(entity_1).is_ok());
}
assert_eq!(entities.entity_contains::<Vector1>(entity_1), false);
# Ok(())
# }
A system that uses an get_mut()
# use tiny_ecs::{Entities, Persist};
# use tiny_ecs::ECSError;
# fn main() -> Result<(), ECSError> {
struct Vector1 {x: i32 }
# let mut entities = Entities::new(Some(3), Some(3));
# entities.new_entity().with(Vector1 { x: 3 })?.finalise()?;
fn some_system(mut components: &mut Persist<Vector1>) {
for (k, v) in components.iter_mut().enumerate() {
v.x += 1;
assert!(v.x > k as i32);
}
}
# let mut components = entities.borrow_mut::<Vector1>()?;
some_system(&mut components);
# Ok(())
# }
Get components for an entity ID list
# use tiny_ecs::{Entities, Persist};
# use tiny_ecs::ECSError;
# fn main() -> Result<(), ECSError> {
struct Vector1 {x: i32 }
# let mut entities = Entities::new(Some(3), Some(3));
# entities.new_entity().with(Vector1 { x: 3 })?.finalise()?;
fn second_system(active: &[usize], mut v1_map: &mut Persist<Vector1>) {
for id in active {
if let Some(part) = v1_map.get_mut(*id) {
part.x = 42;
}
}
}
# let mut components = entities.borrow_mut::<Vector1>()?;
second_system(&[0, 1, 2], &mut components);
# Ok(())
# }
A more complex system using Persists directly
# use tiny_ecs::Entities;
# use tiny_ecs::ECSError;
# fn main() -> Result<(), ECSError> {
# struct Vector1 {x: i32 }
# struct Vector2 {x: i32, y: i32 }
# let mut entities = Entities::new(Some(3), Some(3));
# entities.new_entity()
# .with(Vector1 { x: 3 })?
# .with(Vector2 { x: 3, y: 3 })?
# .finalise()?;
fn other_system(active_ents: &[usize], entities: &mut Entities) -> Result<(), ECSError> {
let mut v1_components = entities
.borrow_mut::<Vector1>()?;
let mut v2_components = entities
.borrow_mut::<Vector2>()?;
for id in active_ents {
if entities.entity_contains::<Vector1>(*id) &&
entities.entity_contains::<Vector2>(*id) {
let v1_part = v1_components.get_mut(*id).unwrap();
let v2_part = v2_components.get_mut(*id).unwrap();
v1_part.x = 42;
assert_ne!(v1_part.x, 43);
assert_eq!(v1_part.x, 42);
}
}
Ok(())
}
other_system(&[0, 1, 2], &mut entities);
# Ok(())
# }