comfy_core/
events.rs

1use crate::*;
2
3use std::any::TypeId;
4
5// pub struct Events {
6//     pub events: HashMap<TypeId, VecDeque<Box<dyn Any>>>,
7// }
8//
9// impl Events {
10//     pub fn new() -> Self {
11//         Self { events: HashMap::default() }
12//     }
13//
14//     pub fn send<T: 'static>(&mut self, event: T) {
15//         self.events
16//             .entry(TypeId::of::<T>())
17//             .or_insert_with(VecDeque::default)
18//             .push_back(Box::new(event));
19//     }
20//
21//     pub fn get<T: 'static>(&mut self) -> &mut VecDeque<Box<&mut T>> {
22//         let queue = self
23//             .events
24//             .entry(TypeId::of::<T>())
25//             .or_insert_with(VecDeque::default);
26//
27//         // ??? magic downcast
28//     }
29// }
30
31pub struct Events {
32    pub events: HashMap<TypeId, Box<dyn Any>>,
33}
34
35impl Events {
36    pub fn new() -> Self {
37        Self { events: HashMap::default() }
38    }
39
40    pub fn send<T: 'static>(&mut self, event: T) {
41        let queue = self
42            .events
43            .entry(TypeId::of::<T>())
44            .or_insert_with(|| Box::<VecDeque<T>>::default());
45
46        if let Some(queue) = queue.downcast_mut::<VecDeque<T>>() {
47            queue.push_back(event);
48        }
49    }
50
51    pub fn get<T: 'static>(&mut self) -> &mut VecDeque<T> {
52        self.events
53            .entry(TypeId::of::<T>())
54            .or_insert_with(|| Box::<VecDeque<T>>::default())
55            .downcast_mut()
56            .unwrap()
57    }
58}
59
60mod tests {
61    #[test]
62    pub fn basic_usage() {
63        use crate::Events;
64
65        let mut events = Events::new();
66
67        events.send(3);
68        events.send(4);
69        events.send(5);
70
71        events.send("foo");
72        events.send("bar");
73
74        let things = events.get::<i32>().iter_mut().collect::<Vec<_>>();
75        assert!(things.into_iter().eq(&[3, 4, 5]));
76
77        let strings = events.get::<&str>().iter_mut().collect::<Vec<_>>();
78        assert!(strings.into_iter().eq(&["foo", "bar"]));
79    }
80}
81
82// TODO: look at resources and then delete this
83// #[derive(Default)]
84// pub struct Context {
85//     resources: HashMap<std::any::TypeId, RefCell<Box<dyn std::any::Any>>>,
86// }
87//
88// impl Context {
89//     pub fn register_resource<T: 'static>(&mut self, res: T) {
90//         self.resources
91//             .insert(std::any::TypeId::of::<T>(), RefCell::new(Box::new(res)));
92//     }
93//
94//     pub fn get_resource<T: 'static>(&self) -> impl Deref<Target = T> + '_ {
95//         Ref::map(
96//             self.resources
97//                 .get(&std::any::TypeId::of::<T>())
98//                 .as_ref()
99//                 .expect("Resource not found")
100//                 .borrow(),
101//             |x| x.downcast_ref::<T>().unwrap(),
102//         )
103//     }
104//
105//     pub fn get_resource_mut<T: 'static>(&self) -> impl DerefMut<Target = T> + '_ {
106//         RefMut::map(
107//             self.resources
108//                 .get(&std::any::TypeId::of::<T>())
109//                 .as_ref()
110//                 .expect("Resource not found")
111//                 .borrow_mut(),
112//             |x| x.downcast_mut::<T>().unwrap(),
113//         )
114//     }
115// }
116//
117// struct OpenGlStuff {
118//     data: i32,
119// }
120// struct PathfindingGrid {
121//     more_data: Vec<Vec<u32>>,
122// }
123//
124// pub fn test() {
125//     let mut ctx = Context::default();
126//     ctx.register_resource(OpenGlStuff { data: 42 });
127//     ctx.register_resource(PathfindingGrid {
128//         more_data: vec![vec![1, 2, 3]],
129//     });
130// }
131//
132// pub fn system(ctx: &Context) {
133//     let opengl = ctx.get_resource::<OpenGlStuff>();
134//     let mut pathfinding = ctx.get_resource_mut::<PathfindingGrid>();
135//     println!("OpenGL stuff: {}", opengl.data);
136//     pathfinding.more_data.push(vec![1, 2, 3, 4]);
137// }