oxide_mvu/
emitter.rs

1//! Event emitter for embedding callbacks in Props.
2
3use flume::Sender;
4
5/// Event emitter that can be embedded in Props.
6///
7/// Clone this handle to create callbacks in your Props that can trigger
8/// events when invoked (e.g., by user interaction).
9///
10/// `Emitter` wraps a lock-free channel sender, making it cheap to clone
11/// and thread-safe without any locking overhead.
12///
13/// # Example
14///
15/// ```rust
16/// use oxide_mvu::{Emitter, MvuLogic, Effect};
17///
18/// enum Event { Click }
19///
20/// #[derive(Clone)]
21/// struct Model { clicks: u32 }
22///
23/// struct Props {
24///     clicks: u32,
25///     on_click: Box<dyn Fn()>,
26/// }
27///
28/// struct MyApp;
29///
30/// impl MvuLogic<Event, Model, Props> for MyApp {
31///     fn init(&self, model: Model) -> (Model, Effect<Event>) {
32///         (model, Effect::none())
33///     }
34///
35///     fn update(&self, event: Event, model: &Model) -> (Model, Effect<Event>) {
36///         match event {
37///             Event::Click => {
38///                 let new_model = Model {
39///                     clicks: model.clicks + 1,
40///                     ..model.clone()
41///                 };
42///                 (new_model, Effect::none())
43///             }
44///         }
45///     }
46///
47///     fn view(&self, model: &Model, emitter: &Emitter<Event>) -> Props {
48///         let emitter = emitter.clone();
49///         Props {
50///             clicks: model.clicks,
51///             on_click: Box::new(move || {
52///                 emitter.emit(Event::Click);
53///             }),
54///         }
55///     }
56/// }
57/// ```
58pub struct Emitter<Event: Send>(pub(crate) Sender<Event>);
59
60impl<Event: Send> Clone for Emitter<Event> {
61    fn clone(&self) -> Self {
62        Self(self.0.clone())
63    }
64}
65
66impl<Event: Send> Emitter<Event> {
67    /// Create a new emitter from a channel sender.
68    pub(crate) fn new(sender: Sender<Event>) -> Self {
69        Self(sender)
70    }
71
72    /// Emit an event.
73    ///
74    /// This queues the event for processing by the runtime. Multiple threads
75    /// can safely call this method concurrently via the lock-free channel.
76    pub fn emit(&self, event: Event) {
77        self.0.send(event).ok();
78    }
79}