diff options
Diffstat (limited to 'ecs/src/component.rs')
-rw-r--r-- | ecs/src/component.rs | 54 |
1 files changed, 52 insertions, 2 deletions
diff --git a/ecs/src/component.rs b/ecs/src/component.rs index bead3b5..59b737e 100644 --- a/ecs/src/component.rs +++ b/ecs/src/component.rs @@ -4,6 +4,9 @@ use std::ops::{Deref, DerefMut}; use seq_macro::seq; +use crate::system::{Input as SystemInput, Param as SystemParam, System}; +use crate::ComponentStorage; + pub trait Component: Any { #[doc(hidden)] @@ -114,20 +117,65 @@ seq!(C in 0..=64 { /// Holds a component which is local to a single system. #[derive(Debug)] -pub struct Local<'world, Value> +pub struct Local<'world, Value: SystemInput> { value: &'world mut Value, } impl<'world, Value> Local<'world, Value> +where + Value: SystemInput, { - pub(crate) fn new(value: &'world mut Value) -> Self + fn new(value: &'world mut Value) -> Self { Self { value } } } +unsafe impl<'world, Value: 'static> SystemParam<'world> for Local<'world, Value> +where + Value: SystemInput, +{ + type Flags = (); + type Input = Value; + + fn initialize<SystemImpl>(system: &mut impl System<SystemImpl>, input: Self::Input) + { + system.set_local_component(input); + } + + fn new<SystemImpl>( + system: &'world mut impl System<SystemImpl>, + _component_storage: &'world mut ComponentStorage, + ) -> Self + { + let local_component = system + .get_local_component_mut::<Value>() + .expect("Local component is uninitialized"); + + Self::new(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::<Value>() != *other_type_id + } + + fn get_comparable() -> Box<dyn Any> + { + Box::new(TypeId::of::<Value>()) + } +} + impl<'world, Value> Deref for Local<'world, Value> +where + Value: SystemInput, { type Target = Value; @@ -138,6 +186,8 @@ impl<'world, Value> Deref for Local<'world, Value> } impl<'world, Value> DerefMut for Local<'world, Value> +where + Value: SystemInput, { fn deref_mut(&mut self) -> &mut Self::Target { |