diff options
Diffstat (limited to 'ecs/src/component')
-rw-r--r-- | ecs/src/component/local.rs | 79 |
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 + } +} |