1use std::{
2 any::{Any, TypeId},
3 collections::HashMap,
4 slice::Iter
5};
6
7trait AsAny {
8 fn as_any(&self) -> &dyn Any;
9 fn as_mut_any(&mut self) -> &mut dyn Any;
10}
11
12impl<T> AsAny for Vec<Option<T>>
13where
14 T: 'static,
15{
16 fn as_any(&self) -> &dyn Any {
17 self
18 }
19
20 fn as_mut_any(&mut self) -> &mut dyn Any {
21 self
22 }
23}
24
25#[derive(Default)]
26pub struct ComponentStorage {
27 data: HashMap<TypeId, Box<dyn AsAny>>,
28}
29
30impl ComponentStorage {
31 fn add_type<T>(&mut self)
32 where
33 T: 'static,
34 {
35 let id = TypeId::of::<T>();
36 self.data.entry(id).or_insert_with(|| {
37 let vec: Vec<Option<T>> = Vec::new();
38 Box::new(vec)
39 });
40 }
41
42 fn get_vec<T>(&self) -> Option<&Vec<Option<T>>>
43 where
44 T: 'static,
45 {
46 let id = TypeId::of::<T>();
47 let boxed_vec = match self.data.get(&id) {
48 Some(v) => v,
49 None => return None,
50 };
51
52 boxed_vec.as_any().downcast_ref::<Vec<Option<T>>>()
53 }
54
55 fn get_mut_vec<T>(&mut self) -> Option<&mut Vec<Option<T>>>
56 where
57 T: 'static,
58 {
59 let id = TypeId::of::<T>();
60 let boxed_vec = match self.data.get_mut(&id) {
61 Some(v) => v,
62 None => return None,
63 };
64
65 boxed_vec.as_mut_any().downcast_mut::<Vec<Option<T>>>()
66 }
67
68 pub fn add_component<T>(&mut self, index: usize, component: T)
69 where
70 T: 'static,
71 {
72 self.add_type::<T>();
73 match self.get_mut_vec::<T>() {
74 Some(vec_t) => {
75 if index >= vec_t.len() {
76 vec_t.resize_with(index + 1, || None);
77 vec_t[index] = Some(component)
78 }
79 }
80 None => {}
81 }
82 }
83
84 pub fn get_component<T>(&self, index: usize) -> Option<&T>
85 where
86 T: 'static,
87 {
88 match self.get_vec::<T>() {
89 Some(vec_t) => {
90 if index < vec_t.len() {
91 vec_t[index].as_ref()
92 } else {
93 None
94 }
95 }
96 None => None,
97 }
98 }
99
100 pub fn get_mut_component<T>(&mut self, index: usize) -> Option<&mut T>
101 where
102 T: 'static,
103 {
104 match self.get_mut_vec::<T>() {
105 Some(vec_t) => {
106 if index < vec_t.len() {
107 vec_t[index].as_mut()
108 } else {
109 None
110 }
111 }
112 None => None,
113 }
114 }
115
116 pub fn get_components_iter<T>(&self) -> Option<Iter<'_, Option<T>>> where T: 'static {
117 self.get_vec::<T>().map(|vec_t| vec_t.iter())
118 }
119
120 pub fn remove_component<T>(&mut self, index: usize) where T: 'static {
121 match self.get_mut_vec::<T>() {
122 Some(vec_t) => {
123 vec_t[index] = None;
124 }
125 None => { }
126 }
127 }
128}
129
130#[cfg(test)]
131mod tests {
132 use super::ComponentStorage;
133
134 #[derive(Debug)]
135 struct Foo;
136
137 #[derive(Debug)]
138 struct Bar {
139 x: u32,
140 }
141
142 #[test]
143 fn add_type() {
144 let mut cs = ComponentStorage::default();
145 assert_eq!(cs.data.len(), 0);
146 cs.add_type::<Foo>();
147 cs.add_type::<Bar>();
148 assert_eq!(cs.data.len(), 2);
149 }
150
151 #[test]
152 fn add_same_type() {
153 let mut cs = ComponentStorage::default();
154 assert_eq!(cs.data.len(), 0);
155 cs.add_type::<Foo>();
156 cs.add_type::<Foo>();
157 assert_eq!(cs.data.len(), 1);
158 }
159
160 #[test]
161 fn get_vec() {
162 let mut cs = ComponentStorage::default();
163 cs.add_type::<Foo>();
164 let foo_vec = cs.get_vec::<Foo>();
165 let bar_vec = cs.get_vec::<Bar>();
166 assert!(foo_vec.is_some());
167 assert!(bar_vec.is_none());
168 }
169
170 #[test]
171 fn get_mut_vec() {
172 let mut cs = ComponentStorage::default();
173 cs.add_type::<Foo>();
174 let foo_vec = cs.get_mut_vec::<Foo>();
175 assert!(foo_vec.is_some());
176 let bar_vec = cs.get_mut_vec::<Bar>();
177 assert!(bar_vec.is_none());
178 }
179
180 #[test]
181 fn add_component() {
182 let mut cs = ComponentStorage::default();
183 cs.add_component(0, Foo {});
184 match cs.get_vec::<Foo>() {
185 Some(vec_t) => assert_eq!(vec_t.len(), 1),
186 None => panic!("Vec should exist'"),
187 }
188 }
189
190 #[test]
191 fn add_component_resize_check() {
192 let mut cs = ComponentStorage::default();
193 cs.add_component(0, Foo {});
194 match cs.get_vec::<Foo>() {
195 Some(vec_t) => assert_eq!(vec_t.len(), 1),
196 None => panic!("Vec should exist'"),
197 }
198
199 cs.add_component(10, Foo {});
200 match cs.get_vec::<Foo>() {
201 Some(vec_t) => assert_eq!(vec_t.len(), 11),
202 None => panic!("Vec should exist'"),
203 }
204
205 }
206
207 #[test]
208 fn get_component() {
209 let mut cs = ComponentStorage::default();
210 cs.add_component(0, Foo {});
211 match cs.get_component::<Foo>(0) {
212 Some(_) => {}
213 None => panic!("Component should exist"),
214 }
215 }
216
217 #[test]
218 #[should_panic]
219 fn get_component_2() {
220 let mut cs = ComponentStorage::default();
221 cs.add_component(0, Foo {});
222 match cs.get_component::<Bar>(0) {
223 Some(_) => {}
224 None => panic!("Component should exist"),
225 }
226 }
227
228 #[test]
229 fn get_mut_component() {
230 let mut cs = ComponentStorage::default();
231 cs.add_component(0, Foo {});
232 match cs.get_mut_component::<Foo>(0) {
233 Some(_) => {}
234 None => panic!("Component should exist"),
235 }
236 }
237
238 #[test]
239 #[should_panic]
240 fn get_mut_component_2() {
241 let mut cs = ComponentStorage::default();
242 cs.add_component(0, Foo {});
243 match cs.get_mut_component::<Bar>(0) {
244 Some(_) => {}
245 None => panic!("Component should exist"),
246 }
247 }
248
249 #[test]
250 fn has_mut_component_changed() {
251 let mut cs = ComponentStorage::default();
252 cs.add_component(0, Bar { x: 100 });
253 match cs.get_mut_component::<Bar>(0) {
254 Some(bar) => {
255 assert_eq!(bar.x, 100);
256 bar.x = 200;
257 }
258 None => panic!("Component should exist"),
259 }
260
261 match cs.get_mut_component::<Bar>(0) {
262 Some(bar) => {
263 assert_eq!(bar.x, 200);
264 }
265 None => panic!("Component should exist"),
266 }
267 }
268
269 #[test]
270 fn get_components_iter() {
271 let mut cs = ComponentStorage::default();
272 cs.add_component(0, Bar { x: 100 });
273 match cs.get_components_iter::<Bar>() {
274 Some(_) => { }
275 None => { panic!("Failed to get iter for components")}
276 };
277 }
278
279 #[test]
280 fn remove_component() {
281 let mut cs = ComponentStorage::default();
282 cs.add_component(0, Foo { });
283 match cs.get_component::<Foo>(0) {
284 Some(_) => { },
285 None => { panic!("Added the wrong component to entity")}
286 };
287 cs.remove_component::<Foo>(0);
288 match cs.get_component::<Foo>(0) {
289 Some(_) => { panic!("Failed to remove component") },
290 None => { }
291 };
292 }
293
294}