diff options
Diffstat (limited to 'ecs/src/system')
| -rw-r--r-- | ecs/src/system/initializable.rs | 131 | ||||
| -rw-r--r-- | ecs/src/system/observer.rs | 280 | ||||
| -rw-r--r-- | ecs/src/system/stateful.rs | 269 |
3 files changed, 0 insertions, 680 deletions
diff --git a/ecs/src/system/initializable.rs b/ecs/src/system/initializable.rs deleted file mode 100644 index b6ec8e8..0000000 --- a/ecs/src/system/initializable.rs +++ /dev/null @@ -1,131 +0,0 @@ -use std::marker::PhantomData; - -use seq_macro::seq; - -use crate::system::{Input, Param as SystemParam, System}; -use crate::tuple::{Reduce as TupleReduce, ReduceElement as TupleReduceElement, Tuple}; - -/// A initializable system. -pub trait Initializable<'world, Impl>: System<'world, Impl> -{ - type Inputs; - - #[must_use] - fn initialize(self, inputs: Self::Inputs) -> Self; -} - -pub trait Param<'world, SystemT>: SystemParam<'world> -{ - fn initialize(system: &mut SystemT, input: Self::Input); -} - -pub struct ParamTupleFilter<'world, SystemT> -{ - _pd: PhantomData<(&'world (), SystemT)>, -} - -impl<'world, SystemT, ParamT, Accumulator> - TupleReduceElement<Accumulator, ParamTupleFilter<'world, SystemT>> for ParamT -where - ParamT: SystemParam< - 'world, - Input: AppendInitializableParam<'world, Accumulator, ParamT, SystemT>, - >, - Accumulator: Tuple, -{ - type Return = <ParamT::Input as AppendInitializableParam< - 'world, - Accumulator, - ParamT, - SystemT, - >>::Return; -} - -pub trait AppendInitializableParam<'world, Accumulator, ParamT, SystemT> -{ - type Return; -} - -impl<'world, InputT, ParamT, Accumulator, SystemT> - AppendInitializableParam<'world, Accumulator, ParamT, SystemT> for InputT -where - InputT: Input, - Accumulator: Tuple, - ParamT: Param<'world, SystemT>, -{ - type Return = Accumulator::WithElementAtEnd<ParamT>; -} - -impl<ParamT, Accumulator, SystemT> - AppendInitializableParam<'_, Accumulator, ParamT, SystemT> for () -where - Accumulator: Tuple, -{ - type Return = Accumulator; -} - -pub trait ParamTuple<'world, SystemT> -{ - type Inputs; - - fn initialize_all(system: &mut SystemT, inputs: Self::Inputs); -} - -macro_rules! impl_initializable_param_tuple { - ($c: tt) => { - seq!(I in 0..$c { - impl<'world, SystemT, #(Param~I,)*> ParamTuple<'world, SystemT> - for (#(Param~I,)*) - where - #(Param~I: Param<'world, SystemT>,)* - { - type Inputs = (#(Param~I::Input,)*); - - fn initialize_all( - system: &mut SystemT, - inputs: Self::Inputs, - ) { - #( - <Param~I as Param<'world, SystemT>>::initialize( - system, - inputs.I - ); - )* - } - } - }); - }; -} - -seq!(C in 1..16 { - impl_initializable_param_tuple!(C); -}); - -impl<SystemT> ParamTuple<'_, SystemT> for () -{ - type Inputs = (); - - fn initialize_all(_system: &mut SystemT, _inputs: Self::Inputs) {} -} - -/// A tuple of system parameters that may or may not be initializable. -pub trait MaybeInitializableParamTuple<'world, SystemT> -{ - /// A tuple of the inputs of the initializable system parameters in this tuple. - type Inputs; - - fn init_initializable(system: &mut SystemT, inputs: Self::Inputs); -} - -impl<'world, SystemT, Params> MaybeInitializableParamTuple<'world, SystemT> for Params -where - Params: - TupleReduce<ParamTupleFilter<'world, SystemT>, Out: ParamTuple<'world, SystemT>>, -{ - type Inputs = <Params::Out as ParamTuple<'world, SystemT>>::Inputs; - - fn init_initializable(system: &mut SystemT, inputs: Self::Inputs) - { - Params::Out::initialize_all(system, inputs); - } -} diff --git a/ecs/src/system/observer.rs b/ecs/src/system/observer.rs deleted file mode 100644 index 6893b0f..0000000 --- a/ecs/src/system/observer.rs +++ /dev/null @@ -1,280 +0,0 @@ -use std::any::type_name; -use std::fmt::Debug; -use std::marker::PhantomData; -use std::mem::transmute; -use std::slice::Iter as SliceIter; - -use ecs_macros::Component; -use seq_macro::seq; - -use crate::World; -use crate::component::Component; -use crate::entity::Handle as EntityHandle; -use crate::error::Error; -use crate::event::Emitted as EmittedEvent; -use crate::pair::Pair; -use crate::system::{ - Metadata, - NoCallbacks, - Param, - ReturnValue as SystemReturnValue, - System, - TypeErased as TypeErasedSystem, -}; -use crate::uid::Uid; -use crate::util::Array; - -pub trait Observed -{ - type Events: Array<Pair<Uid, Uid>>; - - fn events() -> Self::Events; -} - -impl<Relation, Target> Observed for Pair<Relation, Target> -where - Relation: Component, - Target: Component, -{ - type Events = [Pair<Uid, Uid>; 1]; - - fn events() -> Self::Events - { - [Pair::builder() - .relation::<Relation>() - .target::<Target>() - .build()] - } -} - -/// Observer system. -pub trait Observer<'world, Impl>: System<'world, Impl> -{ - type ObservedEvents: Array<Pair<Uid, Uid>>; - - fn observed_events() -> Self::ObservedEvents; - - fn finish_observer(self) -> (WrapperComponent, Self::Callbacks); -} - -pub struct Observe<'world, ObservedT: Observed> -{ - _pd: PhantomData<ObservedT>, - world: &'world World, - emitted_event: EmittedEvent<'world>, -} - -impl<'world, ObservedT: Observed> Observe<'world, ObservedT> -{ - pub fn new(world: &'world World, emitted_event: EmittedEvent<'world>) -> Self - { - Self { - _pd: PhantomData, - world, - emitted_event, - } - } - - #[must_use] - pub fn event(&self) -> Uid - { - self.emitted_event.event - } -} - -impl<ObservedT: Observed> Observe<'_, ObservedT> -{ - #[must_use] - pub fn iter(&self) -> ObserveIter<'_, ObservedT> - { - ObserveIter { - world: self.world, - inner: self.emitted_event.match_ids.iter(), - _pd: PhantomData, - } - } -} - -impl<'a, ObservedT: Observed> IntoIterator for &'a Observe<'_, ObservedT> -{ - type IntoIter = ObserveIter<'a, ObservedT>; - type Item = <Self::IntoIter as Iterator>::Item; - - fn into_iter(self) -> Self::IntoIter - { - self.iter() - } -} - -pub struct ObserveIter<'observe, ObservedT: Observed> -{ - world: &'observe World, - inner: SliceIter<'observe, Uid>, - _pd: PhantomData<ObservedT>, -} - -impl<'observe, ObservedT: Observed> Iterator for ObserveIter<'observe, ObservedT> -{ - type Item = EventMatch<'observe, ObservedT>; - - fn next(&mut self) -> Option<Self::Item> - { - let match_id = *self.inner.next()?; - - Some(EventMatch { - world: self.world, - id: match_id, - _pd: PhantomData, - }) - } -} - -/// A event match. -#[derive(Debug)] -pub struct EventMatch<'world, ObservedT: Observed> -{ - world: &'world World, - id: Uid, - _pd: PhantomData<ObservedT>, -} - -impl<'world, ObservedT: Observed> EventMatch<'world, ObservedT> -{ - #[must_use] - pub fn entity_id(&self) -> Uid - { - self.id - } - - /// Attempts to get the entity with the id of this match. - #[must_use] - pub fn try_get_entity(&self) -> Option<EntityHandle<'world>> - { - self.world.get_entity(self.id) - } -} - -macro_rules! impl_observer { - ($c: tt) => { - seq!(I in 0..$c { - impl<'world, ObservedT, Func, Ret, #(TParam~I,)*> System< - 'world, - fn(Observe<'world, ObservedT>, #(TParam~I,)*) -> Ret - > for Func - where - ObservedT: Observed, - Func: Fn(Observe<'world, ObservedT>, #(TParam~I,)*) -> Ret + 'static, - Ret: SystemReturnValue, - #(TParam~I: Param<'world, Input = ()>,)* - { - type Callbacks = NoCallbacks; - - fn finish(self) -> (TypeErasedSystem, NoCallbacks) - { - const { - panic!("Observers cannot be used as regular systems"); - } - } - } - - impl<'world, ObservedT, Func, Ret, #(TParam~I,)*> Observer< - 'world, - fn(Observe<'world, ObservedT>, #(TParam~I,)*) -> Ret - > for Func - where - ObservedT: Observed, - Func: Fn(Observe<'world, ObservedT>, #(TParam~I,)*) -> Ret + 'static, - Ret: SystemReturnValue, - #(TParam~I: Param<'world, Input = ()>,)* - { - type ObservedEvents = ObservedT::Events; - - fn observed_events() -> Self::ObservedEvents - { - ObservedT::events() - } - - fn finish_observer(self) -> (WrapperComponent, NoCallbacks) - { - #[allow(unused)] - - let wrapper_comp = WrapperComponent::new( - move |world, metadata, emitted_event| { - // SAFETY: The caller of TypeErased::run ensures the lifetime - // is correct - let world = unsafe { &*std::ptr::from_ref(world) }; - - // SAFETY: The caller of TypeErased::run ensures the lifetime - // is correct - let emitted_event = unsafe { - transmute::<EmittedEvent<'_>, EmittedEvent<'_>>( - emitted_event - ) - }; - - self(Observe::new(world, emitted_event), #({ - TParam~I::new(world, &metadata) - },)*).into_result() - }, - type_name::<Func>() - ); - - (wrapper_comp, NoCallbacks) - } - } - }); - }; -} - -seq!(C in 0..16 { - impl_observer!(C); -}); - -#[derive(Component)] -pub struct WrapperComponent -{ - run: Box<RunFn>, - name: &'static str, -} - -impl WrapperComponent -{ - pub fn new( - run: impl Fn(&World, Metadata, EmittedEvent<'_>) -> Result<(), Error> + 'static, - name: &'static str, - ) -> Self - { - Self { run: Box::new(run), name } - } - - /// Runs the observer system. - /// - /// # Safety - /// `world` must live at least as long as the [`World`] the system belongs to. - pub unsafe fn run( - &self, - world: &World, - metadata: Metadata, - emitted_event: EmittedEvent<'_>, - ) -> Result<(), Error> - { - (self.run)(world, metadata, emitted_event) - } - - pub fn name(&self) -> &'static str - { - self.name - } -} - -impl Debug for WrapperComponent -{ - fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result - { - formatter - .debug_struct("WrapperComponent") - .finish_non_exhaustive() - } -} - -type RunFn = dyn Fn(&World, Metadata, EmittedEvent<'_>) -> Result<(), Error>; diff --git a/ecs/src/system/stateful.rs b/ecs/src/system/stateful.rs deleted file mode 100644 index 3e0076a..0000000 --- a/ecs/src/system/stateful.rs +++ /dev/null @@ -1,269 +0,0 @@ -use std::any::type_name; -use std::mem::transmute; - -use seq_macro::seq; - -use crate::World; -use crate::component::Parts as ComponentParts; -use crate::component::local::SystemWithLocalComponents; -use crate::event::Emitted as EmittedEvent; -use crate::system::initializable::{Initializable, MaybeInitializableParamTuple}; -use crate::system::observer::{ - Observe, - Observed, - Observer, - WrapperComponent as ObserverWrapperComponent, -}; -use crate::system::{ - Into as IntoSystem, - Metadata, - Param, - ReturnValue, - System, - TypeErased, -}; - -/// A stateful system. -pub struct Stateful<Func> -{ - func: Func, - local_components: Vec<ComponentParts>, -} - -macro_rules! impl_system { - ($c: tt) => { - seq!(I in 0..$c { - impl<'world, Func, Ret, #(TParam~I,)*> - System<'world, fn(#(TParam~I,)*) -> Ret> for Stateful<Func> - where - Func: Fn(#(TParam~I,)*) -> Ret + 'static, - Ret: ReturnValue, - #(TParam~I: Param<'world, Input: 'static>,)* - { - type Callbacks = Callbacks; - - fn finish(self) -> (TypeErased, Self::Callbacks) - { - let Self { func, local_components } = self; - - let callbacks = Callbacks { local_components }; - - let type_erased = TypeErased { - run: Box::new(move |world, metadata| { - // SAFETY: The caller of TypeErased::run ensures the lifetime - // is correct - let world = unsafe { &*std::ptr::from_ref(world) }; - - func(#({ - TParam~I::new(&world, &metadata) - },)*); - - Ok(()) - }), - name: type_name::<Func>() - }; - - - (type_erased, callbacks) - } - } - - impl<'world, Func, Ret, #(TParam~I,)*> - Initializable<'world, fn(#(TParam~I,)*) -> Ret> for Stateful<Func> - where - Func: Fn(#(TParam~I,)*) -> Ret + 'static, - Ret: ReturnValue, - #(TParam~I: Param<'world, Input: 'static>,)* - (#(TParam~I,)*): MaybeInitializableParamTuple<'world, Self> - { - type Inputs = < - (#(TParam~I,)*) as MaybeInitializableParamTuple<'world, Self> - >::Inputs; - - fn initialize(mut self, inputs: Self::Inputs) -> Self - { - init_initializable_params::<_, (#(TParam~I,)*)>(&mut self, inputs); - - self - } - } - - impl<'world, Func, Ret, #(TParam~I,)*> - IntoSystem<'world, fn(#(TParam~I,)*) -> Ret> for Func - where - Func: Fn(#(TParam~I,)*) -> Ret + 'static, - Ret: ReturnValue, - #(TParam~I: Param<'world>,)* - { - type System = Stateful<Func>; - - fn into_system(self) -> Self::System - { - Self::System { - func: self, - local_components: Vec::new(), // TODO: Use Vec::with_capacity - } - } - } - }); - }; -} - -seq!(C in 1..16 { - impl_system!(C); -}); - -impl<Func> SystemWithLocalComponents for Stateful<Func> -{ - fn add_local_component(&mut self, component_parts: ComponentParts) - { - self.local_components.push(component_parts); - } -} - -#[derive(Debug)] -pub struct Callbacks -{ - local_components: Vec<ComponentParts>, -} - -impl crate::system::Callbacks for Callbacks -{ - fn on_created(&mut self, world: &mut World, metadata: Metadata) - { - for local_comp_parts in self.local_components.drain(..) { - world.add_component(metadata.ent_id, local_comp_parts); - } - } -} - -fn init_initializable_params<'world, SystemT, Params>( - system: &mut SystemT, - inputs: Params::Inputs, -) where - Params: MaybeInitializableParamTuple<'world, SystemT>, -{ - Params::init_initializable(system, inputs); -} - -macro_rules! impl_observer { - ($c: tt) => { - seq!(I in 0..$c { - impl<'world, ObservedT, Func, Ret, #(TParam~I,)*> System< - 'world, - fn(Observe<'world, ObservedT>, #(TParam~I,)*) -> Ret - > for Stateful<Func> - where - ObservedT: Observed, - Func: Fn(Observe<'world, ObservedT>, #(TParam~I,)*) -> Ret + 'static, - Ret: ReturnValue, - #(TParam~I: Param<'world>,)* - { - type Callbacks = Callbacks; - - fn finish(self) -> (TypeErased, Callbacks) - { - unimplemented!(); - } - } - - impl<'world, ObservedT, Func, Ret, #(TParam~I,)*> Initializable< - 'world, - fn(Observe<'world, ObservedT>, #(TParam~I,)*) -> Ret - > for Stateful<Func> - where - ObservedT: Observed, - Func: Fn(Observe<'world, ObservedT>, #(TParam~I,)*) -> Ret + 'static, - Ret: ReturnValue, - #(TParam~I: Param<'world>,)* - (#(TParam~I,)*): MaybeInitializableParamTuple<'world, Self> - { - type Inputs = < - (#(TParam~I,)*) as MaybeInitializableParamTuple<'world, Self> - >::Inputs; - - fn initialize(mut self, inputs: Self::Inputs) -> Self - { - init_initializable_params::<_, (#(TParam~I,)*)>(&mut self, inputs); - - self - } - } - - impl<'world, ObservedT, Func, Ret, #(TParam~I,)*> Observer< - 'world, - fn(Observe<'world, ObservedT>, #(TParam~I,)*) -> Ret - > for Stateful<Func> - where - ObservedT: Observed, - Func: Fn(Observe<'world, ObservedT>, #(TParam~I,)*) -> Ret + 'static, - Ret: ReturnValue, - #(TParam~I: Param<'world>,)* - { - type ObservedEvents = ObservedT::Events; - - fn observed_events() -> Self::ObservedEvents - { - ObservedT::events() - } - - fn finish_observer(self) -> (ObserverWrapperComponent, Callbacks) - { - #![allow(unused)] - - let Self { func, local_components } = self; - - let callbacks = Callbacks { local_components }; - - let wrapper_comp = ObserverWrapperComponent::new( - move |world, metadata, emitted_event| { - // SAFETY: The caller of TypeErased::run ensures the lifetime - // is correct - let world = unsafe { &*std::ptr::from_ref(world) }; - - // SAFETY: The caller of TypeErased::run ensures the lifetime - // is correct - let emitted_event = unsafe { - transmute::<EmittedEvent<'_>, EmittedEvent<'_>>( - emitted_event - ) - }; - - func(Observe::new(world, emitted_event), #({ - TParam~I::new(world, &metadata) - },)*).into_result() - }, - type_name::<Func>() - ); - - (wrapper_comp, callbacks) - } - } - - impl<'world, Func, Ret, ObservedT, #(TParam~I,)*> IntoSystem< - 'world, - fn(Observe<'world, ObservedT>, #(TParam~I,)*) -> Ret - > for Func - where - ObservedT: Observed, - Func: Fn(Observe<'world, ObservedT>, #(TParam~I,)*) -> Ret + 'static, - Ret: ReturnValue, - #(TParam~I: Param<'world>,)* - { - type System = Stateful<Func>; - - fn into_system(self) -> Stateful<Func> - { - Stateful { - func: self, - local_components: Vec::new(), // TODO: Use Vec::with_capacity - } - } - } - }); - }; -} - -seq!(C in 0..16 { - impl_observer!(C); -}); |
