111 lines
3.3 KiB
Rust
111 lines
3.3 KiB
Rust
use std::collections::HashMap;
|
|
use std::sync::{Arc, Mutex};
|
|
use serde_json::Value;
|
|
use tauri::{AppHandle, Manager};
|
|
use tokio::sync::mpsc;
|
|
use tracing::{debug, info};
|
|
use uuid::Uuid;
|
|
|
|
pub type EventHandler = Box<dyn Fn(Value) + Send + Sync>;
|
|
|
|
pub struct EventBus {
|
|
subscribers: Arc<Mutex<HashMap<String, Vec<(SubscriptionId, EventHandler)>>>>,
|
|
sender: mpsc::UnboundedSender<Event>,
|
|
}
|
|
|
|
pub type SubscriptionId = String;
|
|
|
|
#[derive(Clone, Debug)]
|
|
pub struct Event {
|
|
pub event_type: String,
|
|
pub data: Value,
|
|
pub timestamp: chrono::DateTime<chrono::Utc>,
|
|
pub source: String,
|
|
}
|
|
|
|
impl EventBus {
|
|
pub fn new() -> Self {
|
|
let (sender, mut receiver) = mpsc::unbounded_channel::<Event>();
|
|
let subscribers: Arc<Mutex<HashMap<String, Vec<(SubscriptionId, EventHandler)>>>> = Arc::new(Mutex::new(HashMap::new()));
|
|
let subs_clone = subscribers.clone();
|
|
|
|
// Event dispatch loop
|
|
tokio::spawn(async move {
|
|
while let Some(event) = receiver.recv().await {
|
|
let subs = subs_clone.lock().unwrap();
|
|
if let Some(handlers) = subs.get(&event.event_type) {
|
|
for (_, handler) in handlers.iter() {
|
|
handler(event.data.clone());
|
|
}
|
|
}
|
|
// Also dispatch to wildcard subscribers
|
|
if let Some(wildcard_handlers) = subs.get("*") {
|
|
for (_, handler) in wildcard_handlers.iter() {
|
|
handler(event.data.clone());
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
Self {
|
|
subscribers,
|
|
sender,
|
|
}
|
|
}
|
|
|
|
pub fn subscribe(
|
|
&self,
|
|
event_type: &str,
|
|
handler_id: String
|
|
) -> SubscriptionId {
|
|
let id = Uuid::new_v4().to_string();
|
|
|
|
// Store subscription info - actual handler would be connected via frontend
|
|
let mut subs = self.subscribers.lock().unwrap();
|
|
let handlers = subs.entry(event_type.to_string()).or_insert_with(Vec::new);
|
|
|
|
// Create a handler that emits to frontend
|
|
let handler = Box::new(move |data: Value| {
|
|
debug!("Event {} dispatched to {}", event_type, handler_id);
|
|
// Frontend callback handled via Tauri events
|
|
}) as EventHandler;
|
|
|
|
handlers.push((id.clone(), handler));
|
|
|
|
info!("Subscribed {} to event type {}", id, event_type);
|
|
id
|
|
}
|
|
|
|
pub fn unsubscribe(&self, subscription_id: &str) {
|
|
let mut subs = self.subscribers.lock().unwrap();
|
|
for handlers in subs.values_mut() {
|
|
handlers.retain(|(id, _)| id != subscription_id);
|
|
}
|
|
info!("Unsubscribed {}", subscription_id);
|
|
}
|
|
|
|
pub fn publish(&self,
|
|
event_type: &str,
|
|
data: Value
|
|
) {
|
|
let event = Event {
|
|
event_type: event_type.to_string(),
|
|
data,
|
|
timestamp: chrono::Utc::now(),
|
|
source: "core".to_string(),
|
|
};
|
|
|
|
let _ = self.sender.send(event);
|
|
debug!("Published event: {}", event_type);
|
|
}
|
|
|
|
pub fn emit_to_frontend(
|
|
&self,
|
|
app_handle: &tauri::AppHandle,
|
|
event_type: &str,
|
|
data: Value
|
|
) {
|
|
app_handle.emit_all(event_type, data).ok();
|
|
}
|
|
}
|