diff options
| author | HampusM <hampus@hampusmat.com> | 2026-05-19 00:12:11 +0200 |
|---|---|---|
| committer | HampusM <hampus@hampusmat.com> | 2026-05-19 00:12:11 +0200 |
| commit | d5a744b0909c4b2bec397ae4dcd43b56aba355c6 (patch) | |
| tree | 1dcf8b769775ab7a0f4ff87e280aa98a0d280d21 /ecs/src/system/observer.rs | |
| parent | b13b3f6e13f9ac9fe7fee0b5a81b026f411f0301 (diff) | |
Diffstat (limited to 'ecs/src/system/observer.rs')
| -rw-r--r-- | ecs/src/system/observer.rs | 106 |
1 files changed, 38 insertions, 68 deletions
diff --git a/ecs/src/system/observer.rs b/ecs/src/system/observer.rs index 0472614..6893b0f 100644 --- a/ecs/src/system/observer.rs +++ b/ecs/src/system/observer.rs @@ -1,3 +1,4 @@ +use std::any::type_name; use std::fmt::Debug; use std::marker::PhantomData; use std::mem::transmute; @@ -6,20 +7,22 @@ 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; -use crate::World; pub trait Observed { @@ -154,30 +157,34 @@ impl<'world, ObservedT: Observed> EventMatch<'world, ObservedT> macro_rules! impl_observer { ($c: tt) => { seq!(I in 0..$c { - impl<'world, ObservedT, Func, #(TParam~I,)*> System< + impl<'world, ObservedT, Func, Ret, #(TParam~I,)*> System< 'world, - fn(Observe<'world, ObservedT>, #(TParam~I,)*) + fn(Observe<'world, ObservedT>, #(TParam~I,)*) -> Ret > for Func where ObservedT: Observed, - Func: Fn(Observe<'world, ObservedT>, #(TParam~I,)*) + Copy + 'static, + Func: Fn(Observe<'world, ObservedT>, #(TParam~I,)*) -> Ret + 'static, + Ret: SystemReturnValue, #(TParam~I: Param<'world, Input = ()>,)* { type Callbacks = NoCallbacks; fn finish(self) -> (TypeErasedSystem, NoCallbacks) { - unimplemented!(); + const { + panic!("Observers cannot be used as regular systems"); + } } } - impl<'world, ObservedT, Func, #(TParam~I,)*> Observer< + impl<'world, ObservedT, Func, Ret, #(TParam~I,)*> Observer< 'world, - fn(Observe<'world, ObservedT>, #(TParam~I,)*) + fn(Observe<'world, ObservedT>, #(TParam~I,)*) -> Ret > for Func where ObservedT: Observed, - Func: Fn(Observe<'world, ObservedT>, #(TParam~I,)*) + Copy + 'static, + Func: Fn(Observe<'world, ObservedT>, #(TParam~I,)*) -> Ret + 'static, + Ret: SystemReturnValue, #(TParam~I: Param<'world, Input = ()>,)* { type ObservedEvents = ObservedT::Events; @@ -189,8 +196,10 @@ macro_rules! impl_observer { fn finish_observer(self) -> (WrapperComponent, NoCallbacks) { - let wrapper_comp = WrapperComponent { - run: Box::new(move |world, metadata, emitted_event| { + #[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) }; @@ -205,9 +214,10 @@ macro_rules! impl_observer { self(Observe::new(world, emitted_event), #({ TParam~I::new(world, &metadata) - },)*); - }), - }; + },)*).into_result() + }, + type_name::<Func>() + ); (wrapper_comp, NoCallbacks) } @@ -216,70 +226,25 @@ macro_rules! impl_observer { }; } -seq!(C in 1..16 { +seq!(C in 0..16 { impl_observer!(C); }); -impl<'world, ObservedT, Func> System<'world, fn(Observe<'world, ObservedT>)> for Func -where - ObservedT: Observed, - Func: Fn(Observe<'world, ObservedT>) + Copy + 'static, -{ - type Callbacks = NoCallbacks; - - fn finish(self) -> (TypeErasedSystem, NoCallbacks) - { - const { - panic!("Observers cannot be used as regular systems"); - } - } -} - -impl<'world, ObservedT, Func> Observer<'world, fn(Observe<'world, ObservedT>)> for Func -where - ObservedT: Observed, - Func: Fn(Observe<'world, ObservedT>) + Copy + 'static, -{ - type ObservedEvents = ObservedT::Events; - - fn observed_events() -> Self::ObservedEvents - { - ObservedT::events() - } - - fn finish_observer(self) -> (WrapperComponent, NoCallbacks) - { - let wrapper_comp = WrapperComponent { - run: Box::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)); - }), - }; - - (wrapper_comp, NoCallbacks) - } -} - #[derive(Component)] pub struct WrapperComponent { run: Box<RunFn>, + name: &'static str, } impl WrapperComponent { - pub fn new(run: impl Fn(&World, Metadata, EmittedEvent<'_>) + 'static) -> Self + pub fn new( + run: impl Fn(&World, Metadata, EmittedEvent<'_>) -> Result<(), Error> + 'static, + name: &'static str, + ) -> Self { - Self { run: Box::new(run) } + Self { run: Box::new(run), name } } /// Runs the observer system. @@ -291,9 +256,14 @@ impl WrapperComponent world: &World, metadata: Metadata, emitted_event: EmittedEvent<'_>, - ) + ) -> Result<(), Error> + { + (self.run)(world, metadata, emitted_event) + } + + pub fn name(&self) -> &'static str { - (self.run)(world, metadata, emitted_event); + self.name } } @@ -307,4 +277,4 @@ impl Debug for WrapperComponent } } -type RunFn = dyn Fn(&World, Metadata, EmittedEvent<'_>); +type RunFn = dyn Fn(&World, Metadata, EmittedEvent<'_>) -> Result<(), Error>; |
