From 9d8c73dd2671131929967214433dae5479e95b5b Mon Sep 17 00:00:00 2001 From: HampusM Date: Tue, 9 Apr 2024 22:25:03 +0200 Subject: feat(ecs): add support for singleton components --- ecs/src/lib.rs | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) (limited to 'ecs/src/lib.rs') diff --git a/ecs/src/lib.rs b/ecs/src/lib.rs index 33d981b..ce1a7d1 100644 --- a/ecs/src/lib.rs +++ b/ecs/src/lib.rs @@ -89,6 +89,20 @@ impl World }); } + /// Adds a single component. This component will be globally shared. + /// + /// # Errors + /// Returns `Err` if this component has already been added as a single component. + pub fn add_single_component( + &mut self, + single_component: SingleComponent, + ) -> Result<(), SingleComponentAlreadyExistsError> + where + SingleComponent: Component, + { + self.data.single_component_storage.insert(single_component) + } + pub fn register_system<'this, SystemImpl>( &'this mut self, event: &impl Event, @@ -206,6 +220,7 @@ pub struct WorldData { events: HashMap>, component_storage: Arc>, + single_component_storage: SingleComponentStorage, action_queue: Arc>, } @@ -324,3 +339,42 @@ impl Drop for ComponentStorage } } } + +#[derive(Debug, thiserror::Error)] +#[error("Single component {0} already exists")] +pub struct SingleComponentAlreadyExistsError(pub &'static str); + +#[derive(Debug, Default)] +struct SingleComponentStorage +{ + storage: HashMap>>, +} + +impl SingleComponentStorage +{ + fn get(&self) -> Option<&Lock>> + { + self.storage.get(&TypeId::of::()) + } + + fn insert( + &mut self, + single_component: SingleComponent, + ) -> Result<(), SingleComponentAlreadyExistsError> + { + let single_component_type_id = TypeId::of::(); + + if self.storage.contains_key(&single_component_type_id) { + return Err(SingleComponentAlreadyExistsError(type_name::< + SingleComponent, + >())); + } + + self.storage.insert( + single_component_type_id, + Lock::new(Box::new(single_component)), + ); + + Ok(()) + } +} -- cgit v1.2.3-18-g5258