use crate::{Any, TypeId};
pub trait Component: Send + Sync + 'static {}
pub type ComponentBox = Box<dyn Any + Send + Sync + 'static>;
#[derive(Clone, PartialEq, Eq, Hash)]
pub struct ComponentKey {
type_id: TypeId,
}
impl ComponentKey {
pub fn of<T: Component>() -> Self {
Self {
type_id: TypeId::of::<T>(),
}
}
pub fn from_value<T: Component>(value: &T) -> Self {
Self {
type_id: value.type_id(),
}
}
}
#[macro_export]
macro_rules! component_id {
($type: ty) => {
$crate::ComponentKey::of::<$type>()
};
($value: expr) => {
$crate::ComponentKey::from_value($value)
};
}
#[macro_export]
macro_rules! component {
($type: ty) => {
impl $crate::Component for $type {}
};
}
pub trait Bundle {
fn into_boxes(self) -> Vec<(ComponentKey, ComponentBox)>;
}
impl<T: Component> Bundle for T {
fn into_boxes(self) -> Vec<(ComponentKey, ComponentBox)> {
vec![(ComponentKey::of::<Self>(), Box::new(self))]
}
}
macro_rules! bundle_tuple_impl {
($($key: tt => $name: ident),*) => {
impl<$($name: $crate::Component),*> Bundle for ($($name,)*) {
fn into_boxes(self) -> Vec<(ComponentKey, ComponentBox)> {
vec![
$((ComponentKey::of::<$name>(), Box::new(self.$key))),*
]
}
}
}
}
bundle_tuple_impl!(0 => A);
bundle_tuple_impl!(0 => A, 1 => B);
bundle_tuple_impl!(0 => A, 1 => B, 2 => C);
bundle_tuple_impl!(0 => A, 1 => B, 2 => C, 3 => D);
bundle_tuple_impl!(0 => A, 1 => B, 2 => C, 3 => D, 4 => E);
bundle_tuple_impl!(0 => A, 1 => B, 2 => C, 3 => D, 4 => E, 5 => F);
bundle_tuple_impl!(0 => A, 1 => B, 2 => C, 3 => D, 4 => E, 5 => F, 6 => G);
bundle_tuple_impl!(0 => A, 1 => B, 2 => C, 3 => D, 4 => E, 5 => F, 6 => G, 7 => H);
bundle_tuple_impl!(0 => A, 1 => B, 2 => C, 3 => D, 4 => E, 5 => F, 6 => G, 7 => H, 8 => I);
bundle_tuple_impl!(0 => A, 1 => B, 2 => C, 3 => D, 4 => E, 5 => F, 6 => G, 7 => H, 8 => I, 9 => J);
bundle_tuple_impl!(0 => A, 1 => B, 2 => C, 3 => D, 4 => E, 5 => F, 6 => G, 7 => H, 8 => I, 9 => J, 10 => K);
bundle_tuple_impl!(0 => A, 1 => B, 2 => C, 3 => D, 4 => E, 5 => F, 6 => G, 7 => H, 8 => I, 9 => J, 10 => K, 11 => L);
bundle_tuple_impl!(0 => A, 1 => B, 2 => C, 3 => D, 4 => E, 5 => F, 6 => G, 7 => H, 8 => I, 9 => J, 10 => K, 11 => L, 12 => M);
bundle_tuple_impl!(0 => A, 1 => B, 2 => C, 3 => D, 4 => E, 5 => F, 6 => G, 7 => H, 8 => I, 9 => J, 10 => K, 11 => L, 12 => M, 13 => N);
bundle_tuple_impl!(0 => A, 1 => B, 2 => C, 3 => D, 4 => E, 5 => F, 6 => G, 7 => H, 8 => I, 9 => J, 10 => K, 11 => L, 12 => M, 13 => N, 14 => O);