flatbox_assets/
resources.rs1use 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}