diff options
Diffstat (limited to 'ecs/src/system.rs')
| -rw-r--r-- | ecs/src/system.rs | 41 | 
1 files changed, 37 insertions, 4 deletions
| diff --git a/ecs/src/system.rs b/ecs/src/system.rs index 868afa7..f8885fc 100644 --- a/ecs/src/system.rs +++ b/ecs/src/system.rs @@ -85,7 +85,7 @@ macro_rules! impl_system {                  {                      TypeErased {                          data: Box::new(self), -                        func: Box::new(|data, world_data| { +                        run: Box::new(|data, world_data| {                              // SAFETY: The caller of TypeErased::run ensures the lifetime                              // is correct                              let data = unsafe { &*addr_of!(*data) }; @@ -102,6 +102,23 @@ macro_rules! impl_system {                              me.run(world_data);                          }), +                        prepare: Box::new(|data, world_data| { +                            // SAFETY: The caller of TypeErased::run ensures the lifetime +                            // is correct +                            let data = unsafe { &*addr_of!(*data) }; + +                            let me = data +                                .downcast_ref::<Func>() +                                .expect("Function downcast failed"); + +                            // SAFETY: The caller of TypeErased::run ensures the lifetime +                            // is correct +                            let world_data = unsafe { +                                &*(world_data as *const WorldData) +                            }; + +                            me.prepare(world_data); +                        }),                      }                  } @@ -137,7 +154,8 @@ pub trait Into<Impl>  pub struct TypeErased  {      data: Box<dyn Any + RefUnwindSafe + UnwindSafe>, -    func: Box<TypeErasedFunc>, +    run: Box<TypeErasedRunFn>, +    prepare: Box<TypeErasedPrepareFn>,  }  impl TypeErased @@ -151,7 +169,19 @@ impl TypeErased          // You have to dereference for downcasting to work for some reason          let data = &*self.data; -        (self.func)(data, world_data); +        (self.run)(data, world_data); +    } + +    /// Prepares the system. +    /// +    /// # Safety +    /// `world_data` must live at least as long as the [`World`] the system belongs to. +    pub unsafe fn prepare(&self, world_data: &WorldData) +    { +        // You have to dereference for downcasting to work for some reason +        let data = &*self.data; + +        (self.prepare)(data, world_data);      }  } @@ -164,7 +194,10 @@ impl Debug for TypeErased  }  /// Function in [`TypeErased`] used to run the system. -type TypeErasedFunc = dyn Fn(&dyn Any, &WorldData) + RefUnwindSafe + UnwindSafe; +type TypeErasedRunFn = dyn Fn(&dyn Any, &WorldData) + RefUnwindSafe + UnwindSafe; + +/// Function in [`TypeErased`] used to prepare the system. +type TypeErasedPrepareFn = dyn Fn(&dyn Any, &WorldData) + RefUnwindSafe + UnwindSafe;  /// A parameter to a [`System`].  /// | 
