use crate::nodes::Node; use parking_lot::Mutex; use rustc_hash::FxHashMap; use std::{ borrow::Borrow, hash::Hash, sync::{Arc, Weak}, }; #[derive(Default)] pub struct LifeLinkedNodeList { nodes: Mutex>>, } impl LifeLinkedNodeList { pub fn add(&self, node: Weak) { self.nodes.lock().push(node); } pub fn clear(&self) { self.nodes .lock() .iter() .filter_map(|node| node.upgrade()) .for_each(|node| { node.destroy(); }); self.nodes.lock().clear(); } } impl Drop for LifeLinkedNodeList { fn drop(&mut self) { self.clear(); } } #[derive(Default)] pub struct LifeLinkedNodeMap { nodes: Mutex>>, } #[allow(dead_code)] impl LifeLinkedNodeMap { pub fn add(&self, key: K, node: &Arc) { self.nodes.lock().insert(key, Arc::downgrade(node)); } pub fn get(&self, key: &Q) -> Option> where Q: ?Sized, K: Borrow, Q: Hash + Eq, { self.nodes.lock().get(key).and_then(|n| n.upgrade()) } pub fn nodes(&self) -> Vec> { self.nodes .lock() .values() .filter_map(|v| v.upgrade()) .collect() } pub fn remove(&self, key: &Q) -> Option> where Q: ?Sized, K: Borrow, Q: Hash + Eq, { self.nodes.lock().remove(key).and_then(|n| n.upgrade()) } pub fn clear(&self) { let mut nodes = self.nodes.lock(); nodes .values() .filter_map(|node| node.upgrade()) .for_each(|node| { node.destroy(); }); nodes.clear(); } } impl Drop for LifeLinkedNodeMap { fn drop(&mut self) { self.clear(); } }