1use std::{
2 any::{Any, TypeId},
3 collections::HashMap,
4};
5
6use crate::{
7 ecs::Component,
8 world::Archetype,
9};
10
11pub struct Container {
12 components: HashMap<TypeId, Box<dyn Any>>,
13}
14
15impl Container {
16 pub fn new<A: Archetype>() -> Self {
17 let mut result = Self {
18 components: HashMap::new(),
19 };
20 A::map(&mut result);
21 result
22 }
23
24 pub fn push<T: Component>(&mut self, component: T) {
25 self.components
26 .get_mut(&TypeId::of::<T>())
27 .map(|v| {
28 v.downcast_mut::<Vec<T>>()
29 .unwrap()
30 .push(component)
31 });
32 }
33
34 pub fn init<T: Component>(&mut self) {
35 self.components.insert(TypeId::of::<T>(), Box::new(Vec::<T>::new()));
36 }
37
38 pub fn get_mut<T: Component>(&self) -> Option<&mut Vec<T>>
39 where T: Component
40 {
41 self.components
42 .get(&TypeId::of::<T>())
43 .map(|v| {
44 unsafe {
45 let vec_ref = v.downcast_ref::<Vec<T>>().unwrap();
46 let vec_ptr = vec_ref as *const Vec<T>;
47 let mut_ptr = vec_ptr as *mut Vec<T>;
48 &mut *mut_ptr
49 }
50 })
51 }
52
53 pub fn get<T: Component>(&self) -> Option<&Vec<T>>
54 where T: Component
55 {
56 self.components
57 .get(&TypeId::of::<T>())
58 .map(|v| v.downcast_ref::<Vec<T>>().unwrap())
59 }
60
61 pub fn has(&self, key: TypeId) -> bool {
80 self.components.contains_key(&key)
81 }
82
83 pub fn len(&self) -> usize {
84 self.components.len()
85 }
86}
87
88#[cfg(test)]
89mod tests {
90 struct Item1(u32);
91 struct Item2(u32);
92 use crate::container::Container;
93 #[test]
94 fn mutability() {
95 let mut c = Container::new::<(Item1, Item2)>();
96 c.push::<Item1>(Item1(123));
97 c.push::<Item2>(Item2(666));
98
99 for i in c.get_mut::<Item1>().unwrap() {
100 i.0 += 198;
101 }
102
103 for i in c.get::<Item1>().unwrap() {
104 assert_eq!(i.0, 321);
105 }
106
107 }
108}