use std::{any::{TypeId, Any}, ptr::NonNull, mem::size_of}; use crate::{component::Component, component_info::ComponentInfo}; pub trait Bundle { /// Get a list of type ids that this bundle is storing fn type_ids(&self) -> Vec; /// Get ComponentInfo's for the components in this bundle fn info(&self) -> Vec; /// Take the bundle by calling the closure with pointers to each component, its type and size. /// The closure is expected to take ownership of the pointer. fn take(self, f: impl FnMut(NonNull, TypeId, usize)); } // The macro below can implement this for us, but this is here for development impl Bundle for (C1,) { fn type_ids(&self) -> Vec { vec![self.0.type_id()] } fn info(&self) -> Vec { vec![ComponentInfo::new::()] } fn take(self, mut f: impl FnMut(NonNull, TypeId, usize)) { let (c1, ) = self; f(NonNull::from(&c1).cast(), TypeId::of::(), size_of::()); } } macro_rules! impl_bundle_tuple { ( $($name: ident),+ ) => ( #[allow(non_snake_case)] impl<$($name: Component),+> Bundle for ($($name,)+) { fn type_ids(&self) -> Vec { // these names wont follow rust convention, but its a macro so deal with it let ($($name),+) = self; vec![$($name.type_id()),+] } fn info(&self) -> Vec { vec![$(ComponentInfo::new::<$name>()),+] } fn take(self, mut f: impl FnMut(NonNull, TypeId, usize)) { // these names wont follow rust convention, but its a macro so deal with it let ($($name),+) = self; $(f(NonNull::from(&$name).cast(), TypeId::of::<$name>(), size_of::<$name>());)+ } } ); } // hopefully 16 components in a bundle is enough impl_bundle_tuple! { C1, C2 } impl_bundle_tuple! { C1, C2, C3 } impl_bundle_tuple! { C1, C2, C3, C4 } impl_bundle_tuple! { C1, C2, C3, C4, C5 } impl_bundle_tuple! { C1, C2, C3, C4, C5, C6 } impl_bundle_tuple! { C1, C2, C3, C4, C5, C6, C7 } impl_bundle_tuple! { C1, C2, C3, C4, C5, C6, C7, C8 } impl_bundle_tuple! { C1, C2, C3, C4, C5, C6, C7, C8, C9 } impl_bundle_tuple! { C1, C2, C3, C4, C5, C6, C7, C8, C9, C10 } impl_bundle_tuple! { C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11 } impl_bundle_tuple! { C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12 } impl_bundle_tuple! { C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13 } impl_bundle_tuple! { C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 } impl_bundle_tuple! { C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15 } impl_bundle_tuple! { C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15, C16 }