48 lines
1.3 KiB
Rust
48 lines
1.3 KiB
Rust
use std::collections::HashMap;
|
|
use std::sync::Mutex;
|
|
use tokio::sync::mpsc;
|
|
|
|
/// A fired timer event delivered to the plugin that created it.
|
|
#[derive(Clone, Debug)]
|
|
pub struct TimerEvent {
|
|
pub timer_id: String,
|
|
pub callback_id: String,
|
|
}
|
|
|
|
/// Manages per-plugin event channels for timer callbacks.
|
|
pub struct CallbackBus {
|
|
senders: Mutex<HashMap<String, mpsc::Sender<TimerEvent>>>,
|
|
}
|
|
|
|
impl CallbackBus {
|
|
pub fn new() -> Self {
|
|
Self {
|
|
senders: Mutex::new(HashMap::new()),
|
|
}
|
|
}
|
|
|
|
/// Register a plugin and get a receiver for its timer events.
|
|
pub fn subscribe(&self, plugin_id: &str) -> mpsc::Receiver<TimerEvent> {
|
|
let (tx, rx) = mpsc::channel(64);
|
|
self.senders
|
|
.lock()
|
|
.unwrap()
|
|
.insert(plugin_id.to_string(), tx);
|
|
rx
|
|
}
|
|
|
|
/// Deliver a timer event to the target plugin.
|
|
pub fn fire(&self, plugin_id: &str, event: TimerEvent) {
|
|
let senders = self.senders.lock().unwrap();
|
|
if let Some(tx) = senders.get(plugin_id) {
|
|
// Non-blocking send; drop if channel full
|
|
let _ = tx.try_send(event);
|
|
}
|
|
}
|
|
|
|
/// Remove a plugin's channel (on unregister/disconnect).
|
|
pub fn remove(&self, plugin_id: &str) {
|
|
self.senders.lock().unwrap().remove(plugin_id);
|
|
}
|
|
}
|