From 5feeaf154a8b729873c729b4488f28536cf4ae24 Mon Sep 17 00:00:00 2001 From: HampusM Date: Sat, 21 Dec 2024 14:43:53 +0100 Subject: feat(ecs): add support for entities without components --- ecs/src/actions.rs | 8 ++++++++ ecs/src/archetype.rs | 22 ++++++++++------------ ecs/src/component.rs | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 66 insertions(+), 12 deletions(-) (limited to 'ecs') diff --git a/ecs/src/actions.rs b/ecs/src/actions.rs index babd5a2..c062472 100644 --- a/ecs/src/actions.rs +++ b/ecs/src/actions.rs @@ -44,6 +44,10 @@ impl<'world> Actions<'world> { debug_assert_eq!(entity_uid.kind(), UidKind::Entity); + if Comps::metadata().len() == 0 { + return; + } + self.action_queue.push(Action::AddComponents( entity_uid, components.into_vec(), @@ -58,6 +62,10 @@ impl<'world> Actions<'world> { debug_assert_eq!(entity_uid.kind(), UidKind::Entity); + if Comps::metadata().len() == 0 { + return; + } + self.action_queue.push(Action::RemoveComponents( entity_uid, Comps::metadata(), diff --git a/ecs/src/archetype.rs b/ecs/src/archetype.rs index d2ee36a..354d206 100644 --- a/ecs/src/archetype.rs +++ b/ecs/src/archetype.rs @@ -4,7 +4,6 @@ use crate::component::{ IsOptional as ComponentIsOptional, Metadata as ComponentMetadata, }; -use crate::uid::Uid; /// Archetype ID. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] @@ -19,10 +18,9 @@ impl Id components_metadata: &impl AsRef<[ComponentMetadata]>, ) -> Self { - debug_assert!( - components_metadata.as_ref().len() > 0, - "Cannot create a archetype ID from a empty component metadata list" - ); + if components_metadata.as_ref().len() == 0 { + return Self { hash: 0 }; + } debug_assert!( components_metadata @@ -31,7 +29,7 @@ impl Id "Cannot create archetype ID from a unsorted component metadata list" ); - Self::new( + let component_ids = components_metadata .as_ref() .iter() @@ -41,13 +39,8 @@ impl Id } Some(component_metadata.id) - }), - ) - } + }); - /// Returns the ID of a archetype with the given components. - fn new(component_ids: impl IntoIterator) -> Self - { let mut hasher = DefaultHasher::new(); for component_id in component_ids { @@ -56,6 +49,11 @@ impl Id let hash = hasher.finish(); + assert_ne!( + hash, 0, + "Archetype ID 0 is reserved for a archetype with zero components" + ); + Self { hash } } } diff --git a/ecs/src/component.rs b/ecs/src/component.rs index 85c556f..1fde5b4 100644 --- a/ecs/src/component.rs +++ b/ecs/src/component.rs @@ -351,3 +351,51 @@ macro_rules! inner { seq!(C in 0..=64 { inner!(C); }); + +impl Sequence for () +{ + type MutRefs<'component> = (); + type Refs<'component> = (); + + fn into_vec(self) -> Vec> + { + Vec::new() + } + + fn metadata() -> Vec + { + Vec::new() + } + + fn added_event_ids() -> Vec + { + Vec::new() + } + + fn removed_event_ids() -> Vec + { + Vec::new() + } + + #[inline] + fn from_components_mut<'component>( + _components: &'component [EntityComponent], + _component_index_lookup: impl Fn(Uid) -> Option, + _world: &'component World, + _lock_component: fn(&EntityComponent) -> WriteGuard<'_, Box>, + ) -> Self::MutRefs<'component> + { + () + } + + #[inline] + fn from_components<'component>( + _components: &'component [EntityComponent], + _component_index_lookup: impl Fn(Uid) -> Option, + _world: &'component World, + _lock_component: fn(&EntityComponent) -> ReadGuard<'_, Box>, + ) -> Self::Refs<'component> + { + () + } +} -- cgit v1.2.3-18-g5258