1use std::{
4 any::Any,
5 fmt,
6 marker::PhantomData,
7 mem,
8 ops::{ControlFlow, Deref},
9 sync::{
10 Arc,
11 atomic::{AtomicBool, Ordering},
12 },
13 time::Instant,
14};
15
16mod args;
17pub use args::*;
18
19mod command;
20pub use command::*;
21
22mod events;
23pub use events::*;
24
25mod channel;
26pub use channel::*;
27
28use crate::{
29 handler::{AppHandler, AppHandlerArgs},
30 update::{EventUpdate, UpdateDeliveryList, UpdateSubscribers},
31 widget::WidgetId,
32};
33use parking_lot::Mutex;
34use zng_app_context::AppLocal;
35use zng_clone_move::clmv;
36use zng_unique_id::{IdEntry, IdMap, IdSet};
37
38#[macro_export]
69macro_rules! event_macro {
70 ($(
71 $(#[$attr:meta])*
72 $vis:vis static $EVENT:ident: $Args:path;
73 )+) => {
74 $(
75 $(#[$attr])*
76 $vis static $EVENT: $crate::event::Event<$Args> = {
77 $crate::event::app_local! {
78 static LOCAL: $crate::event::EventData = const { $crate::event::EventData::new(std::stringify!($EVENT)) };
79 }
80 $crate::event::Event::new(&LOCAL)
81 };
82 )+
83 }
84}
85#[doc(inline)]
86pub use crate::event_macro as event;
87
88#[doc(hidden)]
89pub struct EventData {
90 name: &'static str,
91 widget_subs: IdMap<WidgetId, EventHandle>,
92 hooks: Vec<EventHook>,
93}
94impl EventData {
95 #[doc(hidden)]
96 pub const fn new(name: &'static str) -> Self {
97 EventData {
98 name,
99 widget_subs: IdMap::new(),
100 hooks: vec![],
101 }
102 }
103}
104
105pub struct Event<A: EventArgs> {
109 local: &'static AppLocal<EventData>,
110 _args: PhantomData<fn(A)>,
111}
112impl<A: EventArgs> fmt::Debug for Event<A> {
113 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
114 if f.alternate() {
115 write!(f, "Event({})", self.name())
116 } else {
117 write!(f, "{}", self.name())
118 }
119 }
120}
121impl<A: EventArgs> Event<A> {
122 #[doc(hidden)]
123 pub const fn new(local: &'static AppLocal<EventData>) -> Self {
124 Event { local, _args: PhantomData }
125 }
126
127 pub fn as_any(&self) -> AnyEvent {
129 AnyEvent { local: self.local }
130 }
131
132 pub fn subscribe(&self, widget_id: WidgetId) -> EventHandle {
137 self.as_any().subscribe(widget_id)
138 }
139
140 pub fn is_subscriber(&self, widget_id: WidgetId) -> bool {
142 self.as_any().is_subscriber(widget_id)
143 }
144
145 pub fn has_subscribers(&self) -> bool {
147 self.as_any().has_subscribers()
148 }
149
150 pub fn visit_subscribers<T>(&self, visit: impl FnMut(WidgetId) -> ControlFlow<T>) -> Option<T> {
155 self.as_any().visit_subscribers(visit)
156 }
157
158 pub fn name(&self) -> &'static str {
160 self.local.read().name
161 }
162
163 pub fn has(&self, update: &EventUpdate) -> bool {
165 *self == update.event
166 }
167
168 pub fn on<'a>(&self, update: &'a EventUpdate) -> Option<&'a A> {
170 if *self == update.event {
171 update.args.as_any().downcast_ref()
172 } else {
173 None
174 }
175 }
176
177 pub fn on_unhandled<'a>(&self, update: &'a EventUpdate) -> Option<&'a A> {
179 self.on(update).filter(|a| !a.propagation().is_stopped())
180 }
181
182 pub fn handle<R>(&self, update: &EventUpdate, handler: impl FnOnce(&A) -> R) -> Option<R> {
184 if let Some(args) = self.on(update) {
185 args.handle(handler)
186 } else {
187 None
188 }
189 }
190
191 pub fn new_update(&self, args: A) -> EventUpdate {
193 self.new_update_custom(args, UpdateDeliveryList::new(Box::new(self.as_any())))
194 }
195
196 pub fn new_update_custom(&self, args: A, mut delivery_list: UpdateDeliveryList) -> EventUpdate {
198 args.delivery_list(&mut delivery_list);
199 EventUpdate {
200 event: self.as_any(),
201 delivery_list,
202 args: Box::new(args),
203 pre_actions: Mutex::new(vec![]),
204 pos_actions: Mutex::new(vec![]),
205 }
206 }
207
208 pub fn notify(&self, args: A) {
210 let update = self.new_update(args);
211 EVENTS.notify(update);
212 }
213
214 pub fn on_pre_event<H>(&self, handler: H) -> EventHandle
255 where
256 H: AppHandler<A>,
257 {
258 self.on_event_impl(handler, true)
259 }
260
261 pub fn on_event(&self, handler: impl AppHandler<A>) -> EventHandle {
302 self.on_event_impl(handler, false)
303 }
304
305 fn on_event_impl(&self, handler: impl AppHandler<A>, is_preview: bool) -> EventHandle {
306 let handler = Arc::new(Mutex::new(handler));
307 let (inner_handle_owner, inner_handle) = zng_handle::Handle::new(());
308 self.as_any().hook(move |update| {
309 if inner_handle_owner.is_dropped() {
310 return false;
311 }
312
313 let handle = inner_handle.downgrade();
314 update.push_once_action(
315 Box::new(clmv!(handler, |update| {
316 let args = update.args().as_any().downcast_ref::<A>().unwrap();
317 if !args.propagation().is_stopped() {
318 handler.lock().event(
319 args,
320 &AppHandlerArgs {
321 handle: &handle,
322 is_preview,
323 },
324 );
325 }
326 })),
327 is_preview,
328 );
329
330 true
331 })
332 }
333
334 pub fn receiver(&self) -> EventReceiver<A>
340 where
341 A: Send,
342 {
343 let (sender, receiver) = flume::unbounded();
344
345 self.as_any()
346 .hook(move |update| sender.send(update.args().as_any().downcast_ref::<A>().unwrap().clone()).is_ok())
347 .perm();
348
349 EventReceiver { receiver, event: *self }
350 }
351
352 pub fn sender(&self) -> EventSender<A>
356 where
357 A: Send,
358 {
359 EVENTS_SV.write().sender(*self)
360 }
361
362 pub fn has_hooks(&self) -> bool {
366 self.as_any().has_hooks()
367 }
368}
369impl<A: EventArgs> Clone for Event<A> {
370 fn clone(&self) -> Self {
371 *self
372 }
373}
374impl<A: EventArgs> Copy for Event<A> {}
375impl<A: EventArgs> PartialEq for Event<A> {
376 fn eq(&self, other: &Self) -> bool {
377 self.local == other.local
378 }
379}
380impl<A: EventArgs> Eq for Event<A> {}
381
382#[derive(Clone, Copy)]
384pub struct AnyEvent {
385 local: &'static AppLocal<EventData>,
386}
387impl fmt::Debug for AnyEvent {
388 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
389 if f.alternate() {
390 write!(f, "AnyEvent({})", self.name())
391 } else {
392 write!(f, "{}", self.name())
393 }
394 }
395}
396impl AnyEvent {
397 pub fn name(&self) -> &'static str {
399 self.local.read().name
400 }
401
402 pub fn is<A: EventArgs>(&self, event: &Event<A>) -> bool {
404 self == event
405 }
406
407 pub fn has(&self, update: &EventUpdate) -> bool {
409 *self == update.event
410 }
411
412 pub fn hook(&self, hook: impl Fn(&mut EventUpdate) -> bool + Send + Sync + 'static) -> EventHandle {
414 self.hook_impl(Box::new(hook))
415 }
416 fn hook_impl(&self, hook: Box<dyn Fn(&mut EventUpdate) -> bool + Send + Sync>) -> EventHandle {
417 let (handle, hook) = EventHandle::new(hook);
418 self.local.write().hooks.push(hook);
419 handle
420 }
421
422 pub fn subscribe(&self, widget_id: WidgetId) -> EventHandle {
427 self.local
428 .write()
429 .widget_subs
430 .entry(widget_id)
431 .or_insert_with(EventHandle::new_none)
432 .clone()
433 }
434
435 pub fn is_subscriber(&self, widget_id: WidgetId) -> bool {
437 self.local.read().widget_subs.contains_key(&widget_id)
438 }
439
440 pub fn has_subscribers(&self) -> bool {
442 !self.local.read().widget_subs.is_empty()
443 }
444
445 pub fn visit_subscribers<T>(&self, mut visit: impl FnMut(WidgetId) -> ControlFlow<T>) -> Option<T> {
450 for sub in self.local.read().widget_subs.keys() {
451 match visit(*sub) {
452 ControlFlow::Continue(_) => continue,
453 ControlFlow::Break(r) => return Some(r),
454 }
455 }
456 None
457 }
458
459 pub fn has_hooks(&self) -> bool {
463 !self.local.read().hooks.is_empty()
464 }
465
466 pub(crate) fn on_update(&self, update: &mut EventUpdate) {
467 let mut hooks = mem::take(&mut self.local.write().hooks);
468 hooks.retain(|h| h.call(update));
469
470 let mut write = self.local.write();
471 hooks.append(&mut write.hooks);
472 write.hooks = hooks;
473 }
474}
475impl PartialEq for AnyEvent {
476 fn eq(&self, other: &Self) -> bool {
477 self.local == other.local
478 }
479}
480impl Eq for AnyEvent {}
481impl std::hash::Hash for AnyEvent {
482 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
483 std::hash::Hash::hash(self.local, state)
484 }
485}
486impl<A: EventArgs> PartialEq<AnyEvent> for Event<A> {
487 fn eq(&self, other: &AnyEvent) -> bool {
488 self.local == other.local
489 }
490}
491impl<A: EventArgs> PartialEq<Event<A>> for AnyEvent {
492 fn eq(&self, other: &Event<A>) -> bool {
493 self.local == other.local
494 }
495}
496
497impl UpdateSubscribers for AnyEvent {
498 fn contains(&self, widget_id: WidgetId) -> bool {
499 if let Some(mut write) = self.local.try_write() {
500 match write.widget_subs.entry(widget_id) {
501 IdEntry::Occupied(e) => {
502 let t = e.get().retain();
503 if !t {
504 let _ = e.remove();
505 }
506 t
507 }
508 IdEntry::Vacant(_) => false,
509 }
510 } else {
511 match self.local.read().widget_subs.get(&widget_id) {
513 Some(e) => e.retain(),
514 None => false,
515 }
516 }
517 }
518
519 fn to_set(&self) -> IdSet<WidgetId> {
520 self.local.read().widget_subs.keys().copied().collect()
521 }
522}
523
524#[must_use = "the event subscriptions or handlers are dropped if the handle is dropped"]
526#[derive(Clone, Default)]
527pub struct EventHandles(pub Vec<EventHandle>);
528impl EventHandles {
529 pub const fn dummy() -> Self {
531 EventHandles(vec![])
532 }
533
534 pub fn is_dummy(&self) -> bool {
536 self.0.is_empty() || self.0.iter().all(EventHandle::is_dummy)
537 }
538
539 pub fn perm(self) {
541 for handle in self.0 {
542 handle.perm()
543 }
544 }
545
546 pub fn push(&mut self, other: EventHandle) -> &mut Self {
548 if !other.is_dummy() {
549 self.0.push(other);
550 }
551 self
552 }
553
554 pub fn clear(&mut self) {
556 self.0.clear();
557 }
558}
559impl FromIterator<EventHandle> for EventHandles {
560 fn from_iter<T: IntoIterator<Item = EventHandle>>(iter: T) -> Self {
561 EventHandles(iter.into_iter().filter(|h| !h.is_dummy()).collect())
562 }
563}
564impl<const N: usize> From<[EventHandle; N]> for EventHandles {
565 fn from(handles: [EventHandle; N]) -> Self {
566 handles.into_iter().filter(|h| !h.is_dummy()).collect()
567 }
568}
569impl Extend<EventHandle> for EventHandles {
570 fn extend<T: IntoIterator<Item = EventHandle>>(&mut self, iter: T) {
571 for handle in iter {
572 self.push(handle);
573 }
574 }
575}
576impl IntoIterator for EventHandles {
577 type Item = EventHandle;
578
579 type IntoIter = std::vec::IntoIter<EventHandle>;
580
581 fn into_iter(self) -> Self::IntoIter {
582 self.0.into_iter()
583 }
584}
585
586struct EventHandleData {
587 perm: AtomicBool,
588 hook: Option<Box<dyn Fn(&mut EventUpdate) -> bool + Send + Sync>>,
589}
590
591#[derive(Clone)]
593#[must_use = "the event subscription or handler is dropped if the handle is dropped"]
594pub struct EventHandle(Option<Arc<EventHandleData>>);
595impl PartialEq for EventHandle {
596 fn eq(&self, other: &Self) -> bool {
597 match (&self.0, &other.0) {
598 (None, None) => true,
599 (None, Some(_)) | (Some(_), None) => false,
600 (Some(a), Some(b)) => Arc::ptr_eq(a, b),
601 }
602 }
603}
604impl Eq for EventHandle {}
605impl std::hash::Hash for EventHandle {
606 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
607 let i = match &self.0 {
608 Some(rc) => Arc::as_ptr(rc) as usize,
609 None => 0,
610 };
611 state.write_usize(i);
612 }
613}
614impl fmt::Debug for EventHandle {
615 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
616 let i = match &self.0 {
617 Some(rc) => Arc::as_ptr(rc) as usize,
618 None => 0,
619 };
620 f.debug_tuple("EventHandle").field(&i).finish()
621 }
622}
623impl Default for EventHandle {
625 fn default() -> Self {
626 Self::dummy()
627 }
628}
629impl EventHandle {
630 fn new(hook: Box<dyn Fn(&mut EventUpdate) -> bool + Send + Sync>) -> (Self, EventHook) {
631 let rc = Arc::new(EventHandleData {
632 perm: AtomicBool::new(false),
633 hook: Some(hook),
634 });
635 (Self(Some(rc.clone())), EventHook(rc))
636 }
637
638 fn new_none() -> Self {
639 Self(Some(Arc::new(EventHandleData {
640 perm: AtomicBool::new(false),
641 hook: None,
642 })))
643 }
644
645 pub fn dummy() -> Self {
647 EventHandle(None)
648 }
649
650 pub fn is_dummy(&self) -> bool {
652 self.0.is_none()
653 }
654
655 pub fn perm(self) {
658 if let Some(rc) = self.0 {
659 rc.perm.store(true, Ordering::Relaxed);
660 }
661 }
662
663 pub fn with(self, other: Self) -> EventHandles {
665 [self, other].into()
666 }
667
668 fn retain(&self) -> bool {
669 let rc = self.0.as_ref().unwrap();
670 Arc::strong_count(rc) > 1 || rc.perm.load(Ordering::Relaxed)
671 }
672}
673
674struct EventHook(Arc<EventHandleData>);
675impl EventHook {
676 fn call(&self, update: &mut EventUpdate) -> bool {
678 (Arc::strong_count(&self.0) > 1 || self.0.perm.load(Ordering::Relaxed)) && (self.0.hook.as_ref().unwrap())(update)
679 }
680}