use crate::data_model::{DataModel, WebSocketMessage}; use std::sync::Arc; use tokio::sync::{broadcast, RwLock}; use tracing::debug; /// Manages the application state and broadcasts updates to WebSocket clients pub struct StateManager { data: Arc>, revision: Arc>, broadcast_tx: broadcast::Sender, } impl StateManager { pub fn new() -> Self { let (broadcast_tx, _) = broadcast::channel(100); Self { data: Arc::new(RwLock::new(DataModel::new())), revision: Arc::new(RwLock::new(0)), broadcast_tx, } } /// Get the current data model and revision pub async fn get_snapshot(&self) -> (DataModel, u32) { let data = self.data.read().await.clone(); let rev = *self.revision.read().await; (data, rev) } /// Subscribe to state updates pub fn subscribe(&self) -> broadcast::Receiver { self.broadcast_tx.subscribe() } /// Update the data model and broadcast to all connected clients pub async fn update_data(&self, new_data: DataModel) { let mut data = self.data.write().await; let mut rev = self.revision.write().await; *data = new_data.clone(); *rev += 1; debug!("Data model updated to revision {}", *rev); // Broadcast full data dump to all connected clients // In the future, we can optimize this by computing and sending JSON patches let message = WebSocketMessage { rev: *rev, data: Some(new_data), patch: None, }; // Ignore errors if no receivers are connected let _ = self.broadcast_tx.send(message); } /// Get a WebSocket message with the current state pub async fn get_initial_message(&self) -> WebSocketMessage { let (data, rev) = self.get_snapshot().await; WebSocketMessage { rev, data: Some(data), patch: None, } } } impl Default for StateManager { fn default() -> Self { Self::new() } }