1use std::mem::ManuallyDrop;
4
5use crate::storage::ComponentId;
6use crate::world::World;
7
8pub trait Component: Send + Sync + 'static {}
10impl<T: Send + Sync + 'static> Component for T {}
11
12pub unsafe trait Bundle: Send + Sync + 'static {
20 #[doc(hidden)]
21 fn component_ids(world: &mut World, out: &mut Vec<ComponentId>);
22 #[doc(hidden)]
23 unsafe fn write(self, f: &mut impl FnMut(usize, *const u8));
24}
25
26macro_rules! bundle_tuple {
27 ($($t:ident $i:tt),*) => {
28 unsafe impl<$($t: Component),*> Bundle for ($($t,)*) {
29 fn component_ids(world: &mut World, out: &mut Vec<ComponentId>) {
30 $(out.push(world.register::<$t>());)*
31 }
32 unsafe fn write(self, f: &mut impl FnMut(usize, *const u8)) {
33 let me = ManuallyDrop::new(self);
34 $(f($i, (&me.$i as *const $t).cast());)*
35 }
36 }
37 };
38}
39bundle_tuple!(A 0);
40bundle_tuple!(A 0, B 1);
41bundle_tuple!(A 0, B 1, C 2);
42bundle_tuple!(A 0, B 1, C 2, D 3);
43bundle_tuple!(A 0, B 1, C 2, D 3, E 4);
44bundle_tuple!(A 0, B 1, C 2, D 3, E 4, F 5);
45bundle_tuple!(A 0, B 1, C 2, D 3, E 4, F 5, G 6);
46bundle_tuple!(A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7);
47bundle_tuple!(A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7, I 8);
48bundle_tuple!(A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7, I 8, J 9);
49bundle_tuple!(A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7, I 8, J 9, K 10);
50bundle_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);