diff options
author | HampusM <hampus@hampusmat.com> | 2024-04-09 22:25:03 +0200 |
---|---|---|
committer | HampusM <hampus@hampusmat.com> | 2024-04-09 22:25:03 +0200 |
commit | 9d8c73dd2671131929967214433dae5479e95b5b (patch) | |
tree | d522d975e14e6db7544474b641d824edd8edbae5 /ecs/src/lib.rs | |
parent | 50234ddc9ee7acd6d2b8d0a5626caf9e9293c0da (diff) |
feat(ecs): add support for singleton components
Diffstat (limited to 'ecs/src/lib.rs')
-rw-r--r-- | ecs/src/lib.rs | 54 |
1 files changed, 54 insertions, 0 deletions
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<SingleComponent>( + &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<EventId, Vec<usize>>, component_storage: Arc<Lock<ComponentStorage>>, + single_component_storage: SingleComponentStorage, action_queue: Arc<Lock<ActionQueue>>, } @@ -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<TypeId, Lock<Box<dyn Component>>>, +} + +impl SingleComponentStorage +{ + fn get<SingleComponent: Component>(&self) -> Option<&Lock<Box<dyn Component>>> + { + self.storage.get(&TypeId::of::<SingleComponent>()) + } + + fn insert<SingleComponent: Component>( + &mut self, + single_component: SingleComponent, + ) -> Result<(), SingleComponentAlreadyExistsError> + { + let single_component_type_id = TypeId::of::<SingleComponent>(); + + 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(()) + } +} |