use std::{ collections::{HashMap, HashSet}, sync::{Arc, LazyLock}, }; use btleplug::platform::{Adapter, PeripheralId}; use tauri::{ async_runtime::{JoinHandle, Mutex, RwLock}, AppHandle, Runtime, }; use uuid::Uuid; use crate::config_db::ConfigDb; pub struct AppState { pub db: ConfigDb, pub central_event_handler: Arc>>>, } unsafe impl Send for AppState {} unsafe impl Sync for AppState {} static CENTRAL_ADAPTER: LazyLock>>> = LazyLock::new(|| Arc::new(RwLock::new(None))); static CACHED_SERVICES: LazyLock>>>> = LazyLock::new(|| Arc::new(RwLock::new(HashMap::new()))); static FOUND_PERIPHERALS: LazyLock>>> = LazyLock::new(|| Arc::new(RwLock::new(HashSet::new()))); static SCANNING: LazyLock>> = LazyLock::new(|| Arc::new(Mutex::new(false))); static CONNECTED_PERIPHERAL: LazyLock>>> = LazyLock::new(|| Arc::new(Mutex::new(None))); impl AppState { pub async fn new(app: &AppHandle) -> anyhow::Result { let db = ConfigDb::open(app)?; Ok(Self { db, central_event_handler: Arc::new(Mutex::new(None)), }) } pub async fn set_central_event_handler(&self, handler: JoinHandle<()>) { let mut central_event_handler = self.central_event_handler.lock().await; *central_event_handler = Some(handler); } pub async fn clear_central_event_handler(&self) { let mut central_event_handler = self.central_event_handler.lock().await; if let Some(handler) = central_event_handler.take() { handler.abort(); } } } pub async fn get_central_adapter() -> Option { let central_adapter = CENTRAL_ADAPTER.read().await; central_adapter.clone() } pub async fn set_central_adapter(adapter: Adapter) { let mut central_adapter = CENTRAL_ADAPTER.write().await; *central_adapter = Some(adapter); } pub async fn cleaar_central_adapter() { let mut central_adapter = CENTRAL_ADAPTER.write().await; *central_adapter = None; } pub async fn get_found_peripherals() -> HashSet { let found_peripherals = FOUND_PERIPHERALS.read().await; found_peripherals.clone() } pub async fn update_found_peripherals(peripheral: PeripheralId) { let mut found_peripherals = FOUND_PERIPHERALS.write().await; found_peripherals.insert(peripheral); } pub async fn clear_found_peripherals() { let mut found_peripherals = FOUND_PERIPHERALS.write().await; found_peripherals.clear(); let mut cached_services = CACHED_SERVICES.write().await; cached_services.clear(); } pub async fn get_found_setvices(peripheral: &PeripheralId) -> HashSet { let cached_services = CACHED_SERVICES.read().await; cached_services.get(peripheral).cloned().unwrap_or_default() } pub async fn update_found_services(peripheral: PeripheralId, services: HashSet) { let mut cached_services = CACHED_SERVICES.write().await; cached_services.insert(peripheral, services); } pub async fn get_scanning() -> bool { let scanning = SCANNING.lock().await; *scanning } pub async fn set_scanning(scanning: bool) { let mut scanning_state = SCANNING.lock().await; *scanning_state = scanning; } pub async fn get_connected_peripheral() -> Option { let connected_peripheral = CONNECTED_PERIPHERAL.lock().await; connected_peripheral.clone() } pub async fn set_connected_peripheral(peripheral: PeripheralId) { let mut connected_peripheral = CONNECTED_PERIPHERAL.lock().await; *connected_peripheral = Some(peripheral); } pub async fn clear_connected_peripheral() { let mut connected_peripheral = CONNECTED_PERIPHERAL.lock().await; *connected_peripheral = None; }