Skip to content

Instantly share code, notes, and snippets.

@reem
Created September 11, 2014 22:02
Show Gist options
  • Save reem/41eb72ceff05f63ae017 to your computer and use it in GitHub Desktop.
Save reem/41eb72ceff05f63ae017 to your computer and use it in GitHub Desktop.
#![license = "MIT"]
//#![deny(missing_doc)]
#![deny(warnings)]
//! Crate comment goes here
extern crate typemap;
local_data_key!(LocalEventQueue, Arc<EventQueue>)
macro_rules! queue(
() => {{
LocalEventQueue.get().expect("an Event Queue to be in TLS")
}}
)
pub struct Event<T> {
data: T
}
impl<T> Event<T> {
pub fn new(val: T) -> Event<T> {
Event { data: val }
}
pub fn trigger<K: Assoc<T>>(self) -> IoResult<()> {
(queue!()).trigger(self)
}
}
pub fn on<K: Assoc<X>, H: Handler<X>, X>(handler: H) -> IoResult<()> {
(queue!()).on::<K, H, X>(handler)
}
pub type Handler<X> = Box<Fn<(X,), ()>>;
enum EventKey<K: Assoc<X>, X> {}
impl<K: Assoc<X>, X> Assoc<Handler<X>> for EventKey<K, X> {}
pub struct EventQueue {
events: Mutex<TypeMap>
}
impl EventQueue {
pub fn new() -> Arc<EventQueue> {
let this = Arc::new(EventQueue { events: Mutex::new(TypeMap::new()) });
LocalEventQueue.replace(Some(this.clone()));
this
}
fn trigger<K: Assoc<X>, X>(event: Event<X>) {
// FIXME (make asynchronous):
// Instead of firing this off immediately, this has to put it in a *queue*,
// which is then fired via epoll.
self.events.lock().find::<EventKey<K, X>, Handler<X>>().recv(event)
}
fn on<K: Assox<X>, X>(handler: Handler<X>) {
self.events.lock().insert::<EventKey<K, X>, Handler<X>>(handler)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment