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
#![allow(dead_code)] use std::collections::BTreeMap; /// Enumerator of the Event type. Whatever type E of Event::Args you implement here is the type E that will be used for the EventPublisher. pub enum Event<E> { Args(E), Missing, } // To deal with handler functions - F: Rc<Box<Fn(&event<E>)>> /// EventPublisher. Works similarly to C#'s event publishing pattern. Event handling functions are subscribed to the publisher. /// Whenever the publisher fires an event it calls all subscribed event handler functions. /// Use event::EventPublisher::<E>::new() to construct pub struct EventPublisher<E> { //handlers: Vec<Rc<Box<Fn(&Event<E>) + 'static>>>, handlers: BTreeMap<usize, fn(&Event<E>)>, } impl<E> EventPublisher<E> { /// Event publisher constructor. pub fn new() -> EventPublisher<E> { EventPublisher{ handlers: BTreeMap::<usize, fn(&Event<E>)>::new() } } /// Subscribes event handler functions to the EventPublisher. /// INPUT: handler: fn(&Event<E>) handler is a pointer to a function to handle an event of the type E. The function must /// be capable of handling references to the event type set up by the publisher, rather than the raw event itself. /// OUTPUT: void pub fn subscribe_handler(&mut self, handler: fn(&Event<E>)){ let p_handler: usize; unsafe{ p_handler = *(handler as *const usize); } self.handlers.insert(p_handler, handler); } /// Unsubscribes an event handler from the publisher. /// INPUT: handler: fn(&Event<E>) handler is a pointer to a function to handle an event of the type E. /// OUTPUT: bool output is a bool of whether or not the function was found in the list of subscribed event handlers and subsequently removed. pub fn unsubscribe_handler(&mut self, handler: fn(&Event<E>)) -> bool { let p_handler: usize; unsafe{ p_handler = *(handler as *const usize); } match self.handlers.remove(&p_handler){ Some(_) => true, None => false, } } // TODO: Implement this concurrently /// Publishes events, pushing the &Event<E> to all handler functions stored by the event publisher. /// INPUT: event: &Event<E> Reference to the Event<E> being pushed to all handling functions. pub fn publish_event(&self, event: &Event<E>){ for (_, handler) in self.handlers.iter(){ handler(event); } } }