summaryrefslogtreecommitdiff
path: root/ecs/src/lib.rs
diff options
context:
space:
mode:
authorHampusM <hampus@hampusmat.com>2024-04-09 22:25:03 +0200
committerHampusM <hampus@hampusmat.com>2024-04-09 22:25:03 +0200
commit9d8c73dd2671131929967214433dae5479e95b5b (patch)
treed522d975e14e6db7544474b641d824edd8edbae5 /ecs/src/lib.rs
parent50234ddc9ee7acd6d2b8d0a5626caf9e9293c0da (diff)
feat(ecs): add support for singleton components
Diffstat (limited to 'ecs/src/lib.rs')
-rw-r--r--ecs/src/lib.rs54
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(())
+ }
+}