diff --git a/Cargo.toml b/Cargo.toml index e9de61d..528f96c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,7 @@ libstardustxr = {path = "../libstardustxr-rs"} anyhow = "1.0.57" ctrlc = "3.2.2" mio = {version = "0.8.3", features = ["net", "os-poll", "os-ext"]} +rccell = "0.1.3" slab = "0.4.6" thiserror = "1.0.31" vek = "0.15.8" diff --git a/src/core/client.rs b/src/core/client.rs index a566003..d286087 100644 --- a/src/core/client.rs +++ b/src/core/client.rs @@ -5,7 +5,7 @@ use mio::net::UnixStream; use std::rc::{Rc, Weak}; pub struct Client<'a> { - pub messenger: Rc>, + messenger: Rc>, pub scenegraph: Scenegraph<'a>, } diff --git a/src/core/scenegraph.rs b/src/core/scenegraph.rs index 201d6e2..0829392 100644 --- a/src/core/scenegraph.rs +++ b/src/core/scenegraph.rs @@ -4,17 +4,17 @@ use crate::nodes::spatial::Spatial; use anyhow::Result; use libstardustxr::scenegraph; use libstardustxr::scenegraph::ScenegraphError; -use std::{cell::RefCell, collections::HashMap, rc::Rc, rc::Weak}; +use rccell::{RcCell, WeakCell}; +use std::collections::HashMap; -#[derive(Default)] pub struct Scenegraph<'a> { - nodes: HashMap>>>, + nodes: HashMap>>, root: NodeRef<'a>, hmd: NodeRef<'a>, } impl<'a> Scenegraph<'a> { - pub fn add_node(&mut self, node: Rc>>) { + pub fn add_node(&mut self, node: RcCell>) { let path = node.borrow().get_path().to_string(); self.nodes.insert(path, node); } @@ -23,8 +23,10 @@ impl<'a> Scenegraph<'a> { self.nodes.remove(path); } - pub fn get_node(&self, path: &str) -> Weak>> { - self.nodes.get(path).map_or(Weak::default(), Rc::downgrade) + pub fn get_node(&self, path: &str) -> WeakCell> { + self.nodes + .get(path) + .map_or(WeakCell::new(), RcCell::downgrade) } pub fn add_interfaces(&mut self, client: &mut Client<'a>) -> Result<()> { @@ -34,6 +36,16 @@ impl<'a> Scenegraph<'a> { } } +impl<'a> Default for Scenegraph<'a> { + fn default() -> Self { + Scenegraph { + nodes: HashMap::new(), + root: WeakCell::new(), + hmd: WeakCell::new(), + } + } +} + impl<'a> scenegraph::Scenegraph for Scenegraph<'a> { fn send_signal(&self, path: &str, method: &str, data: &[u8]) -> Result<(), ScenegraphError> { self.nodes diff --git a/src/nodes/core.rs b/src/nodes/core.rs index b560965..0479d75 100644 --- a/src/nodes/core.rs +++ b/src/nodes/core.rs @@ -1,6 +1,7 @@ use crate::core::client::Client; use anyhow::{anyhow, ensure, Result}; use libstardustxr::messenger::Messenger; +use rccell::{RcCell, WeakCell}; use std::{ cell::RefCell, collections::HashMap, @@ -13,7 +14,12 @@ 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> = Weak>>; +pub type NodeRef<'a> = WeakCell>; + +pub enum NodeData<'a> { + None, + Spatial(Spatial<'a>), +} pub struct Node<'a> { path: String, @@ -22,7 +28,7 @@ pub struct Node<'a> { local_signals: HashMap>>, local_methods: HashMap>>, - pub spatial: Option, + pub data: NodeData<'a>, } impl<'a> Node<'a> { @@ -48,10 +54,10 @@ impl<'a> Node<'a> { local_signals: HashMap::new(), local_methods: HashMap::new(), - spatial: None, + data: NodeData::None, }; - let node_ref = Rc::new(RefCell::new(node)); - let weak_node = Rc::downgrade(&node_ref); + let node_ref = RcCell::new(node); + let weak_node = node_ref.downgrade(); match client { Some(client_) => client_.scenegraph.add_node(node_ref), None => {} diff --git a/src/nodes/spatial.rs b/src/nodes/spatial.rs index 2b7cf2f..c99a3fb 100644 --- a/src/nodes/spatial.rs +++ b/src/nodes/spatial.rs @@ -1,15 +1,16 @@ -use super::core::{Node, NodeRef}; +use super::core::{Node, NodeData, NodeRef}; use crate::core::client::Client; use anyhow::Result; use vek::mat::repr_c::row_major::Mat4; -pub struct Spatial { +pub struct Spatial<'a> { + node: &'a Node<'a>, transform: Mat4, } -impl<'a> Spatial { - pub fn new(transform: Mat4) -> Self { - Spatial { transform } +impl<'a> Spatial<'a> { + pub fn new(node: &'a Node<'a>, transform: Mat4) -> Self { + Spatial { node, transform } } pub fn new_node(