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 63 64 65 66 67 68 69
macro_rules! handler { ( $context:path, $(#[doc = $doc:literal])+ $name:ident, $(#[doc = $doc_if:literal])+ $name_if:ident, ) => { $(#[doc = $doc])+ pub fn $name<H, F>(&mut self, handler: H) where H: (Fn(std::sync::Arc<$context>) -> F) + Send + Sync + 'static, F: std::future::Future<Output = ()> + Send + 'static, { let set: fn(&mut Self, H) = paste::expr!(|event_loop, handler| { event_loop.[<$name _handlers>].push(Box::new(move |context| { tokio::spawn(handler(context)); })) }); set(self, handler) } $(#[doc = $doc_if])+ pub fn $name_if<H, HF, P, PF>( &mut self, predicate: P, handler: H, ) where H: (Fn(Arc<$context>) -> HF) + Send + Sync + 'static, HF: Future<Output = ()> + Send + 'static, P: (Fn(Arc<$context>) -> PF) + Send + Sync + 'static, PF: Future<Output = bool> + Send + 'static, { let predicate = Arc::new(predicate); let handler = Arc::new(handler); self.$name(move |context| { let predicate = Arc::clone(&predicate); let handler = Arc::clone(&handler); async move { if predicate(Arc::clone(&context)).await { handler(context).await } } }); } paste::item! { #[allow(dead_code)] fn [<will_handle_ $name>](&self) -> bool { !self.[<$name _handlers>].is_empty() } } paste::item! { fn [<run_ $name _handlers>](&self, context: std::sync::Arc<$context>) { &self.[<$name _handlers>].iter().for_each(|handler| { handler(context.clone()); }); } } }; }