diff options
Diffstat (limited to 'ecs/src/system.rs')
| -rw-r--r-- | ecs/src/system.rs | 316 |
1 files changed, 0 insertions, 316 deletions
diff --git a/ecs/src/system.rs b/ecs/src/system.rs deleted file mode 100644 index 046d25b..0000000 --- a/ecs/src/system.rs +++ /dev/null @@ -1,316 +0,0 @@ -use std::any::{type_name, Any}; -use std::convert::Infallible; -use std::fmt::Debug; -use std::marker::PhantomData; -use std::ops::{Deref, DerefMut}; -use std::panic::{RefUnwindSafe, UnwindSafe}; - -use seq_macro::seq; - -use crate::component::{ - Component, - FromOptional as FromOptionalComponent, - FromOptionalMut as FromOptionalMutComponent, -}; -use crate::lock::{ReadGuard, WriteGuard}; -use crate::tuple::{ReduceElement as TupleReduceElement, With as TupleWith}; -use crate::World; - -pub mod stateful; - -pub trait System<'world, Impl>: 'static -{ - type Input; - - #[must_use] - fn initialize(self, input: Self::Input) -> Self; - - fn run<'this>(&'this self, world: &'world World) - where - 'this: 'world; - - fn into_type_erased(self) -> TypeErased; - - fn get_local_component_mut<LocalComponent: Component>( - &self, - ) -> Option<ComponentRefMut<LocalComponent>>; - - fn set_local_component<LocalComponent: Component>( - &mut self, - local_component: LocalComponent, - ); -} - -macro_rules! impl_system { - ($c: tt) => { - seq!(I in 0..$c { - impl<'world, Func, #(TParam~I,)*> System<'world, fn(#(TParam~I,)*)> - for Func - where - Func: Fn(#(TParam~I,)*) + Copy + RefUnwindSafe + UnwindSafe + 'static, - #(TParam~I: Param<'world, Flags = NoInitParamFlag>,)* - { - type Input = Infallible; - - fn initialize(self, _input: Self::Input) -> Self - { - self - } - - fn run<'this>(&'this self, world: &'world World) - where - 'this: 'world - { - let func = *self; - - func(#({ - TParam~I::new(self, world) - },)*); - } - - fn into_type_erased(self) -> TypeErased - { - 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"); - - // SAFETY: The caller of TypeErased::run ensures the lifetime - // is correct - let world = unsafe { &*std::ptr::from_ref(world) }; - - me.run(world); - }), - } - } - - fn get_local_component_mut<LocalComponent: Component>( - &self, - ) -> Option<ComponentRefMut<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"); - } - } - }); - }; -} - -seq!(C in 1..16 { - impl_system!(C); -}); - -pub trait Into<Impl> -{ - type System; - - fn into_system(self) -> Self::System; -} - -pub struct TypeErased -{ - data: Box<dyn Any + RefUnwindSafe + UnwindSafe>, - run: Box<TypeErasedRunFn>, -} - -impl TypeErased -{ - /// Runs the system. - /// - /// # Safety - /// `world_data` must live at least as long as the [`World`] the system belongs to. - pub unsafe fn run(&self, world: &World) - { - // You have to dereference for downcasting to work for some reason - let data = &*self.data; - - (self.run)(data, world); - } -} - -impl Debug for TypeErased -{ - fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result - { - formatter.debug_struct("TypeErased").finish_non_exhaustive() - } -} - -/// Function in [`TypeErased`] used to run the system. -type TypeErasedRunFn = dyn Fn(&dyn Any, &World) + RefUnwindSafe + UnwindSafe; - -/// A parameter to a [`System`]. -pub unsafe trait Param<'world> -{ - type Input; - type Flags; - - 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; -} - -pub struct NoInitParamFlag {} - -/// 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: TupleWith<Self>, -{ - type Return = Accumulator::With; -} - -impl<Accumulator> TupleReduceElement<Accumulator, ParamWithInputFilter> for () -{ - type Return = Accumulator; -} - -#[derive(Debug)] -pub struct ComponentRefMut<'a, ComponentT: Component> -{ - inner: WriteGuard<'a, Box<dyn Component>>, - _ph: PhantomData<ComponentT>, -} - -impl<'a, ComponentT: Component> ComponentRefMut<'a, ComponentT> -{ - pub(crate) fn new(inner: WriteGuard<'a, Box<dyn Component>>) -> Self - { - Self { inner, _ph: PhantomData } - } -} - -impl<'component, ComponentT: Component> FromOptionalMutComponent<'component> - for ComponentRefMut<'component, ComponentT> -{ - fn from_optional_mut_component( - inner: Option<WriteGuard<'component, Box<dyn Component>>>, - _world: &'component World, - ) -> Self - { - Self { - inner: inner.unwrap_or_else(|| { - panic!( - "Component {} was not found in entity", - type_name::<ComponentT>() - ); - }), - _ph: PhantomData, - } - } -} - -impl<'comp, ComponentT> FromOptionalMutComponent<'comp> - for Option<ComponentRefMut<'comp, ComponentT>> -where - ComponentT: Component, -{ - fn from_optional_mut_component( - optional_component: Option<WriteGuard<'comp, Box<dyn Component>>>, - _world: &'comp World, - ) -> Self - { - optional_component.map(|component| ComponentRefMut::new(component)) - } -} - -impl<'a, ComponentT: Component> Deref for ComponentRefMut<'a, ComponentT> -{ - type Target = ComponentT; - - fn deref(&self) -> &Self::Target - { - self.inner.downcast_ref().unwrap() - } -} - -impl<'a, ComponentT: Component> DerefMut for ComponentRefMut<'a, ComponentT> -{ - fn deref_mut(&mut self) -> &mut Self::Target - { - self.inner.downcast_mut().unwrap() - } -} - -#[derive(Debug)] -pub struct ComponentRef<'a, ComponentT: Component> -{ - inner: ReadGuard<'a, Box<dyn Component>>, - _ph: PhantomData<ComponentT>, -} - -impl<'a, ComponentT: Component> ComponentRef<'a, ComponentT> -{ - pub(crate) fn new(inner: ReadGuard<'a, Box<dyn Component>>) -> Self - { - Self { inner, _ph: PhantomData } - } -} - -impl<'component, ComponentT: Component> FromOptionalComponent<'component> - for ComponentRef<'component, ComponentT> -{ - fn from_optional_component( - inner: Option<ReadGuard<'component, Box<dyn Component>>>, - _world: &'component World, - ) -> Self - { - Self { - inner: inner.unwrap_or_else(|| { - panic!( - "Component {} was not found in entity", - type_name::<ComponentT>() - ); - }), - _ph: PhantomData, - } - } -} - -impl<'comp, ComponentT> FromOptionalComponent<'comp> - for Option<ComponentRef<'comp, ComponentT>> -where - ComponentT: Component, -{ - fn from_optional_component( - optional_component: Option<ReadGuard<'comp, Box<dyn Component>>>, - _world: &'comp World, - ) -> Self - { - optional_component.map(|component| ComponentRef::new(component)) - } -} - -impl<'a, ComponentT: Component> Deref for ComponentRef<'a, ComponentT> -{ - type Target = ComponentT; - - fn deref(&self) -> &Self::Target - { - self.inner.downcast_ref().unwrap() - } -} |
