add multi-parenting

This commit is contained in:
Daniel Griffen 2018-10-28 19:43:48 -07:00
parent 5b7b4f1e12
commit 3c3e8754ad
No known key found for this signature in database
GPG Key ID: 315FB75FAC745B68
3 changed files with 43 additions and 39 deletions

View File

@ -49,29 +49,30 @@ macro_rules! register_hook {
macro_rules! post_event { macro_rules! post_event {
// TODO allow multiple $t:ty at once and re-#[doc(hidden)] the low-level get_post_targets and // TODO allow multiple $t:ty at once and re-#[doc(hidden)] the low-level get_post_targets and
// get_event_id // get_event_id
($b:expr, $t:ty, $e:expr) => { ($b:expr, $e:expr, $($t:ty),+) => {
{ {
// hygiene // hygiene
let bus: &$crate::EventBus = $b; let bus: &$crate::EventBus = $b;
// event setup, this may evaluate to any type. // event setup, this may evaluate to any type.
let event: &mut _ = $e; let event: &mut _ = $e;
{ {
// event type setup let _ = ($({
static EVENT_ID: ::std::sync::atomic::AtomicUsize = ::std::sync::atomic::ATOMIC_USIZE_INIT; // event type setup
static EVENT_ID_INIT: ::std::sync::Once = ::std::sync::ONCE_INIT; static EVENT_ID: ::std::sync::atomic::AtomicUsize = ::std::sync::atomic::ATOMIC_USIZE_INIT;
// no generics allowed. static EVENT_ID_INIT: ::std::sync::Once = ::std::sync::ONCE_INIT;
static DUMMY: ::std::marker::PhantomData<dyn Fn(&mut $t) + Send + Sync> = ::std::marker::PhantomData; // no generics allowed.
EVENT_ID_INIT.call_once(|| { static DUMMY: ::std::marker::PhantomData<dyn Fn(&mut $t) + Send + Sync> = ::std::marker::PhantomData;
EVENT_ID.store($crate::get_event_id::<$t>(), std::sync::atomic::Ordering::Relaxed); EVENT_ID_INIT.call_once(|| {
}); EVENT_ID.store($crate::get_event_id::<$t>(), std::sync::atomic::Ordering::Relaxed);
let id = EVENT_ID.load(std::sync::atomic::Ordering::Relaxed); });
let id = EVENT_ID.load(std::sync::atomic::Ordering::Relaxed);
let handlers = $crate::get_post_targets::<$t>(bus, event, id);
for (_pri, fun) in handlers.iter() {
fun(event);
}
},)+); // big tuple of (Handlers<type>, Handlers<type>, Handlers<type>, Handlers<type>, ...)
// handler retrieval and invokation
let event: &mut $t = event;
let handlers = $crate::get_post_targets::<$t>(bus, event, id);
for (_pri, fun) in handlers.iter() {
fun(event);
}
} }
} }
} }
@ -84,7 +85,7 @@ macro_rules! post_event {
macro_rules! post_event_cancellable { macro_rules! post_event_cancellable {
// TODO allow multiple $t:ty at once and re-#[doc(hidden)] the low-level get_post_targets and // TODO allow multiple $t:ty at once and re-#[doc(hidden)] the low-level get_post_targets and
// get_event_id // get_event_id
($b:expr, $t:ty, $e:expr) => { ($b:expr, $e:expr, $($t:ty),+) => {
{ {
// hygiene // hygiene
let bus: &$crate::EventBus = $b; let bus: &$crate::EventBus = $b;
@ -96,25 +97,28 @@ macro_rules! post_event_cancellable {
} }
test(event); test(event);
// event type setup let cancelled = ($({
static EVENT_ID: ::std::sync::atomic::AtomicUsize = ::std::sync::atomic::ATOMIC_USIZE_INIT; // event type setup
static EVENT_ID_INIT: ::std::sync::Once = ::std::sync::ONCE_INIT; static EVENT_ID: ::std::sync::atomic::AtomicUsize = ::std::sync::atomic::ATOMIC_USIZE_INIT;
// no generics allowed. static EVENT_ID_INIT: ::std::sync::Once = ::std::sync::ONCE_INIT;
static DUMMY: ::std::marker::PhantomData<dyn Fn(&mut $t) + Send + Sync> = ::std::marker::PhantomData; // no generics allowed.
EVENT_ID_INIT.call_once(|| { static DUMMY: ::std::marker::PhantomData<dyn Fn(&mut $t) + Send + Sync> = ::std::marker::PhantomData;
EVENT_ID.store($crate::get_event_id::<$t>(), std::sync::atomic::Ordering::Relaxed); EVENT_ID_INIT.call_once(|| {
}); EVENT_ID.store($crate::get_event_id::<$t>(), std::sync::atomic::Ordering::Relaxed);
let id = EVENT_ID.load(std::sync::atomic::Ordering::Relaxed); });
let id = EVENT_ID.load(std::sync::atomic::Ordering::Relaxed);
let handlers = $crate::get_post_targets::<$t>(bus, event, id);
// handler retrieval and invokation for (_pri, fun) in handlers.iter() {
let handlers = $crate::get_post_targets::<$t>(bus, event, id); fun(event as &mut $t);
for (_pri, fun) in handlers.iter() { if Cancellable::cancelled(event) {
fun(event as &mut $t); break;
if event.cancelled() { }
break;
} }
}
event.cancelled() event.cancelled()
},)+); // big tuple of (Handlers<type>, Handlers<type>, Handlers<type>, Handlers<type>, ...)
} }
} }
} }

View File

@ -27,12 +27,12 @@ fn test_basic_usage() {
register_hook!(&event_bus, 0, MyEvent, add_handler); register_hook!(&event_bus, 0, MyEvent, add_handler);
let mut event = MyEvent { i: 3 }; let mut event = MyEvent { i: 3 };
assert_eq!(event.i, 3); assert_eq!(event.i, 3);
post_event!(&event_bus, MyEvent, &mut event); post_event!(&event_bus, &mut event, MyEvent);
assert_eq!(event.i, 4); assert_eq!(event.i, 4);
register_hook!(&event_bus, 1, MyEvent, no_handler); register_hook!(&event_bus, 1, MyEvent, no_handler);
post_event!(&event_bus, MyEvent, &mut event); post_event!(&event_bus, &mut event, MyEvent);
assert_eq!(event.i, 5); assert_eq!(event.i, 5);
//event_bus.unregister(handler_id); //event_bus.unregister(handler_id);
post_event!(&event_bus, MyEvent, &mut event); post_event!(&event_bus, &mut event, MyEvent);
//assert_eq!(event.i, 5); //assert_eq!(event.i, 5);
} }

View File

@ -55,6 +55,6 @@ fn test_dyn_usage() {
//let handler_id = event_bus.register(add_handler, 0); //let handler_id = event_bus.register(add_handler, 0);
register_hook!(&event_bus, 0, dyn MyEvent, on_myevent); register_hook!(&event_bus, 0, dyn MyEvent, on_myevent);
register_hook!(&event_bus, 1, dyn MyExtraEvent, on_myextraevent); register_hook!(&event_bus, 1, dyn MyExtraEvent, on_myextraevent);
post_event!(&event_bus, dyn MyEvent, &mut event); post_event!(&event_bus, &mut event, dyn MyEvent);
post_event_cancellable!(&event_bus, dyn MyExtraEvent, &mut extraEvent); post_event_cancellable!(&event_bus, &mut extraEvent, dyn MyExtraEvent, dyn MyEvent);
} }