From 618f2d6748e6191361958768ec7949584cd5f939 Mon Sep 17 00:00:00 2001 From: Nova Date: Mon, 23 May 2022 21:42:26 -0400 Subject: [PATCH] refactor: use inheritance-based style for nodes --- src/core/scenegraph.rs | 31 ++++++++--------------------- src/nodes/core.rs | 37 +++++++---------------------------- src/nodes/spatial.rs | 44 ++++++++++++++++++++++++++++++------------ 3 files changed, 47 insertions(+), 65 deletions(-) diff --git a/src/core/scenegraph.rs b/src/core/scenegraph.rs index 3622759..8b2ce16 100644 --- a/src/core/scenegraph.rs +++ b/src/core/scenegraph.rs @@ -1,5 +1,4 @@ use crate::core::client::Client; -use crate::nodes::core::{Node, NodeRef}; use crate::nodes::spatial::Spatial; use anyhow::Result; use libstardustxr::scenegraph; @@ -8,41 +7,26 @@ use rccell::{RcCell, WeakCell}; use std::collections::HashMap; pub struct Scenegraph<'a> { - nodes: HashMap>>, - root: NodeRef<'a>, - hmd: NodeRef<'a>, + pub spatial_nodes: HashMap>>, } impl<'a> Scenegraph<'a> { pub fn new(client: &mut Client<'a>) -> Self { + // root: Spatial::new(Some(client), "/", Default::default()), + // hmd: Spatial::new(Some(client), "/hmd", Default::default()), Scenegraph { - nodes: HashMap::new(), - root: Spatial::new_node(Some(client), "/", Default::default()).unwrap(), - hmd: Spatial::new_node(Some(client), "/hmd", Default::default()).unwrap(), + spatial_nodes: HashMap::new(), } } - pub fn add_node(&mut self, node: RcCell>) { - let path = node.borrow().get_path().to_string(); - self.nodes.insert(path, node); - } - - pub fn remove_node(&mut self, path: &str) { - self.nodes.remove(path); - } - - pub fn get_node(&self, path: &str) -> WeakCell> { - self.nodes - .get(path) - .map_or(WeakCell::new(), RcCell::downgrade) - } } impl<'a> scenegraph::Scenegraph for Scenegraph<'a> { fn send_signal(&self, path: &str, method: &str, data: &[u8]) -> Result<(), ScenegraphError> { - self.nodes + self.spatial_nodes .get(path) .ok_or(ScenegraphError::NodeNotFound)? .borrow() + .node .send_local_signal(method, data) .map_err(|_| ScenegraphError::MethodNotFound) } @@ -52,10 +36,11 @@ impl<'a> scenegraph::Scenegraph for Scenegraph<'a> { method: &str, data: &[u8], ) -> Result, ScenegraphError> { - self.nodes + self.spatial_nodes .get(path) .ok_or(ScenegraphError::NodeNotFound)? .borrow() + .node .execute_local_method(method, data) .map_err(|_| ScenegraphError::MethodNotFound) } diff --git a/src/nodes/core.rs b/src/nodes/core.rs index e24e5de..abef12a 100644 --- a/src/nodes/core.rs +++ b/src/nodes/core.rs @@ -1,29 +1,17 @@ use crate::core::client::Client; use anyhow::{anyhow, ensure, Result}; use libstardustxr::messenger::Messenger; -use rccell::{RcCell, WeakCell}; use std::{collections::HashMap, rc::Weak, vec::Vec}; -use super::spatial::Spatial; - pub type Signal<'a> = dyn Fn(&[u8]) + 'a; pub type Method<'a> = dyn Fn(&[u8]) -> Vec + 'a; -pub type NodeRef<'a> = WeakCell>; - -pub enum NodeData<'a> { - None, - Spatial(Spatial<'a>), -} - pub struct Node<'a> { path: String, trailing_slash_pos: usize, - pub messenger: Weak>, + messenger: Weak>, local_signals: HashMap>>, local_methods: HashMap>>, - - pub data: NodeData<'a>, } impl<'a> Node<'a> { @@ -34,17 +22,13 @@ impl<'a> Node<'a> { self.path.as_str() } - pub fn from_path( - client: Option<&mut Client<'a>>, - path: &str, - data_closure: impl FnOnce(NodeRef<'a>) -> NodeData<'a>, - ) -> 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(); - client - .as_ref() - .map(|c| weak_messenger = c.get_weak_messenger()); - let node = Node { + if let Some(c) = client.as_ref() { + weak_messenger = c.get_weak_messenger(); + } + Ok(Node { path: path.to_string(), trailing_slash_pos: path .rfind('/') @@ -52,14 +36,7 @@ impl<'a> Node<'a> { messenger: weak_messenger, local_signals: HashMap::new(), local_methods: HashMap::new(), - - data: NodeData::None, - }; - let node_ref = RcCell::new(node); - let weak_node = node_ref.downgrade(); - node_ref.borrow_mut().data = data_closure(weak_node.clone()); - client.map(|c| c.scenegraph.as_mut().unwrap().add_node(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 c7f9ca4..bb2fdcf 100644 --- a/src/nodes/spatial.rs +++ b/src/nodes/spatial.rs @@ -1,25 +1,45 @@ -use super::core::{Node, NodeData, NodeRef}; +use super::core::Node; use crate::core::client::Client; -use anyhow::Result; +use rccell::{RcCell, WeakCell}; use vek::mat::repr_c::row_major::Mat4; pub struct Spatial<'a> { - node: NodeRef<'a>, + pub node: Node<'a>, + parent: WeakCell>, transform: Mat4, } impl<'a> Spatial<'a> { - pub fn new(node: NodeRef<'a>, transform: Mat4) -> Self { - Spatial { node, transform } - } - - pub fn new_node( + pub fn new( client: Option<&mut Client<'a>>, path: &str, transform: Mat4, - ) -> Result> { - Node::from_path(client, path, move |node| { - NodeData::Spatial(Spatial::new(node, transform)) - }) + ) -> WeakCell { + let spatial = RcCell::new(Spatial { + node: Node::from_path(client.as_deref(), path).unwrap(), + parent: WeakCell::new(), + transform, + }); + let weak_spatial = spatial.downgrade(); + client + .unwrap() + .scenegraph + .as_mut() + .unwrap() + .spatial_nodes + .insert(path.to_string(), spatial); + weak_spatial } + + pub fn get_local_transform(&self) -> Mat4 { + self.transform + } + pub fn get_global_transform(&self) -> Mat4 { + match self.parent.upgrade() { + Some(value) => value.borrow().get_global_transform() * self.transform, + None => self.transform, + } + } + + // pub fn get_transform(&self, space: NodeRef) {} }