summaryrefslogtreecommitdiff
path: root/engine-ecs/src/system/stateful.rs
diff options
context:
space:
mode:
Diffstat (limited to 'engine-ecs/src/system/stateful.rs')
-rw-r--r--engine-ecs/src/system/stateful.rs86
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
}
}
}