use std::any::{Any, TypeId}; use std::fmt::Debug; 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); });