refactor: use inheritance-based style for nodes
This commit is contained in:
@@ -1,5 +1,4 @@
|
|||||||
use crate::core::client::Client;
|
use crate::core::client::Client;
|
||||||
use crate::nodes::core::{Node, NodeRef};
|
|
||||||
use crate::nodes::spatial::Spatial;
|
use crate::nodes::spatial::Spatial;
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use libstardustxr::scenegraph;
|
use libstardustxr::scenegraph;
|
||||||
@@ -8,41 +7,26 @@ use rccell::{RcCell, WeakCell};
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
pub struct Scenegraph<'a> {
|
pub struct Scenegraph<'a> {
|
||||||
nodes: HashMap<String, RcCell<Node<'a>>>,
|
pub spatial_nodes: HashMap<String, RcCell<Spatial<'a>>>,
|
||||||
root: NodeRef<'a>,
|
|
||||||
hmd: NodeRef<'a>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Scenegraph<'a> {
|
impl<'a> Scenegraph<'a> {
|
||||||
pub fn new(client: &mut Client<'a>) -> Self {
|
pub fn new(client: &mut Client<'a>) -> Self {
|
||||||
|
// root: Spatial::new(Some(client), "/", Default::default()),
|
||||||
|
// hmd: Spatial::new(Some(client), "/hmd", Default::default()),
|
||||||
Scenegraph {
|
Scenegraph {
|
||||||
nodes: HashMap::new(),
|
spatial_nodes: HashMap::new(),
|
||||||
root: Spatial::new_node(Some(client), "/", Default::default()).unwrap(),
|
|
||||||
hmd: Spatial::new_node(Some(client), "/hmd", Default::default()).unwrap(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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> {
|
impl<'a> scenegraph::Scenegraph for Scenegraph<'a> {
|
||||||
fn send_signal(&self, path: &str, method: &str, data: &[u8]) -> Result<(), ScenegraphError> {
|
fn send_signal(&self, path: &str, method: &str, data: &[u8]) -> Result<(), ScenegraphError> {
|
||||||
self.nodes
|
self.spatial_nodes
|
||||||
.get(path)
|
.get(path)
|
||||||
.ok_or(ScenegraphError::NodeNotFound)?
|
.ok_or(ScenegraphError::NodeNotFound)?
|
||||||
.borrow()
|
.borrow()
|
||||||
|
.node
|
||||||
.send_local_signal(method, data)
|
.send_local_signal(method, data)
|
||||||
.map_err(|_| ScenegraphError::MethodNotFound)
|
.map_err(|_| ScenegraphError::MethodNotFound)
|
||||||
}
|
}
|
||||||
@@ -52,10 +36,11 @@ impl<'a> scenegraph::Scenegraph for Scenegraph<'a> {
|
|||||||
method: &str,
|
method: &str,
|
||||||
data: &[u8],
|
data: &[u8],
|
||||||
) -> Result<Vec<u8>, ScenegraphError> {
|
) -> Result<Vec<u8>, ScenegraphError> {
|
||||||
self.nodes
|
self.spatial_nodes
|
||||||
.get(path)
|
.get(path)
|
||||||
.ok_or(ScenegraphError::NodeNotFound)?
|
.ok_or(ScenegraphError::NodeNotFound)?
|
||||||
.borrow()
|
.borrow()
|
||||||
|
.node
|
||||||
.execute_local_method(method, data)
|
.execute_local_method(method, data)
|
||||||
.map_err(|_| ScenegraphError::MethodNotFound)
|
.map_err(|_| ScenegraphError::MethodNotFound)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,29 +1,17 @@
|
|||||||
use crate::core::client::Client;
|
use crate::core::client::Client;
|
||||||
use anyhow::{anyhow, ensure, Result};
|
use anyhow::{anyhow, ensure, Result};
|
||||||
use libstardustxr::messenger::Messenger;
|
use libstardustxr::messenger::Messenger;
|
||||||
use rccell::{RcCell, WeakCell};
|
|
||||||
use std::{collections::HashMap, rc::Weak, vec::Vec};
|
use std::{collections::HashMap, rc::Weak, vec::Vec};
|
||||||
|
|
||||||
use super::spatial::Spatial;
|
|
||||||
|
|
||||||
pub type Signal<'a> = dyn Fn(&[u8]) + 'a;
|
pub type Signal<'a> = dyn Fn(&[u8]) + 'a;
|
||||||
pub type Method<'a> = dyn Fn(&[u8]) -> Vec<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> {
|
pub struct Node<'a> {
|
||||||
path: String,
|
path: String,
|
||||||
trailing_slash_pos: usize,
|
trailing_slash_pos: usize,
|
||||||
pub messenger: Weak<Messenger<'a>>,
|
messenger: Weak<Messenger<'a>>,
|
||||||
local_signals: HashMap<String, Box<Signal<'a>>>,
|
local_signals: HashMap<String, Box<Signal<'a>>>,
|
||||||
local_methods: HashMap<String, Box<Method<'a>>>,
|
local_methods: HashMap<String, Box<Method<'a>>>,
|
||||||
|
|
||||||
pub data: NodeData<'a>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Node<'a> {
|
impl<'a> Node<'a> {
|
||||||
@@ -34,17 +22,13 @@ impl<'a> Node<'a> {
|
|||||||
self.path.as_str()
|
self.path.as_str()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_path(
|
pub fn from_path(client: Option<&Client<'a>>, path: &str) -> Result<Node<'a>> {
|
||||||
client: Option<&mut Client<'a>>,
|
|
||||||
path: &str,
|
|
||||||
data_closure: impl FnOnce(NodeRef<'a>) -> NodeData<'a>,
|
|
||||||
) -> Result<NodeRef<'a>> {
|
|
||||||
ensure!(path.starts_with('/'), "Invalid path {}", path);
|
ensure!(path.starts_with('/'), "Invalid path {}", path);
|
||||||
let mut weak_messenger = Weak::default();
|
let mut weak_messenger = Weak::default();
|
||||||
client
|
if let Some(c) = client.as_ref() {
|
||||||
.as_ref()
|
weak_messenger = c.get_weak_messenger();
|
||||||
.map(|c| weak_messenger = c.get_weak_messenger());
|
}
|
||||||
let node = Node {
|
Ok(Node {
|
||||||
path: path.to_string(),
|
path: path.to_string(),
|
||||||
trailing_slash_pos: path
|
trailing_slash_pos: path
|
||||||
.rfind('/')
|
.rfind('/')
|
||||||
@@ -52,14 +36,7 @@ impl<'a> Node<'a> {
|
|||||||
messenger: weak_messenger,
|
messenger: weak_messenger,
|
||||||
local_signals: HashMap::new(),
|
local_signals: HashMap::new(),
|
||||||
local_methods: 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<()> {
|
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 crate::core::client::Client;
|
||||||
use anyhow::Result;
|
use rccell::{RcCell, WeakCell};
|
||||||
use vek::mat::repr_c::row_major::Mat4;
|
use vek::mat::repr_c::row_major::Mat4;
|
||||||
|
|
||||||
pub struct Spatial<'a> {
|
pub struct Spatial<'a> {
|
||||||
node: NodeRef<'a>,
|
pub node: Node<'a>,
|
||||||
|
parent: WeakCell<Spatial<'a>>,
|
||||||
transform: Mat4<f32>,
|
transform: Mat4<f32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Spatial<'a> {
|
impl<'a> Spatial<'a> {
|
||||||
pub fn new(node: NodeRef<'a>, transform: Mat4<f32>) -> Self {
|
pub fn new(
|
||||||
Spatial { node, transform }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn new_node(
|
|
||||||
client: Option<&mut Client<'a>>,
|
client: Option<&mut Client<'a>>,
|
||||||
path: &str,
|
path: &str,
|
||||||
transform: Mat4<f32>,
|
transform: Mat4<f32>,
|
||||||
) -> Result<NodeRef<'a>> {
|
) -> WeakCell<Self> {
|
||||||
Node::from_path(client, path, move |node| {
|
let spatial = RcCell::new(Spatial {
|
||||||
NodeData::Spatial(Spatial::new(node, transform))
|
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