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(())
# }