refactor: use inheritance-based style for nodes

This commit is contained in:
Nova
2022-05-23 21:42:26 -04:00
parent 1709d19da2
commit 618f2d6748
3 changed files with 47 additions and 65 deletions

View File

@@ -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<String, RcCell<Node<'a>>>,
root: NodeRef<'a>,
hmd: NodeRef<'a>,
pub spatial_nodes: HashMap<String, RcCell<Spatial<'a>>>,
}
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<Node<'a>>) {
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<Node<'a>> {
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<Vec<u8>, ScenegraphError> {
self.nodes
self.spatial_nodes
.get(path)
.ok_or(ScenegraphError::NodeNotFound)?
.borrow()
.node
.execute_local_method(method, data)
.map_err(|_| ScenegraphError::MethodNotFound)
}

View File

@@ -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<u8> + 'a;
pub type NodeRef<'a> = WeakCell<Node<'a>>;
pub enum NodeData<'a> {
None,
Spatial(Spatial<'a>),
}
pub struct Node<'a> {
path: String,
trailing_slash_pos: usize,
pub messenger: Weak<Messenger<'a>>,
messenger: Weak<Messenger<'a>>,
local_signals: HashMap<String, Box<Signal<'a>>>,
local_methods: HashMap<String, Box<Method<'a>>>,
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<NodeRef<'a>> {
pub fn from_path(client: Option<&Client<'a>>, path: &str) -> Result<Node<'a>> {
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<()> {

View File

@@ -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<Spatial<'a>>,
transform: Mat4<f32>,
}
impl<'a> Spatial<'a> {
pub fn new(node: NodeRef<'a>, transform: Mat4<f32>) -> Self {
Spatial { node, transform }
}
pub fn new_node(
pub fn new(
client: Option<&mut Client<'a>>,
path: &str,
transform: Mat4<f32>,
) -> Result<NodeRef<'a>> {
Node::from_path(client, path, move |node| {
NodeData::Spatial(Spatial::new(node, transform))
})
) -> WeakCell<Self> {
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<f32> {
self.transform
}
pub fn get_global_transform(&self) -> Mat4<f32> {
match self.parent.upgrade() {
Some(value) => value.borrow().get_global_transform() * self.transform,
None => self.transform,
}
}
// pub fn get_transform(&self, space: NodeRef) {}
}