diff options
Diffstat (limited to 'ecs/src/system/observer.rs')
| -rw-r--r-- | ecs/src/system/observer.rs | 280 |
1 files changed, 0 insertions, 280 deletions
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>; |
