diff options
Diffstat (limited to 'engine-ecs/src/system/stateful.rs')
| -rw-r--r-- | engine-ecs/src/system/stateful.rs | 86 |
1 files changed, 41 insertions, 45 deletions
diff --git a/engine-ecs/src/system/stateful.rs b/engine-ecs/src/system/stateful.rs index b73baeb..c9354c3 100644 --- a/engine-ecs/src/system/stateful.rs +++ b/engine-ecs/src/system/stateful.rs @@ -1,4 +1,5 @@ use std::any::type_name; +use std::marker::PhantomData; use std::mem::transmute; use seq_macro::seq; @@ -7,12 +8,7 @@ use crate::component::local::SystemWithLocalComponents; use crate::component::Parts as ComponentParts; 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::observer::{Observe, Observed, Observer}; use crate::system::{ Into as IntoSystem, Metadata, @@ -24,10 +20,10 @@ use crate::system::{ use crate::World; /// A stateful system. -pub struct Stateful<Func> +pub struct Stateful<Func: Copy + 'static> { - func: Func, local_components: Vec<ComponentParts>, + _pd: PhantomData<Func>, } macro_rules! impl_system { @@ -36,7 +32,7 @@ macro_rules! impl_system { impl<'world, Func, Ret, #(TParam~I,)*> System<'world, fn(#(TParam~I,)*) -> Ret> for Stateful<Func> where - Func: Fn(#(TParam~I,)*) -> Ret + 'static, + Func: Fn(#(TParam~I,)*) -> Ret + Copy + 'static, Ret: ReturnValue, #(TParam~I: Param<'world, Input: 'static>,)* { @@ -44,22 +40,29 @@ macro_rules! impl_system { fn finish(self) -> (TypeErased, Self::Callbacks) { - let Self { func, local_components } = self; + crate::util::const_assert!( + size_of::<Func>() == 0, + "System function is not zero-sized (not function pointer)" + ); + + let Self { local_components, .. } = self; let callbacks = Callbacks { local_components }; let type_erased = TypeErased { - run: Box::new(move |world, metadata| { + run: |world, metadata, _| { // SAFETY: The caller of TypeErased::run ensures the lifetime // is correct let world = unsafe { &*std::ptr::from_ref(world) }; + let func = unsafe { std::mem::zeroed::<Func>() }; + func(#({ TParam~I::new(&world, &metadata) },)*); Ok(()) - }), + }, name: type_name::<Func>() }; @@ -71,7 +74,7 @@ macro_rules! impl_system { impl<'world, Func, Ret, #(TParam~I,)*> Initializable<'world, fn(#(TParam~I,)*) -> Ret> for Stateful<Func> where - Func: Fn(#(TParam~I,)*) -> Ret + 'static, + Func: Fn(#(TParam~I,)*) -> Ret + Copy + 'static, Ret: ReturnValue, #(TParam~I: Param<'world, Input: 'static>,)* (#(TParam~I,)*): MaybeInitializableParamTuple<'world, Self> @@ -91,7 +94,7 @@ macro_rules! impl_system { impl<'world, Func, Ret, #(TParam~I,)*> IntoSystem<'world, fn(#(TParam~I,)*) -> Ret> for Func where - Func: Fn(#(TParam~I,)*) -> Ret + 'static, + Func: Fn(#(TParam~I,)*) -> Ret + Copy + 'static, Ret: ReturnValue, #(TParam~I: Param<'world>,)* { @@ -100,8 +103,8 @@ macro_rules! impl_system { fn into_system(self) -> Self::System { Self::System { - func: self, local_components: Vec::new(), // TODO: Use Vec::with_capacity + _pd: PhantomData } } } @@ -113,7 +116,7 @@ seq!(C in 1..16 { impl_system!(C); }); -impl<Func> SystemWithLocalComponents for Stateful<Func> +impl<Func: Copy + 'static> SystemWithLocalComponents for Stateful<Func> { fn add_local_component(&mut self, component_parts: ComponentParts) { @@ -149,31 +152,13 @@ fn init_initializable_params<'world, SystemT, Params>( 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, + Func: Fn(Observe<'world, ObservedT>, #(TParam~I,)*) -> Ret + Copy + 'static, Ret: ReturnValue, #(TParam~I: Param<'world>,)* (#(TParam~I,)*): MaybeInitializableParamTuple<'world, Self> @@ -196,10 +181,11 @@ macro_rules! impl_observer { > for Stateful<Func> where ObservedT: Observed, - Func: Fn(Observe<'world, ObservedT>, #(TParam~I,)*) -> Ret + 'static, + Func: Fn(Observe<'world, ObservedT>, #(TParam~I,)*) -> Ret + Copy + 'static, Ret: ReturnValue, #(TParam~I: Param<'world>,)* { + type Callbacks = Callbacks; type ObservedEvents = ObservedT::Events; fn observed_events() -> Self::ObservedEvents @@ -207,20 +193,28 @@ macro_rules! impl_observer { ObservedT::events() } - fn finish_observer(self) -> (ObserverWrapperComponent, Callbacks) + fn finish_observer(self) -> (TypeErased, Callbacks) { #![allow(unused)] - let Self { func, local_components } = self; + crate::util::const_assert!( + size_of::<Func>() == 0, + "System function is not zero-sized (not function pointer)" + ); + + let Self { local_components, .. } = self; let callbacks = Callbacks { local_components }; - let wrapper_comp = ObserverWrapperComponent::new( - move |world, metadata, emitted_event| { + let system = TypeErased { + run: |world, metadata, emitted_event| { // SAFETY: The caller of TypeErased::run ensures the lifetime // is correct let world = unsafe { &*std::ptr::from_ref(world) }; + let emitted_event = + emitted_event.expect("No event info passed to observer"); + // SAFETY: The caller of TypeErased::run ensures the lifetime // is correct let emitted_event = unsafe { @@ -229,14 +223,16 @@ macro_rules! impl_observer { ) }; + let func = unsafe { std::mem::zeroed::<Func>() }; + func(Observe::new(world, emitted_event), #({ TParam~I::new(world, &metadata) },)*).into_result() }, - type_name::<Func>() - ); + name: type_name::<Func>() + }; - (wrapper_comp, callbacks) + (system, callbacks) } } @@ -246,7 +242,7 @@ macro_rules! impl_observer { > for Func where ObservedT: Observed, - Func: Fn(Observe<'world, ObservedT>, #(TParam~I,)*) -> Ret + 'static, + Func: Fn(Observe<'world, ObservedT>, #(TParam~I,)*) -> Ret + Copy + 'static, Ret: ReturnValue, #(TParam~I: Param<'world>,)* { @@ -255,8 +251,8 @@ macro_rules! impl_observer { fn into_system(self) -> Stateful<Func> { Stateful { - func: self, local_components: Vec::new(), // TODO: Use Vec::with_capacity + _pd: PhantomData } } } |
