use std::{ collections::HashMap, sync::{Arc, Mutex, MutexGuard}, }; use element_bridge::TextureBridge; pub type AllBuffers = Arc>>>>>; #[derive(Eq, Hash, PartialEq, Debug)] pub struct WindowId { id: u64, name: String, } #[derive(Default)] pub struct WindowsManager { inner: HashMap>>, all_bridges: Vec<(usize, Arc>)>, all_revelant_buffers: Arc>>>>>, } impl WindowsManager { pub fn new() -> Self { Self { inner: HashMap::new(), all_bridges: Vec::new(), all_revelant_buffers: Arc::new(Mutex::new(HashMap::new())), } } pub fn edit_window(&mut self, id: WindowId, f: F) -> (usize, Arc>) where F: FnOnce(&mut TextureBridge), { let bridge = self.inner.get(&id).unwrap(); let mut _bridge = bridge.lock().unwrap(); f(&mut _bridge); (0, bridge.clone()) } pub fn add_window( &mut self, id: WindowId, bridge: TextureBridge, ) -> (usize, Arc>) { let bridge = Arc::new(Mutex::new(bridge)); // New window self.inner .entry(id) .and_modify(|e| *e = bridge.clone()) .or_insert(bridge.clone()); let new_id = self.all_bridges.len(); self.all_bridges.push((new_id, bridge.clone())); let buffer = { let bridge = bridge.lock().unwrap(); bridge.buffer() }; self.all_revelant_buffers .lock() .unwrap() .insert(new_id, buffer); (new_id, bridge) } pub fn get_bridge(&self, id: usize) -> Option>> { self.all_bridges.get(id).map(|(_, bridge)| bridge.clone()) } pub fn buffer(&self) -> AllBuffers { self.all_revelant_buffers.clone() } } impl WindowId { pub fn new>(name: S) -> Self { Self { id: 0, name: name.into(), } } } #[derive(Clone, Default)] pub struct WM(Arc>); impl WM { pub fn new() -> Self { Self(Arc::new(std::sync::Mutex::new(WindowsManager::new()))) } pub fn windows_manager(&self) -> Arc> { self.0.clone() } pub fn wm(&self) -> MutexGuard<'_, WindowsManager> { self.0.lock().unwrap() } }