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