Skip to main content

santui_core/
event.rs

1use std::collections::VecDeque;
2
3/// Events that can be published through the application's [`EventBus`].
4#[derive(Clone, Debug, PartialEq)]
5pub enum Event {
6    /// The active theme changed (plugins should refresh their colours).
7    ThemeChanged,
8    /// The current user signed in or out (plugins should refresh their state).
9    UserUpdated,
10    /// Plugin-to-plugin message.  `from` and `to` are plugin ids.
11    PluginMessage {
12        from: String,
13        to: String,
14        action: String,
15        data: String,
16    },
17}
18
19/// A simple in-app event bus for decoupling components.
20///
21/// Components emit events via [`EventBus::emit`] and the main loop drains the
22/// pending queue via [`EventBus::drain`] once per frame, forwarding them to
23/// [`PluginManager::process_events`](crate::app::plugin_manager::PluginManager).
24///
25/// The pending queue is capped at [`MAX_PENDING`] entries.  If full, the oldest
26/// event is dropped to make room for the newest, ensuring the bus never grows
27/// without bound.
28#[derive(Debug, Default)]
29pub struct EventBus {
30    pending: VecDeque<Event>,
31}
32
33const MAX_PENDING: usize = 1024;
34
35impl EventBus {
36    pub fn new() -> Self {
37        Self {
38            pending: VecDeque::new(),
39        }
40    }
41
42    /// Push an event onto the pending queue.
43    ///
44    /// If the queue is at capacity the oldest event is dropped.
45    pub fn emit(&mut self, event: Event) {
46        if self.pending.len() >= MAX_PENDING {
47            self.pending.pop_front();
48        }
49        self.pending.push_back(event);
50    }
51
52    /// Drain all pending events.
53    pub fn drain(&mut self) -> Vec<Event> {
54        self.pending.drain(..).collect()
55    }
56}