summaryrefslogtreecommitdiff
path: root/ecs/src/system/observer.rs
diff options
context:
space:
mode:
authorHampusM <hampus@hampusmat.com>2026-05-19 00:12:11 +0200
committerHampusM <hampus@hampusmat.com>2026-05-19 00:12:11 +0200
commitd5a744b0909c4b2bec397ae4dcd43b56aba355c6 (patch)
tree1dcf8b769775ab7a0f4ff87e280aa98a0d280d21 /ecs/src/system/observer.rs
parentb13b3f6e13f9ac9fe7fee0b5a81b026f411f0301 (diff)
feat(ecs): add error handlingHEADmaster
Diffstat (limited to 'ecs/src/system/observer.rs')
-rw-r--r--ecs/src/system/observer.rs106
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>;