use std::any::{Any, TypeId}; use std::fmt::Debug; use std::ops::{Deref, DerefMut}; use seq_macro::seq; pub trait Component: Any { #[doc(hidden)] fn as_any_mut(&mut self) -> &mut dyn Any; #[doc(hidden)] fn as_any(&self) -> &dyn Any; } impl Component for Value { fn as_any_mut(&mut self) -> &mut dyn Any { self } fn as_any(&self) -> &dyn Any { self } } impl dyn Component { pub fn downcast_mut(&mut self) -> Option<&mut Real> { self.as_any_mut().downcast_mut() } 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 MutRefs<'component> where Self: 'component; fn into_vec(self) -> Vec>; fn type_ids() -> Vec; fn from_components<'components>( components: &'components mut [Box], ) -> Self::MutRefs<'components>; } macro_rules! inner { ($c: tt) => { seq!(I in 0..=$c { impl<#(Comp~I: Component,)*> Sequence for (#(Comp~I,)*) { 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>( components: &'components mut [Box], ) -> Self::MutRefs<'components> { #( 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, Value> { value: &'world mut Value, } impl<'world, Value> Local<'world, Value> { pub(crate) fn new(value: &'world mut Value) -> Self { Self { value } } } impl<'world, Value> Deref for Local<'world, Value> { type Target = Value; fn deref(&self) -> &Self::Target { self.value } } impl<'world, Value> DerefMut for Local<'world, Value> { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.value } }