wecs_core/resource/
resource.rs

1use std::{
2    any::{Any, TypeId},
3    collections::HashMap,
4};
5
6pub trait Resource {}
7
8pub struct ResourceId(usize);
9
10struct ResourceData {
11    resource: Box<dyn Any>,
12}
13
14pub struct Resources {
15    data: Vec<ResourceData>,
16    id_mappings: HashMap<TypeId, usize>,
17}
18
19impl Default for Resources {
20    fn default() -> Self {
21        Self::new()
22    }
23}
24
25impl Resources {
26    pub fn new() -> Self {
27        Self {
28            data: Vec::default(),
29            id_mappings: HashMap::default(),
30        }
31    }
32
33    pub fn init<R>(&mut self) -> ResourceId
34    where
35        R: Resource + Default + 'static,
36    {
37        self.insert(R::default())
38    }
39
40    pub fn insert<R>(&mut self, resource: R) -> ResourceId
41    where
42        R: Resource + 'static,
43    {
44        let type_id = TypeId::of::<R>();
45
46        let index = self.id_mappings.entry(type_id).or_insert(self.data.len());
47        self.data.insert(
48            *index,
49            ResourceData {
50                resource: Box::new(resource),
51            },
52        );
53
54        ResourceId(*index)
55    }
56
57    pub fn remove<R>(&mut self)
58    where
59        R: Resource + 'static,
60    {
61        let type_id = TypeId::of::<R>();
62
63        if let Some(index) = self.id_mappings.remove(&type_id) {
64            self.data.remove(index);
65        };
66    }
67
68    pub fn get<R>(&self) -> Option<&R>
69    where
70        R: Resource + 'static,
71    {
72        return if let Some(index) = self.id_mappings.get(&TypeId::of::<R>()) {
73            self.data.get(*index).map(|data| {
74                data.resource
75                    .downcast_ref::<R>()
76                    .expect("could not cast resource")
77            })
78        } else {
79            None
80        };
81    }
82
83    pub fn get_or_init<R>(&mut self) -> Option<&R>
84    where
85        R: Resource + Default + 'static,
86    {
87        return if let Some(index) = self.id_mappings.get(&TypeId::of::<R>()) {
88            self.data.get(*index).map(|data| {
89                data.resource
90                    .downcast_ref::<R>()
91                    .expect("could not cast resource")
92            })
93        } else {
94            self.init::<R>();
95            self.get::<R>()
96        };
97    }
98
99    pub fn get_mut<R>(&mut self) -> Option<&mut R>
100    where
101        R: Resource + 'static,
102    {
103        return if let Some(index) = self.id_mappings.get(&TypeId::of::<R>()) {
104            self.data.get_mut(*index).map(|data| {
105                data.resource
106                    .downcast_mut::<R>()
107                    .expect("could not cast resource")
108            })
109        } else {
110            None
111        };
112    }
113
114    pub fn get_or_init_mut<R>(&mut self) -> Option<&mut R>
115    where
116        R: Resource + Default + 'static,
117    {
118        return if let Some(index) = self.id_mappings.get(&TypeId::of::<R>()) {
119            self.data.get_mut(*index).map(|data| {
120                data.resource
121                    .downcast_mut::<R>()
122                    .expect("could not cast resource")
123            })
124        } else {
125            self.init::<R>();
126            self.get_mut::<R>()
127        };
128    }
129}