1use std::marker::PhantomData;
2use std::any::{TypeId, Any};
3use std::fmt::Debug;
4use std::collections::BTreeMap;
5use std::cmp::Ordering;
6use std::sync::Arc;
7use std::mem;
8use std::ptr;
9use std::raw::TraitObject;
10
11use minidom::Element;
12
13/// A marker trait which marks all events.
14pub trait Event: Any + Debug {}
15
16/// A trait which can be implemented when something can handle a specific kind of event.
17pub trait EventHandler<E: Event>: Any {
18 /// Handle an event, returns whether to propagate the event to the remaining handlers.
19 fn handle(&self, event: &E) -> Propagation;
20}
21
22struct Record<P, T>(P, T);
23
24impl<P: PartialEq, T> PartialEq for Record<P, T> {
25 fn eq(&self, other: &Record<P, T>) -> bool {
26 self.0 == other.0
27 }
28}
29
30impl<P: Eq, T> Eq for Record<P, T> {}
31
32impl<P: PartialOrd, T> PartialOrd for Record<P, T> {
33 fn partial_cmp(&self, other: &Record<P, T>) -> Option<Ordering> {
34 self.0.partial_cmp(&other.0)
35 }
36}
37
38impl<P: Ord, T> Ord for Record<P, T> {
39 fn cmp(&self, other: &Record<P, T>) -> Ordering {
40 self.0.cmp(&other.0)
41 }
42}
43
44/// An enum representing whether to keep propagating an event or to stop the propagation.
45pub enum Propagation {
46 /// Stop the propagation of the event, the remaining handlers will not get invoked.
47 Stop,
48 /// Continue propagating the event.
49 Continue,
50}
51
52#[derive(Debug)]
53struct GarbageEvent;
54
55impl Event for GarbageEvent {}
56
57impl<E, F> EventHandler<E> for Box<F> where E: Event, F: 'static + Fn(&E) -> Propagation {
58 fn handle(&self, evt: &E) -> Propagation {
59 self(evt)
60 }
61}
62
63/// An event dispatcher, this takes care of dispatching events to their respective handlers.
64pub struct Dispatcher {
65 handlers: BTreeMap<TypeId, Vec<Record<Priority, Box<Any>>>>,
66 queue: Vec<(TypeId, Box<Any>)>,
67}
68
69impl Dispatcher {
70 /// Create a new `Dispatcher`.
71 pub fn new() -> Dispatcher {
72 Dispatcher {
73 handlers: BTreeMap::new(),
74 queue: Vec::new(),
75 }
76 }
77
78 /// Register an event handler.
79 pub fn register<E, H>(&mut self, priority: Priority, handler: H) where E: Event + 'static, H: EventHandler<E> {
80 let handler: Box<EventHandler<E>> = Box::new(handler) as Box<EventHandler<E>>;
81 let ent = self.handlers.entry(TypeId::of::<E>())
82 .or_insert_with(|| Vec::new());
83 ent.push(Record(priority, Box::new(handler) as Box<Any>));
84 ent.sort();
85 }
86
87 /// Append an event to the queue.
88 pub fn dispatch<E>(&mut self, event: E) where E: Event {
89 self.queue.push((TypeId::of::<E>(), Box::new(event) as Box<Any>));
90 }
91
92 /// Flush all events in the queue so they can be handled by their respective handlers.
93 /// Returns whether there are still pending events.
94 pub fn flush(&mut self) -> bool {
95 let mut q = Vec::new();
96 mem::swap(&mut self.queue, &mut q);
97 'evts: for (t, evt) in q {
98 if let Some(handlers) = self.handlers.get_mut(&t) {
99 for &mut Record(_, ref mut handler) in handlers {
100 // GarbageEvent is a garbage type.
101 // The actual passed type is NEVER of this type.
102 let h: &mut EventHandler<GarbageEvent> = unsafe {
103 let handler_obj: &mut TraitObject = mem::transmute(handler);
104 let handler_inner: *mut TraitObject = mem::transmute(handler_obj.data);
105 mem::transmute(*handler_inner)
106 };
107 let e: &&GarbageEvent = unsafe {
108 let evt_ref: &Any = &evt;
109 let evt_obj: TraitObject = mem::transmute(evt_ref);
110 mem::transmute(evt_obj.data)
111 };
112 match h.handle(e) {
113 Propagation::Stop => { continue 'evts; },
114 Propagation::Continue => (),
115 }
116 }
117 }
118 }
119 !self.queue.is_empty()
120 }
121
122 /// Flushes all events, like `flush`, but keeps doing this until there is nothing left in the
123 /// queue.
124 pub fn flush_all(&mut self) {
125 while self.flush() {}
126 }
127
128 /// Dispatch an event to the handlers right now, without going through the queue.
129 pub fn dispatch_now<E>(&mut self, event: E) where E: Event {
130 if let Some(handlers) = self.handlers.get_mut(&TypeId::of::<E>()) {
131 for &mut Record(_, ref mut handler) in handlers {
132 let h = handler.downcast_mut::<Box<EventHandler<E>>>().unwrap();
133 match h.handle(&event) {
134 Propagation::Stop => { return; },
135 Propagation::Continue => (),
136 }
137 }
138 }
139 }
140}
141
142pub struct EventProxy<T: ?Sized, E: Event> {
143 inner: Arc<Box<T>>,
144 vtable: *mut (),
145 _event_type: PhantomData<E>,
146}
147
148impl<T: ?Sized, E: Event> EventProxy<T, E> {
149 /// Unsafe because T is assumed to be a TraitObject or at least have its shape.
150 /// If it is not, things will break. In a fascinatingly horrible manner.
151 /// Some people, such as myself, find it hilarious. Most people do not.
152 /// T is also assumed to actually support EventHandler<E>, if it does not, refer to above
153 /// statement.
154 pub unsafe fn new<H: EventHandler<E>>(inner: Arc<Box<T>>) -> EventProxy<T, E> {
155 let box_with_vtable = &*ptr::null::<H>() as &EventHandler<E>;
156 let obj: TraitObject = mem::transmute(box_with_vtable);
157 EventProxy {
158 inner: inner,
159 vtable: obj.vtable,
160 _event_type: PhantomData,
161 }
162 }
163}
164
165impl<T: ?Sized, E: Event> EventHandler<E> for EventProxy<T, E> where Box<T>: 'static {
166 fn handle(&self, evt: &E) -> Propagation {
167 let inner = Arc::into_raw(self.inner.clone());
168 let obj = TraitObject { data: unsafe { mem::transmute(inner) }, vtable: self.vtable };
169 let handler: &EventHandler<E> = unsafe { mem::transmute(obj) };
170 let prop = handler.handle(evt);
171 unsafe { Arc::<Box<T>>::from_raw(mem::transmute(inner)); }
172 prop
173 }
174}
175
176#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
177pub enum Priority {
178 Max,
179 Default,
180 Min,
181}
182
183impl Default for Priority {
184 fn default() -> Priority {
185 Priority::Default
186 }
187}
188
189#[derive(Debug)]
190pub struct SendElement(pub Element);
191
192impl Event for SendElement {}
193
194#[derive(Debug)]
195pub struct ReceiveElement(pub Element);
196
197impl Event for ReceiveElement {}
198
199#[cfg(test)]
200mod tests {
201 use super::*;
202
203 #[test]
204 #[should_panic(expected = "success")]
205 fn test() {
206 let mut disp = Dispatcher::new();
207
208 struct MyHandler;
209 struct EvilHandler;
210 struct EventFilter;
211
212 #[derive(Debug)]
213 struct MyEvent {
214 should_be_42: u32,
215 }
216
217 impl Event for MyEvent {}
218
219 impl EventHandler<MyEvent> for MyHandler {
220 fn handle(&self, evt: &MyEvent) -> Propagation {
221 if evt.should_be_42 == 42 {
222 panic!("success");
223 }
224 else {
225 panic!("not 42");
226 }
227 }
228 }
229
230 impl EventHandler<MyEvent> for EvilHandler {
231 fn handle(&self, _: &MyEvent) -> Propagation {
232 panic!("should not be called");
233 }
234 }
235
236 impl EventHandler<MyEvent> for EventFilter {
237 fn handle(&self, evt: &MyEvent) -> Propagation {
238 if evt.should_be_42 == 42 {
239 Propagation::Continue
240 }
241 else {
242 Propagation::Stop
243 }
244 }
245 }
246
247 disp.register(Priority::Max, EventFilter);
248 disp.register(Priority::Min, EvilHandler);
249 disp.register(Priority::Default, MyHandler);
250 disp.register(Priority::Min, EvilHandler);
251
252 disp.dispatch(MyEvent {
253 should_be_42: 39,
254 });
255
256 disp.dispatch(MyEvent {
257 should_be_42: 42,
258 });
259
260 disp.flush();
261 }
262}