1use std::{
2 any::{type_name, Any, TypeId},
3 cell::{Ref, RefMut},
4 collections::HashMap,
5 marker::PhantomData,
6 ops::{Deref, DerefMut},
7};
8
9use crate::states::States;
10
11pub trait WidgetParam {
12 type Item<'new>;
13 fn retrieve(resources: &States) -> Self::Item<'_>;
14}
15
16pub struct Res<'a, T: 'static> {
17 value: Ref<'a, Box<dyn Any>>,
18 _marker: PhantomData<&'a T>,
19}
20
21impl<'a, T: 'static> Deref for Res<'a, T> {
22 type Target = T;
23 fn deref(&self) -> &Self::Target {
24 self.value.downcast_ref().unwrap()
25 }
26}
27
28impl<'a, T: 'static> WidgetParam for Res<'a, T> {
29 type Item<'new> = Res<'new, T>;
30 fn retrieve(resources: &States) -> Self::Item<'_> {
31 Res {
32 value: resources.get(&TypeId::of::<T>()).unwrap().borrow(),
33 _marker: PhantomData,
34 }
35 }
36}
37
38pub struct ResMut<'a, T: 'static> {
39 value: RefMut<'a, Box<dyn Any>>,
40 _marker: PhantomData<&'a mut T>,
41}
42
43impl<T: 'static> Deref for ResMut<'_, T> {
44 type Target = T;
45
46 fn deref(&self) -> &T {
47 self.value.downcast_ref().unwrap()
48 }
49}
50
51impl<T: 'static> DerefMut for ResMut<'_, T> {
52 fn deref_mut(&mut self) -> &mut T {
53 self.value.downcast_mut().unwrap()
54 }
55}
56
57impl<'a, T: 'static> WidgetParam for ResMut<'a, T> {
58 type Item<'new> = ResMut<'new, T>;
59
60 fn retrieve(resources: &States) -> Self::Item<'_> {
61 ResMut {
62 value: resources
63 .get(&TypeId::of::<T>())
64 .unwrap_or_else(|| {
65 panic!(
66 "Resource: `{}` with id `{:?}` Not Found",
67 type_name::<T>(),
68 TypeId::of::<T>()
69 )
70 })
71 .borrow_mut(),
72 _marker: PhantomData,
73 }
74 }
75}