EU-Utility-V3/src-tauri/src/events.rs

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();
}
}