use std::any::{Any, TypeId}; use std::fmt::Debug; use std::ops::{Deref, DerefMut}; use seq_macro::seq; use crate::system::{Input as SystemInput, Param as SystemParam, System}; use crate::ComponentStorage; pub trait Component: SystemInput + Any { #[doc(hidden)] fn as_any_mut(&mut self) -> &mut dyn Any; #[doc(hidden)] fn as_any(&self) -> &dyn Any; } impl dyn Component { pub fn downcast_mut(&mut self) -> Option<&mut Real> { self.as_any_mut().downcast_mut() } pub fn downcast_ref(&self) -> Option<&Real> { self.as_any().downcast_ref() } pub fn is(&self) -> bool { self.as_any().is::() } } impl Debug for dyn Component { fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { formatter.debug_struct("Component").finish_non_exhaustive() } } /// A sequence of components. pub trait Sequence { type Refs<'component> where Self: 'component; type MutRefs<'component> where Self: 'component; fn into_vec(self) -> Vec>; fn type_ids() -> Vec; fn from_components(components: &[Box]) -> Self::Refs<'_>; fn from_components_mut(components: &mut [Box]) -> Self::MutRefs<'_>; } macro_rules! inner { ($c: tt) => { seq!(I in 0..=$c { impl<#(Comp~I: Component,)*> Sequence for (#(Comp~I,)*) { type Refs<'component> = (#(&'component Comp~I,)*) where Self: 'component; type MutRefs<'component> = (#(&'component mut Comp~I,)*) where Self: 'component; fn into_vec(self) -> Vec> { Vec::from_iter([#(Box::new(self.I) as Box,)*]) } fn type_ids() -> Vec { vec![ #( TypeId::of::(), )* ] } fn from_components(components: &[Box]) -> Self::Refs<'_> { #( let mut comp_~I = None; )* for comp in components { #( if comp.is::() { comp_~I = Some(comp); continue; } )* } (#( comp_~I.unwrap().downcast_ref::().unwrap(), )*) } fn from_components_mut( components: &mut [Box], ) -> Self::MutRefs<'_> { #( let mut comp_~I = None; )* for comp in components.iter_mut() { #( if comp.is::() { comp_~I = Some(comp); continue; } )* } (#( comp_~I.unwrap().downcast_mut::().unwrap(), )*) } } }); }; } seq!(C in 0..=64 { inner!(C); }); /// Holds a component which is local to a single system. #[derive(Debug)] pub struct Local<'world, LocalComponent: Component> { local_component: &'world mut LocalComponent, } impl<'world, LocalComponent> Local<'world, LocalComponent> where LocalComponent: Component, { fn new(local_component: &'world mut LocalComponent) -> Self { Self { local_component } } } unsafe impl<'world, LocalComponent> SystemParam<'world> for Local<'world, LocalComponent> where LocalComponent: Component, { type Flags = (); type Input = LocalComponent; fn initialize(system: &mut impl System, input: Self::Input) { system.set_local_component(input); } fn new( system: &'world mut impl System, _component_storage: &'world mut ComponentStorage, ) -> Self { let local_component = system .get_local_component_mut::() .expect("Local component is uninitialized"); Self::new(local_component) } fn is_compatible>() -> bool { let other_comparable = Other::get_comparable(); let Some(other_type_id) = other_comparable.downcast_ref::() else { return true; }; TypeId::of::() != *other_type_id } fn get_comparable() -> Box { Box::new(TypeId::of::()) } } impl<'world, LocalComponent> Deref for Local<'world, LocalComponent> where LocalComponent: Component, { type Target = LocalComponent; fn deref(&self) -> &Self::Target { self.local_component } } impl<'world, LocalComponent> DerefMut for Local<'world, LocalComponent> where LocalComponent: Component, { fn deref_mut(&mut self) -> &mut Self::Target { self.local_component } }