diff options
author | HampusM <hampus@hampusmat.com> | 2025-08-15 13:38:27 +0200 |
---|---|---|
committer | HampusM <hampus@hampusmat.com> | 2025-08-22 17:18:54 +0200 |
commit | e229b104593d3afede47cc07e9917a42d6d13e60 (patch) | |
tree | 25cd15befc8bf3e5864158aa791895c6d5bea751 /ecs/src/system.rs | |
parent | c8d3b211b8328452c9d15955004030430a99d1fc (diff) |
refactor(ecs): store local components as system entity components
Diffstat (limited to 'ecs/src/system.rs')
-rw-r--r-- | ecs/src/system.rs | 114 |
1 files changed, 34 insertions, 80 deletions
diff --git a/ecs/src/system.rs b/ecs/src/system.rs index 603c015..a7ca4df 100644 --- a/ecs/src/system.rs +++ b/ecs/src/system.rs @@ -1,37 +1,31 @@ -use std::any::Any; -use std::convert::Infallible; use std::fmt::Debug; use ecs_macros::Component; use seq_macro::seq; -use crate::component::{Component, HandleMut as ComponentHandleMut}; -use crate::tuple::{ReduceElement as TupleReduceElement, Tuple}; +use crate::uid::Uid; use crate::World; +pub mod initializable; pub mod stateful; -pub trait System<'world, Impl>: 'static +/// Metadata of a system. +#[derive(Debug)] +#[non_exhaustive] +pub struct Metadata { - type Input; + pub ent_id: Uid, +} - #[must_use] - fn initialize(self, input: Self::Input) -> Self; +pub trait System<'world, Impl>: 'static +{ + type Callbacks: Callbacks; - fn run<'this>(&'this self, world: &'world World) + fn run<'this>(&'this self, world: &'world World, metadata: Metadata) where 'this: 'world; - fn into_type_erased(self) -> TypeErased; - - fn get_local_component_mut<LocalComponent: Component>( - &self, - ) -> Option<ComponentHandleMut<LocalComponent>>; - - fn set_local_component<LocalComponent: Component>( - &mut self, - local_component: LocalComponent, - ); + fn finish(self) -> (TypeErased, Self::Callbacks); } macro_rules! impl_system { @@ -43,58 +37,34 @@ macro_rules! impl_system { Func: Fn(#(TParam~I,)*) + Copy + 'static, #(TParam~I: Param<'world, Input = ()>,)* { - type Input = Infallible; + type Callbacks = NoCallbacks; - fn initialize(self, _input: Self::Input) -> Self - { - self - } - - fn run<'this>(&'this self, world: &'world World) + fn run<'this>(&'this self, world: &'world World, metadata: Metadata) where 'this: 'world { let func = *self; func(#({ - TParam~I::new(self, world) + TParam~I::new(world, &metadata) },)*); } - fn into_type_erased(self) -> TypeErased + fn finish(self) -> (TypeErased, Self::Callbacks) { - TypeErased { - data: Box::new(self), - run: Box::new(|data, world| { - // SAFETY: The caller of TypeErased::run ensures the lifetime - // is correct - let data = unsafe { &*std::ptr::from_ref(data) }; - - let me = data - .downcast_ref::<Func>() - .expect("Function downcast failed"); - + let type_erased = TypeErased { + run: Box::new(move |world, metadata| { // SAFETY: The caller of TypeErased::run ensures the lifetime // is correct let world = unsafe { &*std::ptr::from_ref(world) }; - me.run(world); + self(#({ + TParam~I::new(world, &metadata) + },)*); }), - } - } + }; - fn get_local_component_mut<LocalComponent: Component>( - &self, - ) -> Option<ComponentHandleMut<LocalComponent>> - { - panic!("System does not have any local components"); - } - - fn set_local_component<LocalComponent: Component>( - &mut self, - _local_component: LocalComponent, - ) { - panic!("System does not have any local components"); + (type_erased, NoCallbacks) } } }); @@ -114,7 +84,6 @@ pub trait Into<Impl> pub struct TypeErased { - data: Box<dyn Any>, run: Box<TypeErasedRunFn>, } @@ -124,12 +93,9 @@ 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) + pub unsafe fn run(&self, world: &World, metadata: Metadata) { - // You have to dereference for downcasting to work for some reason - let data = &*self.data; - - (self.run)(data, world); + (self.run)(world, metadata); } } @@ -142,41 +108,29 @@ impl Debug for TypeErased } /// Function in [`TypeErased`] used to run the system. -type TypeErasedRunFn = dyn Fn(&dyn Any, &World); +type TypeErasedRunFn = dyn Fn(&World, Metadata); /// A parameter to a [`System`]. pub trait Param<'world> { type Input; - fn initialize<SystemImpl>( - system: &mut impl System<'world, SystemImpl>, - input: Self::Input, - ); - - fn new<SystemImpl>( - system: &'world impl System<'world, SystemImpl>, - world: &'world World, - ) -> Self; + fn new(world: &'world World, system_metadata: &Metadata) -> Self; } /// A type which can be used as input to a [`System`]. pub trait Input: 'static {} -/// Component tuple reducing operation to get the parameters that takes input. -pub struct ParamWithInputFilter; - -impl<InputT: Input, Accumulator> TupleReduceElement<Accumulator, ParamWithInputFilter> - for InputT -where - Accumulator: Tuple, +pub trait Callbacks { - type Return = Accumulator::WithElementAtEnd<Self>; + fn on_created(&mut self, world: &mut World, metadata: Metadata); } -impl<Accumulator> TupleReduceElement<Accumulator, ParamWithInputFilter> for () +pub struct NoCallbacks; + +impl Callbacks for NoCallbacks { - type Return = Accumulator; + fn on_created(&mut self, _world: &mut World, _metadata: Metadata) {} } #[derive(Debug, Component)] |