component_storage/
lib.rs

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}