use std::mem::ManuallyDrop;
use crate::storage::ComponentId;
use crate::world::World;
pub trait Component: Send + Sync + 'static {}
impl<T: Send + Sync + 'static> Component for T {}
pub unsafe trait Bundle: Send + Sync + 'static {
#[doc(hidden)]
fn component_ids(world: &mut World, out: &mut Vec<ComponentId>);
#[doc(hidden)]
unsafe fn write(self, f: &mut impl FnMut(usize, *const u8));
}
macro_rules! bundle_tuple {
($($t:ident $i:tt),*) => {
unsafe impl<$($t: Component),*> Bundle for ($($t,)*) {
fn component_ids(world: &mut World, out: &mut Vec<ComponentId>) {
$(out.push(world.register::<$t>());)*
}
unsafe fn write(self, f: &mut impl FnMut(usize, *const u8)) {
let me = ManuallyDrop::new(self);
$(f($i, (&me.$i as *const $t).cast());)*
}
}
};
}
bundle_tuple!(A 0);
bundle_tuple!(A 0, B 1);
bundle_tuple!(A 0, B 1, C 2);
bundle_tuple!(A 0, B 1, C 2, D 3);
bundle_tuple!(A 0, B 1, C 2, D 3, E 4);
bundle_tuple!(A 0, B 1, C 2, D 3, E 4, F 5);
bundle_tuple!(A 0, B 1, C 2, D 3, E 4, F 5, G 6);
bundle_tuple!(A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7);
bundle_tuple!(A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7, I 8);
bundle_tuple!(A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7, I 8, J 9);
bundle_tuple!(A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7, I 8, J 9, K 10);
bundle_tuple!(A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7, I 8, J 9, K 10, L 11);