lyra-engine/lyra-ecs/src/bundle.rs

73 lines
2.8 KiB
Rust
Raw Normal View History

use std::{any::{TypeId, Any}, ptr::NonNull, mem::size_of};
2023-05-25 04:11:16 +00:00
use crate::{component::Component, component_info::ComponentInfo};
2023-05-25 04:11:16 +00:00
pub trait Bundle {
/// 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
/// 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.
fn take(self, f: impl FnMut(NonNull<u8>, TypeId, usize));
2023-05-25 04:11:16 +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,) {
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>()]
}
fn take(self, mut f: impl FnMut(NonNull<u8>, TypeId, usize)) {
2023-11-25 23:43:11 +00:00
let (c1, ) = self;
f(NonNull::from(&c1).cast(), TypeId::of::<C1>(), size_of::<C1>());
2023-11-25 23:43:11 +00:00
}
}
macro_rules! impl_bundle_tuple {
( $($name: ident),+ ) => (
#[allow(non_snake_case)]
impl<$($name: Component),+> Bundle for ($($name,)+) {
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
}
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
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
$(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-05-25 04:11:16 +00:00
// 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 }