From 52565cd38144396f7c181b325d8bf1f6ebf8840f Mon Sep 17 00:00:00 2001 From: Nova Date: Tue, 17 May 2022 02:35:44 -0400 Subject: [PATCH] refactor(node): return weak reference and store Rc in scenegraph --- Cargo.toml | 1 + src/core/scenegraph.rs | 42 +++++++++++++++++------------------------- src/nodes/core.rs | 15 +++++++-------- src/nodes/spatial.rs | 25 ++++++++++++++++++++----- 4 files changed, 45 insertions(+), 38 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index ea2162e..e9de61d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,3 +12,4 @@ ctrlc = "3.2.2" mio = {version = "0.8.3", features = ["net", "os-poll", "os-ext"]} slab = "0.4.6" thiserror = "1.0.31" +vek = "0.15.8" diff --git a/src/core/scenegraph.rs b/src/core/scenegraph.rs index 2e28973..1bcc804 100644 --- a/src/core/scenegraph.rs +++ b/src/core/scenegraph.rs @@ -2,11 +2,11 @@ use crate::nodes::core::Node; use anyhow::Result; use libstardustxr::scenegraph; use libstardustxr::scenegraph::ScenegraphError; -use std::{cell::RefCell, collections::HashMap, rc::Weak}; +use std::{cell::RefCell, collections::HashMap, rc::Rc, rc::Weak}; #[derive(Default)] pub struct Scenegraph<'a> { - nodes: RefCell>>>, + nodes: RefCell>>>>, } impl<'a> Scenegraph<'a> { @@ -14,26 +14,20 @@ impl<'a> Scenegraph<'a> { Default::default() } - pub fn add_node(&self, node: Weak>) { - let node_ref = node.upgrade(); - if node_ref.is_none() { - return; - } + pub fn add_node(&self, node: Rc>>) { + let path = node.borrow().get_path().to_string(); + self.nodes.borrow_mut().insert(path, node); + } + + pub fn remove_node(&self, path: &str) { + self.nodes.borrow_mut().remove(path); + } + + pub fn get_node(&self, path: &str) -> Weak>> { self.nodes - .borrow_mut() - .insert(String::from(node_ref.unwrap().get_path()), node); - } - - pub fn remove_node(&self, node: Weak>) { - let node_ref = node.upgrade(); - if node_ref.is_none() { - return; - } - self.nodes.borrow_mut().remove(node_ref.unwrap().get_path()); - } - - pub fn get_node(&self, path: &str) -> Weak> { - self.nodes.borrow().get(path).cloned().unwrap_or_default() + .borrow() + .get(path) + .map_or(Weak::default(), |node| Rc::downgrade(node)) } } @@ -43,8 +37,7 @@ impl<'a> scenegraph::Scenegraph for Scenegraph<'a> { .borrow() .get(path) .ok_or(ScenegraphError::NodeNotFound)? - .upgrade() - .ok_or(ScenegraphError::NodeNotFound)? + .borrow() .send_local_signal(method, data) .map_err(|_| ScenegraphError::MethodNotFound) } @@ -58,8 +51,7 @@ impl<'a> scenegraph::Scenegraph for Scenegraph<'a> { .borrow() .get(path) .ok_or(ScenegraphError::NodeNotFound)? - .upgrade() - .ok_or(ScenegraphError::NodeNotFound)? + .borrow() .execute_local_method(method, data) .map_err(|_| ScenegraphError::MethodNotFound) } diff --git a/src/nodes/core.rs b/src/nodes/core.rs index b9eba5a..bced367 100644 --- a/src/nodes/core.rs +++ b/src/nodes/core.rs @@ -2,6 +2,7 @@ use crate::core::client::Client; use anyhow::{anyhow, ensure, Result}; use libstardustxr::messenger::Messenger; use std::{ + cell::RefCell, collections::HashMap, rc::{Rc, Weak}, vec::Vec, @@ -19,7 +20,7 @@ pub struct Node<'a> { local_signals: HashMap>>, local_methods: HashMap>>, - pub spatial: Option>, + pub spatial: Option, } impl<'a> Node<'a> { @@ -30,7 +31,7 @@ impl<'a> Node<'a> { self.path.as_str() } - pub fn from_path(client: Option<&Client<'a>>, path: &str) -> Result> { + pub fn from_path(client: Option<&Client<'a>>, path: &str) -> Result>> { ensure!(path.starts_with('/'), "Invalid path {}", path); let mut weak_messenger = Weak::default(); if client.is_some() { @@ -45,14 +46,12 @@ impl<'a> Node<'a> { spatial: None, }; - let node_ref = Rc::new(node); + let node_ref = Rc::new(RefCell::new(node)); + let weak_node = Rc::downgrade(&node_ref); if client.is_some() { - client - .unwrap() - .scenegraph - .add_node(Rc::downgrade(&node_ref)); + client.unwrap().scenegraph.add_node(node_ref); } - Ok(node_ref) + Ok(weak_node) } pub fn send_local_signal(&self, method: &str, data: &[u8]) -> Result<()> { diff --git a/src/nodes/spatial.rs b/src/nodes/spatial.rs index 07dc008..0fc4313 100644 --- a/src/nodes/spatial.rs +++ b/src/nodes/spatial.rs @@ -1,11 +1,26 @@ use super::core::Node; +use crate::core::client::Client; +use anyhow::Result; +use std::cell::RefCell; +use std::rc::Weak; +use vek::mat::repr_c::row_major::Mat4; -pub struct Spatial<'a> { - node: &'a Node<'a>, +pub struct Spatial { + transform: Mat4, } -impl<'a> Spatial<'a> { - pub fn new(node: &'a Node<'a>) -> Self { - Spatial { node } +impl<'a> Spatial { + pub fn new(transform: Mat4) -> Self { + Spatial { transform } + } + + pub fn new_node( + client: Option<&'a Client<'a>>, + path: &str, + transform: Mat4, + ) -> Result>>> { + let node = Node::from_path(client, path)?; + node.upgrade().unwrap().borrow_mut().spatial = Some(Spatial::new(transform)); + Ok(node) } }