dotrix_ecs/
container.rs

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    /*
62    pub fn select<A, B, C>(&mut self) -> (std::slice::Iter<A>, std::slice::IterMut<B>, std::slice::IterMut<C>)
63    where
64        A: Component,
65        B: Component,
66        C: Component,
67    {
68        self.components.into_iter()
69            .filter(|k| k.0 == TypeId::of::<A>() || k.0 == TypeId::of::<C>() || k.0 == TypeId::of::<B>())
70            .map(|v| match v.0 {
71                TypeId::of::<A>() => v.1.downcast_mut::<Vec<A>>().unwrap(),
72                TypeId::of::<B>() => v.1.downcast_mut::<Vec<B>>().unwrap(),
73                TypeId::of::<C>() => v.1.downcast_mut::<Vec<C>>().unwrap(),
74            })
75            .flatten()
76    }
77    */
78
79    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}