Skip to main content

ferroui_system/events/
event.rs

1use super::{HandlerList, HandlerSnapshot};
2use std::rc::Rc;
3
4/// A multicast event of a model object: the equivalent of a managed `event`
5/// member on a type that is not part of the class hierarchy.
6///
7/// Handlers are identified by the token returned from [`add`](Self::add).
8/// Raising works on a snapshot, so handlers may add or remove handlers.
9pub struct Event<A: ?Sized> {
10    handlers: HandlerList<dyn Fn(&A)>,
11}
12
13impl<A: ?Sized> Default for Event<A> {
14    fn default() -> Self {
15        Self::new()
16    }
17}
18
19impl<A: ?Sized> Event<A> {
20    pub fn new() -> Self {
21        Self { handlers: HandlerList::new() }
22    }
23
24    /// An event whose handler tokens come from `ids`, a counter shared with
25    /// other handler lists (see [`HandlerList::with_shared_ids`]).
26    pub fn with_shared_ids(ids: std::rc::Rc<std::cell::Cell<u64>>) -> Self {
27        Self { handlers: HandlerList::with_shared_ids(ids) }
28    }
29
30    /// An event whose handler tokens come from the counter of the process
31    /// (see [`HandlerList::with_ordered_ids`]).
32    pub fn with_ordered_ids() -> Self {
33        Self { handlers: HandlerList::with_ordered_ids() }
34    }
35
36    /// The current handlers with their tokens; later changes do not affect
37    /// it.
38    pub fn snapshot(&self) -> HandlerSnapshot<dyn Fn(&A)> {
39        self.handlers.snapshot()
40    }
41
42    /// Adds a handler; returns the token that removes it.
43    pub fn add(&self, handler: Rc<dyn Fn(&A)>) -> u64 {
44        self.handlers.add(handler)
45    }
46
47    /// Removes a handler. Returns false if the token is unknown.
48    pub fn remove(&self, token: u64) -> bool {
49        self.handlers.remove(token)
50    }
51
52    /// Whether any handler is subscribed.
53    pub fn has_handlers(&self) -> bool {
54        !self.handlers.is_empty()
55    }
56
57    /// The number of subscribed handlers.
58    pub fn handler_count(&self) -> usize {
59        self.handlers.len()
60    }
61
62    /// Invokes the handlers.
63    pub fn raise(&self, args: &A) {
64        if self.handlers.is_empty() {
65            return;
66        }
67        for (_, handler) in self.handlers.snapshot().iter() {
68            handler(args);
69        }
70    }
71}