2023-11-26 05:56:30 +00:00
|
|
|
use std::{any::{TypeId, Any}, ptr::NonNull, mem::size_of};
|
2023-05-25 04:11:16 +00:00
|
|
|
|
2023-11-26 05:56:30 +00:00
|
|
|
use crate::{component::Component, component_info::ComponentInfo};
|
2023-05-25 04:11:16 +00:00
|
|
|
|
|
|
|
pub trait Bundle {
|
2023-11-26 05:56:30 +00:00
|
|
|
/// Get a list of type ids that this bundle is storing
|
|
|
|
fn type_ids(&self) -> Vec<TypeId>;
|
2023-11-25 23:43:11 +00:00
|
|
|
|
2023-11-26 05:56:30 +00:00
|
|
|
/// Get ComponentInfo's for the components in this bundle
|
2023-11-25 23:43:11 +00:00
|
|
|
fn info(&self) -> Vec<ComponentInfo>;
|
|
|
|
|
|
|
|
/// 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.
|
2023-11-26 05:56:30 +00:00
|
|
|
fn take(self, f: impl FnMut(NonNull<u8>, TypeId, usize));
|
2023-05-25 04:11:16 +00:00
|
|
|
}
|
|
|
|
|
2023-11-26 05:56:30 +00:00
|
|
|
// The macro below can implement this for us, but this is here for development
|
2023-11-25 23:43:11 +00:00
|
|
|
impl<C1: Component> Bundle for (C1,) {
|
2023-11-26 05:56:30 +00:00
|
|
|
fn type_ids(&self) -> Vec<TypeId> {
|
2023-11-25 23:43:11 +00:00
|
|
|
vec![self.0.type_id()]
|
|
|
|
}
|
|
|
|
|
|
|
|
fn info(&self) -> Vec<ComponentInfo> {
|
|
|
|
vec![ComponentInfo::new::<C1>()]
|
|
|
|
}
|
|
|
|
|
2023-11-26 05:56:30 +00:00
|
|
|
fn take(self, mut f: impl FnMut(NonNull<u8>, TypeId, usize)) {
|
2023-11-25 23:43:11 +00:00
|
|
|
let (c1, ) = self;
|
|
|
|
|
2023-11-26 05:56:30 +00:00
|
|
|
f(NonNull::from(&c1).cast(), TypeId::of::<C1>(), size_of::<C1>());
|
2023-11-25 23:43:11 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-26 05:56:30 +00:00
|
|
|
macro_rules! impl_bundle_tuple {
|
|
|
|
( $($name: ident),+ ) => (
|
|
|
|
#[allow(non_snake_case)]
|
2023-05-26 02:59:27 +00:00
|
|
|
impl<$($name: Component),+> Bundle for ($($name,)+) {
|
2023-11-26 05:56:30 +00:00
|
|
|
fn type_ids(&self) -> Vec<TypeId> {
|
|
|
|
// these names wont follow rust convention, but its a macro so deal with it
|
|
|
|
let ($($name),+) = self;
|
|
|
|
vec![$($name.type_id()),+]
|
2023-05-25 04:11:16 +00:00
|
|
|
}
|
|
|
|
|
2023-11-26 05:56:30 +00:00
|
|
|
fn info(&self) -> Vec<ComponentInfo> {
|
|
|
|
vec![$(ComponentInfo::new::<$name>()),+]
|
2023-05-25 04:11:16 +00:00
|
|
|
}
|
2023-11-25 23:43:11 +00:00
|
|
|
|
2023-11-26 05:56:30 +00:00
|
|
|
fn take(self, mut f: impl FnMut(NonNull<u8>, TypeId, usize)) {
|
|
|
|
// these names wont follow rust convention, but its a macro so deal with it
|
|
|
|
let ($($name),+) = self;
|
2023-11-25 23:43:11 +00:00
|
|
|
|
2023-11-26 05:56:30 +00:00
|
|
|
$(f(NonNull::from(&$name).cast(), TypeId::of::<$name>(), size_of::<$name>());)+
|
2023-11-25 23:43:11 +00:00
|
|
|
}
|
2023-05-25 04:11:16 +00:00
|
|
|
}
|
|
|
|
);
|
2023-11-26 05:56:30 +00:00
|
|
|
}
|
2023-05-25 04:11:16 +00:00
|
|
|
|
|
|
|
// hopefully 16 components in a bundle is enough
|
2023-11-26 05:56:30 +00:00
|
|
|
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 }
|