summaryrefslogtreecommitdiff
path: root/ecs/src/component/local.rs
diff options
context:
space:
mode:
Diffstat (limited to 'ecs/src/component/local.rs')
-rw-r--r--ecs/src/component/local.rs79
1 files changed, 79 insertions, 0 deletions
diff --git a/ecs/src/component/local.rs b/ecs/src/component/local.rs
new file mode 100644
index 0000000..e1a0c1f
--- /dev/null
+++ b/ecs/src/component/local.rs
@@ -0,0 +1,79 @@
+use std::any::{Any, TypeId};
+use std::ops::{Deref, DerefMut};
+
+use crate::component::Component;
+use crate::system::{ComponentRefMut, Param as SystemParam, System};
+use crate::WorldData;
+
+/// Holds a component which is local to a single system.
+#[derive(Debug)]
+pub struct Local<'world, LocalComponent: Component>
+{
+ local_component: ComponentRefMut<'world, LocalComponent>,
+}
+
+unsafe impl<'world, LocalComponent> SystemParam<'world> for Local<'world, LocalComponent>
+where
+ LocalComponent: Component,
+{
+ type Flags = ();
+ type Input = LocalComponent;
+
+ fn initialize<SystemImpl>(
+ system: &mut impl System<'world, SystemImpl>,
+ input: Self::Input,
+ )
+ {
+ system.set_local_component(input);
+ }
+
+ fn new<SystemImpl>(
+ system: &'world impl System<'world, SystemImpl>,
+ _world_data: &'world WorldData,
+ ) -> Self
+ {
+ let local_component = system
+ .get_local_component_mut::<LocalComponent>()
+ .expect("Local component is uninitialized");
+
+ Self { local_component }
+ }
+
+ fn is_compatible<Other: SystemParam<'world>>() -> bool
+ {
+ let other_comparable = Other::get_comparable();
+
+ let Some(other_type_id) = other_comparable.downcast_ref::<TypeId>() else {
+ return true;
+ };
+
+ TypeId::of::<LocalComponent>() != *other_type_id
+ }
+
+ fn get_comparable() -> Box<dyn Any>
+ {
+ Box::new(TypeId::of::<LocalComponent>())
+ }
+}
+
+impl<'world, LocalComponent> Deref for Local<'world, LocalComponent>
+where
+ LocalComponent: Component,
+{
+ type Target = LocalComponent;
+
+ fn deref(&self) -> &Self::Target
+ {
+ &self.local_component
+ }
+}
+
+impl<'world, LocalComponent> DerefMut for Local<'world, LocalComponent>
+where
+ LocalComponent: Component,
+{
+ fn deref_mut(&mut self) -> &mut Self::Target
+ {
+ &mut self.local_component
+ }
+}