diff options
Diffstat (limited to 'engine-ecs/src/system.rs')
| -rw-r--r-- | engine-ecs/src/system.rs | 33 |
1 files changed, 23 insertions, 10 deletions
diff --git a/engine-ecs/src/system.rs b/engine-ecs/src/system.rs index 38e480d..5395b14 100644 --- a/engine-ecs/src/system.rs +++ b/engine-ecs/src/system.rs @@ -3,6 +3,7 @@ use std::fmt::Debug; use seq_macro::seq; use crate::error::Error; +use crate::event::Emitted as EmittedEvent; use crate::uid::Uid; use crate::{Component, World}; @@ -31,7 +32,7 @@ macro_rules! impl_system { impl<'world, Func, Ret, #(TParam~I,)*> System<'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, Input = ()>,)* { @@ -41,16 +42,23 @@ macro_rules! impl_system { { #![allow(unused)] + crate::util::const_assert!( + size_of::<Func>() == 0, + "System function is not zero-sized (not function pointer)" + ); + 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) }; - self(#({ + let func = unsafe { std::mem::zeroed::<Func>() }; + + func(#({ TParam~I::new(world, &metadata) },)*).into_result() - }), + }, name: std::any::type_name::<Self>() }; @@ -74,8 +82,8 @@ pub trait Into<'world, Impl> pub struct TypeErased { - run: Box<TypeErasedRunFn>, - name: &'static str, + pub run: TypeErasedRunFn, + pub name: &'static str, } impl TypeErased @@ -84,9 +92,14 @@ impl TypeErased /// /// # Safety /// `world_data` must live at least as long as the [`World`] the system belongs to. - pub unsafe fn run(&self, world: &World, metadata: Metadata) -> Result<(), Error> + pub unsafe fn run( + &self, + world: &World, + metadata: Metadata, + evt: Option<EmittedEvent<'_>>, + ) -> Result<(), Error> { - (self.run)(world, metadata) + (self.run)(world, metadata, evt) } pub fn name(&self) -> &'static str @@ -153,5 +166,5 @@ pub(crate) struct SystemComponent pub(crate) system: TypeErased, } -/// Function in [`TypeErased`] used to run the system. -type TypeErasedRunFn = dyn Fn(&World, Metadata) -> Result<(), Error>; +type TypeErasedRunFn = + fn(&World, Metadata, Option<EmittedEvent<'_>>) -> Result<(), Error>; |
