1use crate::{Any, TypeId};
3
4pub trait Component: Send + Sync + 'static {}
6
7pub type ComponentBox = Box<dyn Any + Send + Sync + 'static>;
9
10#[derive(Clone, PartialEq, Eq, Hash)]
12pub struct ComponentKey {
13 type_id: TypeId,
14}
15
16impl ComponentKey {
17 pub fn of<T: Component>() -> Self {
19 Self {
20 type_id: TypeId::of::<T>(),
21 }
22 }
23
24 pub fn from_value<T: Component>(value: &T) -> Self {
26 Self {
27 type_id: value.type_id(),
28 }
29 }
30}
31
32#[macro_export]
34macro_rules! component_id {
35 ($type: ty) => {
36 $crate::ComponentKey::of::<$type>()
37 };
38
39 ($value: expr) => {
40 $crate::ComponentKey::from_value($value)
41 };
42}
43
44#[macro_export]
46macro_rules! component {
47 ($type: ty) => {
48 impl $crate::Component for $type {}
49 };
50}
51
52pub trait Bundle {
54 fn into_boxes(self) -> Vec<(ComponentKey, ComponentBox)>;
56}
57
58impl<T: Component> Bundle for T {
59 fn into_boxes(self) -> Vec<(ComponentKey, ComponentBox)> {
60 vec![(ComponentKey::of::<Self>(), Box::new(self))]
61 }
62}
63
64macro_rules! bundle_tuple_impl {
65 ($($key: tt => $name: ident),*) => {
66 impl<$($name: $crate::Component),*> Bundle for ($($name,)*) {
67 fn into_boxes(self) -> Vec<(ComponentKey, ComponentBox)> {
68 vec![
69 $((ComponentKey::of::<$name>(), Box::new(self.$key))),*
70 ]
71 }
72 }
73 }
74}
75
76bundle_tuple_impl!(0 => A);
77bundle_tuple_impl!(0 => A, 1 => B);
78bundle_tuple_impl!(0 => A, 1 => B, 2 => C);
79bundle_tuple_impl!(0 => A, 1 => B, 2 => C, 3 => D);
80bundle_tuple_impl!(0 => A, 1 => B, 2 => C, 3 => D, 4 => E);
81bundle_tuple_impl!(0 => A, 1 => B, 2 => C, 3 => D, 4 => E, 5 => F);
82bundle_tuple_impl!(0 => A, 1 => B, 2 => C, 3 => D, 4 => E, 5 => F, 6 => G);
83bundle_tuple_impl!(0 => A, 1 => B, 2 => C, 3 => D, 4 => E, 5 => F, 6 => G, 7 => H);
84bundle_tuple_impl!(0 => A, 1 => B, 2 => C, 3 => D, 4 => E, 5 => F, 6 => G, 7 => H, 8 => I);
85bundle_tuple_impl!(0 => A, 1 => B, 2 => C, 3 => D, 4 => E, 5 => F, 6 => G, 7 => H, 8 => I, 9 => J);
86bundle_tuple_impl!(0 => A, 1 => B, 2 => C, 3 => D, 4 => E, 5 => F, 6 => G, 7 => H, 8 => I, 9 => J, 10 => K);
87bundle_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);
88bundle_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);
89bundle_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);
90bundle_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);