flatbox_assets/
resources.rs

1use std::any::TypeId;
2use std::collections::HashMap;
3use std::sync::Arc;
4
5use as_any::AsAny;
6use parking_lot::{RwLock, MappedRwLockReadGuard, RwLockReadGuard, MappedRwLockWriteGuard, RwLockWriteGuard};
7
8pub trait Resource: AsAny + Send + Sync + 'static {}
9impl<T: AsAny + Send + Sync + 'static> Resource for T {}
10
11#[derive(Default)]
12pub struct Resources {
13    res: HashMap<TypeId, Arc<RwLock<dyn Resource>>>
14}
15
16impl Resources {
17    pub fn new() -> Resources {
18        Resources::default()
19    }
20
21    pub fn add_resource<R: Resource>(&mut self, resource: R) {
22        self.res.insert(TypeId::of::<R>(), Arc::new(RwLock::new(resource)));
23    }
24
25    pub fn get_resource<R: Resource>(&self) -> Option<MappedRwLockReadGuard<R>> {
26        if let Some(res) = self.res.get(&TypeId::of::<R>()) {
27            let data = match res.try_read() {
28                Some(data) => data,
29                None => return None,
30            };
31            
32            return RwLockReadGuard::try_map(data, |data| {
33                (*data).as_any().downcast_ref::<R>()
34            }).ok();
35        }
36
37        None
38    }
39
40    pub fn get_resource_mut<R: Resource>(&self) -> Option<MappedRwLockWriteGuard<R>> {
41        if let Some(res) = self.res.get(&TypeId::of::<R>()) {
42            let data = match res.try_write() {
43                Some(data) => data,
44                None => return None,
45            };
46            
47            return RwLockWriteGuard::try_map(data, |data| {
48                (*data).as_any_mut().downcast_mut::<R>()
49            }).ok();
50        }
51
52        None
53    }
54
55    pub fn remove_resource<R: Resource>(&mut self) {
56        self.res.remove(&TypeId::of::<R>());
57    }
58}