event.rs

  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}