my_ecs/ecs/ent/
component.rs1use crate::ds::prelude::*;
2use my_ecs_macros::repeat_macro;
3
4pub trait Component: Send + Sync + Sized + 'static {
6 const IS_SEND: bool = true; const IS_SYNC: bool = true; const IS_DEFAULT: bool = false; const FN_DEFAULT: FnDefaultRaw = unimpl_default; const IS_CLONE: bool = false; const FN_CLONE: FnCloneRaw = unimpl_clone; fn key() -> ComponentKey {
16 ComponentKey::of::<Self>()
17 }
18
19 fn type_info() -> TypeInfo {
20 TypeInfo::new::<Self>(
21 Self::IS_SEND,
22 Self::IS_SYNC,
23 Self::IS_DEFAULT.then_some(Self::FN_DEFAULT),
24 Self::IS_CLONE.then_some(Self::FN_CLONE),
25 )
26 }
27}
28
29pub trait Components: 'static {
31 type Keys: AsRef<[ComponentKey]>;
32 type Infos: AsRef<[TypeInfo]>;
33
34 const LEN: usize;
35
36 fn keys() -> Self::Keys;
38
39 fn infos() -> Self::Infos;
41
42 fn sorted_keys() -> Self::Keys;
44}
45
46macro_rules! impl_components {
47 ($n:expr, $($i:expr),*) => {const _: () = {
48 #[allow(unused_imports)]
49 use $crate::{
50 ds::TypeInfo,
51 ecs::ent::component::{Component, Components, ComponentKey},
52 };
53 use paste::paste;
54
55 paste! {
56 #[allow(unused_parens)]
57 impl<$([<A $i>]: Component),*> Components for ( $([<A $i>]),* ) {
58 type Keys = [ComponentKey; $n];
59 type Infos = [TypeInfo; $n];
60
61 const LEN: usize = $n;
62
63 fn keys() -> Self::Keys {
64 [ $( [<A $i>]::key() ),* ]
65 }
66
67 fn infos() -> Self::Infos {
68 [ $( [<A $i>]::type_info() ),* ]
69 }
70
71 fn sorted_keys() -> Self::Keys {
72 let mut keys = [ $( [<A $i>]::key() ),* ];
73 keys.sort_unstable();
74 keys
75 }
76 }
77 }
78 };};
79}
80repeat_macro!(impl_components, ..=32);
81
82pub type ComponentKey = ATypeId<ComponentKey_>;
84pub struct ComponentKey_;
85
86#[cfg(test)]
87mod tests {
88 use super::*;
89 use crate as my_ecs;
90 use my_ecs_macros::Component;
91
92 #[test]
93 fn test_component_detect_impls() {
94 #![allow(dead_code)]
95
96 #[derive(Component, Clone)]
97 struct CloneA([u8; 1]);
98 #[derive(Component, Clone)]
99 struct CloneB([u8; 2]);
100
101 #[derive(Component)]
102 struct NonCloneA([u8; 1]);
103 #[derive(Component)]
104 struct NonCloneB([u8; 2]);
105
106 assert!(is_clone_fn_eq::<NonCloneA, NonCloneB>());
109
110 assert!(is_clone_fn_ne::<CloneA, CloneB>());
113 assert!(is_clone_fn_ne::<CloneA, NonCloneA>());
114 assert!(is_clone_fn_ne::<CloneB, NonCloneA>());
115
116 fn is_clone_fn_eq<Ca: Component, Cb: Component>() -> bool {
119 let clone_a = Ca::FN_CLONE as usize;
120 let clone_b = Cb::FN_CLONE as usize;
121 clone_a == clone_b
122 }
123
124 fn is_clone_fn_ne<Ca: Component, Cb: Component>() -> bool {
125 let clone_a = Ca::FN_CLONE as usize;
126 let clone_b = Cb::FN_CLONE as usize;
127 clone_a != clone_b
128 }
129 }
130}