From e229b104593d3afede47cc07e9917a42d6d13e60 Mon Sep 17 00:00:00 2001 From: HampusM Date: Fri, 15 Aug 2025 13:38:27 +0200 Subject: refactor(ecs): store local components as system entity components --- ecs/src/system.rs | 114 ++++++++++++++++-------------------------------------- 1 file changed, 34 insertions(+), 80 deletions(-) (limited to 'ecs/src/system.rs') 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( - &self, - ) -> Option>; - - fn set_local_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::() - .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( - &self, - ) -> Option> - { - panic!("System does not have any local components"); - } - - fn set_local_component( - &mut self, - _local_component: LocalComponent, - ) { - panic!("System does not have any local components"); + (type_erased, NoCallbacks) } } }); @@ -114,7 +84,6 @@ pub trait Into pub struct TypeErased { - data: Box, run: Box, } @@ -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( - system: &mut impl System<'world, SystemImpl>, - input: Self::Input, - ); - - fn new( - 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 TupleReduceElement - for InputT -where - Accumulator: Tuple, +pub trait Callbacks { - type Return = Accumulator::WithElementAtEnd; + fn on_created(&mut self, world: &mut World, metadata: Metadata); } -impl TupleReduceElement for () +pub struct NoCallbacks; + +impl Callbacks for NoCallbacks { - type Return = Accumulator; + fn on_created(&mut self, _world: &mut World, _metadata: Metadata) {} } #[derive(Debug, Component)] -- cgit v1.2.3-18-g5258