diff --git a/src/core/mod.rs b/src/core/mod.rs index a38a168..b945e42 100644 --- a/src/core/mod.rs +++ b/src/core/mod.rs @@ -1,4 +1,5 @@ pub mod client; pub mod eventloop; +pub mod nodelist; pub mod registry; pub mod scenegraph; diff --git a/src/core/nodelist.rs b/src/core/nodelist.rs new file mode 100644 index 0000000..5eb1398 --- /dev/null +++ b/src/core/nodelist.rs @@ -0,0 +1,31 @@ +use crate::nodes::core::Node; +use anyhow::{anyhow, ensure, Result}; +use parking_lot::RwLock; +use std::sync::Weak; + +#[derive(Default)] +pub struct LifeLinkedNodeList { + nodes: RwLock>>, +} +impl LifeLinkedNodeList { + pub fn add(&self, node: Weak) { + self.nodes.write().push(node); + } + + pub fn clear(&self) { + self.nodes + .read() + .iter() + .filter_map(|node| node.upgrade()) + .filter_map(|node| node.get_client().zip(Some(node.get_path().to_string()))) + .for_each(|(client, path)| { + client.scenegraph.remove_node(&path); + }); + self.nodes.write().clear(); + } +} +impl Drop for LifeLinkedNodeList { + fn drop(&mut self) { + self.clear(); + } +} diff --git a/src/nodes/data.rs b/src/nodes/data.rs index 481cb44..d89fc95 100644 --- a/src/nodes/data.rs +++ b/src/nodes/data.rs @@ -2,6 +2,7 @@ use super::core::{Alias, Node}; use super::field::Field; use super::spatial::{get_spatial_parent_flex, get_transform_pose_flex, Spatial}; use crate::core::client::Client; +use crate::core::nodelist::LifeLinkedNodeList; use crate::core::registry::Registry; use anyhow::{anyhow, ensure, Result}; use glam::{vec3a, Mat4}; @@ -65,7 +66,7 @@ fn mask_get_map_at_root(binary: &[u8]) -> Result> #[derive(Default)] pub struct PulseSender { mask: RwLock, - aliases: Mutex>, + aliases: LifeLinkedNodeList, } impl PulseSender { pub fn add_to(node: &Arc) -> Result<()> { @@ -125,11 +126,7 @@ impl PulseSender { distance_sorted_receivers.sort_by(|(d1, _), (d2, _)| d1.partial_cmp(d2).unwrap()); Ok(flexbuffer_from_vector_arguments(move |fbb| { - let mut aliases = sender.aliases.lock(); - for alias in aliases.iter() { - node.get_client().unwrap().scenegraph.remove_node(alias); - } - *aliases = Vec::with_capacity(distance_sorted_receivers.len()); + sender.aliases.clear(); for (i, (_, receiver)) in distance_sorted_receivers.iter().enumerate() { let receiver_alias = Node::create(node.get_path(), receiver.uid.as_str(), false); let receiver_alias = calling_client.scenegraph.add_node(receiver_alias); @@ -139,7 +136,7 @@ impl PulseSender { vec![], vec!["sendData"], ); - aliases[i] = "".to_owned(); + sender.aliases.add(Arc::downgrade(&receiver_alias)); fbb.push(receiver.uid.as_str()); } }))