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::{AppWeakHandle, Handler, HandlerExt as _},
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(&self, handler: Handler<A>) -> EventHandle {
255 self.on_event_impl(handler, true)
256 }
257
258 pub fn on_event(&self, handler: Handler<A>) -> EventHandle {
299 self.on_event_impl(handler, false)
300 }
301
302 fn on_event_impl(&self, handler: Handler<A>, is_preview: bool) -> EventHandle {
303 let handler = handler.into_arc();
304 let (inner_handle_owner, inner_handle) = zng_handle::Handle::new(());
305 self.as_any().hook(move |update| {
306 if inner_handle_owner.is_dropped() {
307 return false;
308 }
309
310 let handle = inner_handle.downgrade();
311 update.push_once_action(
312 Box::new(clmv!(handler, |update| {
313 let args = update.args().as_any().downcast_ref::<A>().unwrap();
314 if !args.propagation().is_stopped() {
315 handler.app_event(handle.clone_boxed(), is_preview, args);
316 }
317 })),
318 is_preview,
319 );
320
321 true
322 })
323 }
324
325 pub fn receiver(&self) -> EventReceiver<A>
331 where
332 A: Send,
333 {
334 let (sender, receiver) = flume::unbounded();
335
336 self.as_any()
337 .hook(move |update| sender.send(update.args().as_any().downcast_ref::<A>().unwrap().clone()).is_ok())
338 .perm();
339
340 EventReceiver { receiver, event: *self }
341 }
342
343 pub fn sender(&self) -> EventSender<A>
347 where
348 A: Send,
349 {
350 EVENTS_SV.write().sender(*self)
351 }
352
353 pub fn has_hooks(&self) -> bool {
357 self.as_any().has_hooks()
358 }
359}
360impl<A: EventArgs> Clone for Event<A> {
361 fn clone(&self) -> Self {
362 *self
363 }
364}
365impl<A: EventArgs> Copy for Event<A> {}
366impl<A: EventArgs> PartialEq for Event<A> {
367 fn eq(&self, other: &Self) -> bool {
368 self.local == other.local
369 }
370}
371impl<A: EventArgs> Eq for Event<A> {}
372
373#[derive(Clone, Copy)]
375pub struct AnyEvent {
376 local: &'static AppLocal<EventData>,
377}
378impl fmt::Debug for AnyEvent {
379 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
380 if f.alternate() {
381 write!(f, "AnyEvent({})", self.name())
382 } else {
383 write!(f, "{}", self.name())
384 }
385 }
386}
387impl AnyEvent {
388 pub fn name(&self) -> &'static str {
390 self.local.read().name
391 }
392
393 pub fn is<A: EventArgs>(&self, event: &Event<A>) -> bool {
395 self == event
396 }
397
398 pub fn has(&self, update: &EventUpdate) -> bool {
400 *self == update.event
401 }
402
403 pub fn hook(&self, hook: impl Fn(&mut EventUpdate) -> bool + Send + Sync + 'static) -> EventHandle {
405 self.hook_impl(Box::new(hook))
406 }
407 fn hook_impl(&self, hook: Box<dyn Fn(&mut EventUpdate) -> bool + Send + Sync>) -> EventHandle {
408 let (handle, hook) = EventHandle::new(hook);
409 self.local.write().hooks.push(hook);
410 handle
411 }
412
413 pub fn subscribe(&self, widget_id: WidgetId) -> EventHandle {
418 self.local
419 .write()
420 .widget_subs
421 .entry(widget_id)
422 .or_insert_with(EventHandle::new_none)
423 .clone()
424 }
425
426 pub fn is_subscriber(&self, widget_id: WidgetId) -> bool {
428 self.local.read().widget_subs.contains_key(&widget_id)
429 }
430
431 pub fn has_subscribers(&self) -> bool {
433 !self.local.read().widget_subs.is_empty()
434 }
435
436 pub fn visit_subscribers<T>(&self, mut visit: impl FnMut(WidgetId) -> ControlFlow<T>) -> Option<T> {
441 for sub in self.local.read().widget_subs.keys() {
442 match visit(*sub) {
443 ControlFlow::Continue(_) => continue,
444 ControlFlow::Break(r) => return Some(r),
445 }
446 }
447 None
448 }
449
450 pub fn has_hooks(&self) -> bool {
454 !self.local.read().hooks.is_empty()
455 }
456
457 pub(crate) fn on_update(&self, update: &mut EventUpdate) {
458 let mut hooks = mem::take(&mut self.local.write().hooks);
459 hooks.retain(|h| h.call(update));
460
461 let mut write = self.local.write();
462 hooks.append(&mut write.hooks);
463 write.hooks = hooks;
464 }
465}
466impl PartialEq for AnyEvent {
467 fn eq(&self, other: &Self) -> bool {
468 self.local == other.local
469 }
470}
471impl Eq for AnyEvent {}
472impl std::hash::Hash for AnyEvent {
473 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
474 std::hash::Hash::hash(self.local, state)
475 }
476}
477impl<A: EventArgs> PartialEq<AnyEvent> for Event<A> {
478 fn eq(&self, other: &AnyEvent) -> bool {
479 self.local == other.local
480 }
481}
482impl<A: EventArgs> PartialEq<Event<A>> for AnyEvent {
483 fn eq(&self, other: &Event<A>) -> bool {
484 self.local == other.local
485 }
486}
487
488impl UpdateSubscribers for AnyEvent {
489 fn contains(&self, widget_id: WidgetId) -> bool {
490 if let Some(mut write) = self.local.try_write() {
491 match write.widget_subs.entry(widget_id) {
492 IdEntry::Occupied(e) => {
493 let t = e.get().retain();
494 if !t {
495 let _ = e.remove();
496 }
497 t
498 }
499 IdEntry::Vacant(_) => false,
500 }
501 } else {
502 match self.local.read().widget_subs.get(&widget_id) {
504 Some(e) => e.retain(),
505 None => false,
506 }
507 }
508 }
509
510 fn to_set(&self) -> IdSet<WidgetId> {
511 self.local.read().widget_subs.keys().copied().collect()
512 }
513}
514
515#[must_use = "the event subscriptions or handlers are dropped if the handle is dropped"]
517#[derive(Clone, Default)]
518pub struct EventHandles(Vec<EventHandle>);
519impl EventHandles {
520 pub const fn dummy() -> Self {
522 EventHandles(vec![])
523 }
524
525 pub fn is_dummy(&self) -> bool {
527 self.0.is_empty() || self.0.iter().all(EventHandle::is_dummy)
528 }
529
530 pub fn perm(self) {
532 for handle in self.0 {
533 handle.perm()
534 }
535 }
536
537 pub fn push(&mut self, other: EventHandle) -> &mut Self {
539 if !other.is_dummy() {
540 self.0.push(other);
541 }
542 self
543 }
544
545 pub fn clear(&mut self) {
547 self.0.clear();
548 }
549}
550impl FromIterator<EventHandle> for EventHandles {
551 fn from_iter<T: IntoIterator<Item = EventHandle>>(iter: T) -> Self {
552 EventHandles(iter.into_iter().filter(|h| !h.is_dummy()).collect())
553 }
554}
555impl<const N: usize> From<[EventHandle; N]> for EventHandles {
556 fn from(handles: [EventHandle; N]) -> Self {
557 handles.into_iter().filter(|h| !h.is_dummy()).collect()
558 }
559}
560impl Extend<EventHandle> for EventHandles {
561 fn extend<T: IntoIterator<Item = EventHandle>>(&mut self, iter: T) {
562 for handle in iter {
563 self.push(handle);
564 }
565 }
566}
567impl IntoIterator for EventHandles {
568 type Item = EventHandle;
569
570 type IntoIter = std::vec::IntoIter<EventHandle>;
571
572 fn into_iter(self) -> Self::IntoIter {
573 self.0.into_iter()
574 }
575}
576
577struct EventHandleData {
578 perm: AtomicBool,
579 hook: Option<Box<dyn Fn(&mut EventUpdate) -> bool + Send + Sync>>,
580}
581
582#[derive(Clone)]
584#[must_use = "the event subscription or handler is dropped if the handle is dropped"]
585pub struct EventHandle(Option<Arc<EventHandleData>>);
586impl PartialEq for EventHandle {
587 fn eq(&self, other: &Self) -> bool {
588 match (&self.0, &other.0) {
589 (None, None) => true,
590 (None, Some(_)) | (Some(_), None) => false,
591 (Some(a), Some(b)) => Arc::ptr_eq(a, b),
592 }
593 }
594}
595impl Eq for EventHandle {}
596impl std::hash::Hash for EventHandle {
597 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
598 let i = match &self.0 {
599 Some(rc) => Arc::as_ptr(rc) as usize,
600 None => 0,
601 };
602 state.write_usize(i);
603 }
604}
605impl fmt::Debug for EventHandle {
606 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
607 let i = match &self.0 {
608 Some(rc) => Arc::as_ptr(rc) as usize,
609 None => 0,
610 };
611 f.debug_tuple("EventHandle").field(&i).finish()
612 }
613}
614impl Default for EventHandle {
616 fn default() -> Self {
617 Self::dummy()
618 }
619}
620impl EventHandle {
621 fn new(hook: Box<dyn Fn(&mut EventUpdate) -> bool + Send + Sync>) -> (Self, EventHook) {
622 let rc = Arc::new(EventHandleData {
623 perm: AtomicBool::new(false),
624 hook: Some(hook),
625 });
626 (Self(Some(rc.clone())), EventHook(rc))
627 }
628
629 fn new_none() -> Self {
630 Self(Some(Arc::new(EventHandleData {
631 perm: AtomicBool::new(false),
632 hook: None,
633 })))
634 }
635
636 pub fn dummy() -> Self {
638 EventHandle(None)
639 }
640
641 pub fn is_dummy(&self) -> bool {
643 self.0.is_none()
644 }
645
646 pub fn perm(self) {
649 if let Some(rc) = self.0 {
650 rc.perm.store(true, Ordering::Relaxed);
651 }
652 }
653
654 pub fn with(self, other: Self) -> EventHandles {
656 [self, other].into()
657 }
658
659 fn retain(&self) -> bool {
660 let rc = self.0.as_ref().unwrap();
661 Arc::strong_count(rc) > 1 || rc.perm.load(Ordering::Relaxed)
662 }
663}
664
665struct EventHook(Arc<EventHandleData>);
666impl EventHook {
667 fn call(&self, update: &mut EventUpdate) -> bool {
669 (Arc::strong_count(&self.0) > 1 || self.0.perm.load(Ordering::Relaxed)) && (self.0.hook.as_ref().unwrap())(update)
670 }
671}