1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
use crate::*;
use std::any::TypeId;
use std::collections::HashMap;
use std::rc::Rc;

pub struct Components {
    any: HashMap<TypeId, Rc<dyn AnyStorage>>,
}

impl Components {
    pub fn new() -> Self {
        Self {
            any: HashMap::new(),
        }
    }

    pub fn get_storage<T: AnyStorage>(&self) -> Option<Rc<T>> {
        match self.any.get(&TypeId::of::<T>()) {
            Some(storage) => match storage.clone().downcast_rc() {
                Ok(r) => Some(r),
                Err(_) => unreachable!(),
            },
            None => None,
        }
    }

    pub fn get_storage_mut<T: AnyStorage>(&self) -> Option<Rc<T>> {
        match self.any.get(&TypeId::of::<T>()) {
            Some(storage) => match storage.clone().downcast_rc() {
                Ok(r) => Some(r),
                Err(_) => unreachable!(),
            },
            None => None,
        }
    }

    pub fn add<T: AnyStorage>(&mut self, storage: T) {
        let id = TypeId::of::<T>();
        assert!(
            self.any.get(&id).is_none(),
            "Added component twice to the same archetype"
        );
        self.any.insert(id, Rc::new(storage));
    }
}