refactor: use inheritance-based style for nodes
This commit is contained in:
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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<()> {
|
||||
|
||||
@@ -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) {}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user