refactor: modularize getting nodes and aspects

This commit is contained in:
Nova
2022-10-18 10:58:39 -04:00
parent a399db006e
commit 88555ee047
14 changed files with 91 additions and 126 deletions

View File

@@ -1,9 +1,9 @@
use super::{eventloop::EventLoop, scenegraph::Scenegraph};
use crate::{
core::registry::Registry,
nodes::{data, drawable, fields, hmd, input, items, root::Root, spatial, startup},
nodes::{data, drawable, fields, hmd, input, items, root::Root, spatial, startup, Node},
};
use anyhow::Result;
use anyhow::{anyhow, Result};
use lazy_static::lazy_static;
use once_cell::sync::OnceCell;
use parking_lot::Mutex;
@@ -99,6 +99,13 @@ impl Client {
client
}
#[inline]
pub fn get_node(&self, name: &'static str, path: &str) -> Result<Arc<Node>> {
self.scenegraph
.get_node(path)
.ok_or_else(|| anyhow!("{} not found", name))
}
pub async fn dispatch(&self) -> Result<(), std::io::Error> {
match &self.messenger {
Some(messenger) => messenger.dispatch(&self.scenegraph).await,

View File

@@ -1,16 +1,17 @@
use super::fields::Field;
use super::spatial::{get_spatial_parent_flex, parse_transform, Spatial};
use super::spatial::{parse_transform, Spatial};
use super::{Alias, Node};
use crate::core::client::Client;
use crate::core::nodelist::LifeLinkedNodeList;
use crate::core::registry::Registry;
use crate::nodes::fields::find_field;
use crate::nodes::spatial::find_spatial_parent;
use anyhow::{anyhow, ensure, Result};
use glam::vec3a;
use parking_lot::Mutex;
use serde::Deserialize;
use stardust_xr::schemas::flex::{deserialize, serialize};
use stardust_xr::values::Transform;
use std::sync::{Arc, Weak};
static PULSE_SENDER_REGISTRY: Registry<PulseSender> = Registry::new();
@@ -253,7 +254,7 @@ pub fn create_pulse_sender_flex(
}
let info: CreatePulseSenderInfo = deserialize(data)?;
let node = Node::create(&calling_client, "/data/sender", info.name, true);
let parent = get_spatial_parent_flex(&calling_client, info.parent_path)?;
let parent = find_spatial_parent(&calling_client, info.parent_path)?;
let transform = parse_transform(info.transform, true, true, false)?;
let node = node.add_to_scenegraph();
Spatial::add_to(&node, Some(parent), transform)?;
@@ -285,16 +286,9 @@ pub fn create_pulse_receiver_flex(
}
let info: CreatePulseReceiverInfo = deserialize(data)?;
let node = Node::create(&calling_client, "/data/sender", info.name, true);
let parent = get_spatial_parent_flex(&calling_client, info.parent_path)?;
let parent = find_spatial_parent(&calling_client, info.parent_path)?;
let transform = parse_transform(info.transform, true, true, false)?;
let field = calling_client
.scenegraph
.get_node(info.field_path)
.ok_or_else(|| anyhow!("Field not found"))?
.field
.get()
.ok_or_else(|| anyhow!("Field node is not a field"))?
.clone();
let field = find_field(&calling_client, info.field_path)?;
let node = node.add_to_scenegraph();
Spatial::add_to(&node, Some(parent), transform)?;

View File

@@ -3,7 +3,7 @@ use crate::core::client::Client;
use crate::core::destroy_queue;
use crate::core::registry::Registry;
use crate::core::resource::ResourceID;
use crate::nodes::spatial::{get_spatial_parent_flex, parse_transform, Spatial};
use crate::nodes::spatial::{find_spatial_parent, parse_transform, Spatial};
use anyhow::{anyhow, ensure, Result};
use once_cell::sync::OnceCell;
use parking_lot::Mutex;
@@ -175,7 +175,7 @@ pub fn create_flex(_node: &Node, calling_client: Arc<Client>, data: &[u8]) -> Re
}
let info: CreateModelInfo = deserialize(data)?;
let node = Node::create(&calling_client, "/drawable/model", info.name, true);
let parent = get_spatial_parent_flex(&calling_client, info.parent_path)?;
let parent = find_spatial_parent(&calling_client, info.parent_path)?;
let transform = parse_transform(info.transform, true, true, true)?;
let node = node.add_to_scenegraph();
Spatial::add_to(&node, Some(parent), transform)?;

View File

@@ -1,7 +1,7 @@
use crate::{
core::{client::Client, destroy_queue, registry::Registry, resource::ResourceID},
nodes::{
spatial::{get_spatial_parent_flex, parse_transform, Spatial},
spatial::{find_spatial_parent, parse_transform, Spatial},
Node,
},
};
@@ -190,7 +190,7 @@ pub fn create_flex(_node: &Node, calling_client: Arc<Client>, data: &[u8]) -> Re
}
let info: CreateTextInfo = deserialize(data)?;
let node = Node::create(&calling_client, "/drawable/text", info.name, true);
let parent = get_spatial_parent_flex(&calling_client, info.parent_path)?;
let parent = find_spatial_parent(&calling_client, info.parent_path)?;
let transform = parse_transform(info.transform, true, true, true)?;
let color = Rgba::from_slice(&info.color);

View File

@@ -1,6 +1,6 @@
use super::{Field, FieldTrait, Node};
use crate::core::client::Client;
use crate::nodes::spatial::{get_spatial_parent_flex, parse_transform, Spatial};
use crate::nodes::spatial::{find_spatial_parent, parse_transform, Spatial};
use anyhow::{ensure, Result};
use glam::{vec3, vec3a, Vec3, Vec3A};
use mint::Vector3;
@@ -73,7 +73,7 @@ pub fn create_box_field_flex(_node: &Node, calling_client: Arc<Client>, data: &[
}
let info: CreateFieldInfo = deserialize(data)?;
let node = Node::create(&calling_client, "/field", info.name, true);
let parent = get_spatial_parent_flex(&calling_client, info.parent_path)?;
let parent = find_spatial_parent(&calling_client, info.parent_path)?;
let transform = parse_transform(info.transform, true, true, false)?;
let node = node.add_to_scenegraph();
Spatial::add_to(&node, Some(parent), transform)?;

View File

@@ -1,6 +1,6 @@
use super::{Field, FieldTrait, Node};
use crate::core::client::Client;
use crate::nodes::spatial::{get_spatial_parent_flex, parse_transform, Spatial};
use crate::nodes::spatial::{find_spatial_parent, parse_transform, Spatial};
use anyhow::{ensure, Result};
use glam::{swizzles::*, vec2, Vec3A};
use portable_atomic::AtomicF32;
@@ -80,7 +80,7 @@ pub fn create_cylinder_field_flex(
}
let info: CreateFieldInfo = deserialize(data)?;
let node = Node::create(&calling_client, "/field", info.name, true);
let parent = get_spatial_parent_flex(&calling_client, info.parent_path)?;
let parent = find_spatial_parent(&calling_client, info.parent_path)?;
let transform = parse_transform(info.transform, true, true, false)?;
let node = node.add_to_scenegraph();
Spatial::add_to(&node, Some(parent), transform)?;

View File

@@ -9,7 +9,8 @@ use self::sphere::{create_sphere_field_flex, SphereField};
use super::spatial::Spatial;
use super::Node;
use crate::core::client::Client;
use anyhow::{anyhow, Result};
use crate::nodes::spatial::find_reference_space;
use anyhow::Result;
use glam::{vec2, vec3a, Vec3, Vec3A};
use mint::Vector3;
use serde::Deserialize;
@@ -76,14 +77,7 @@ fn field_distance_flex(node: &Node, calling_client: Arc<Client>, data: &[u8]) ->
point: Vector3<f32>,
}
let args: FieldInfoArgs = deserialize(data)?;
let reference_space = calling_client
.scenegraph
.get_node(args.reference_space_path)
.ok_or_else(|| anyhow!("Reference space node does not exist"))?
.spatial
.get()
.ok_or_else(|| anyhow!("Reference space node does not have a spatial"))?
.clone();
let reference_space = find_reference_space(&calling_client, args.reference_space_path)?;
let distance = node
.field
@@ -100,14 +94,7 @@ fn field_normal_flex(node: &Node, calling_client: Arc<Client>, data: &[u8]) -> R
radius: Option<f32>,
}
let args: FieldInfoArgs = deserialize(data)?;
let reference_space = calling_client
.scenegraph
.get_node(args.reference_space_path)
.ok_or_else(|| anyhow!("Reference space node does not exist"))?
.spatial
.get()
.ok_or_else(|| anyhow!("Reference space node does not have a spatial"))?
.clone();
let reference_space = find_reference_space(&calling_client, args.reference_space_path)?;
let normal = node.field.get().as_ref().unwrap().normal(
reference_space.as_ref(),
@@ -128,14 +115,7 @@ fn field_closest_point_flex(
radius: Option<f32>,
}
let args: FieldInfoArgs = deserialize(data)?;
let reference_space = calling_client
.scenegraph
.get_node(args.reference_space_path)
.ok_or_else(|| anyhow!("Reference space node does not exist"))?
.spatial
.get()
.ok_or_else(|| anyhow!("Reference space node does not have a spatial"))?
.clone();
let reference_space = find_reference_space(&calling_client, args.reference_space_path)?;
let closest_point = node.field.get().as_ref().unwrap().closest_point(
reference_space.as_ref(),
@@ -224,3 +204,9 @@ pub fn ray_march(ray: Ray, field: &Field) -> RayMarchResult {
result
}
pub fn find_field(client: &Client, path: &str) -> Result<Arc<Field>> {
Ok(client
.get_node("Field", path)?
.get_aspect("Field", "info", |n| &n.field)?)
}

View File

@@ -1,6 +1,6 @@
use super::{Field, FieldTrait, Node};
use crate::core::client::Client;
use crate::nodes::spatial::{get_spatial_parent_flex, Spatial};
use crate::nodes::spatial::{find_spatial_parent, Spatial};
use anyhow::{ensure, Result};
use glam::{Mat4, Vec3A};
use mint::Vector3;
@@ -77,7 +77,7 @@ pub fn create_sphere_field_flex(
}
let info: CreateFieldInfo = deserialize(data)?;
let node = Node::create(&calling_client, "/field", info.name, true);
let parent = get_spatial_parent_flex(&calling_client, info.parent_path)?;
let parent = find_spatial_parent(&calling_client, info.parent_path)?;
let transform = Mat4::from_translation(
info.origin
.unwrap_or_else(|| Vector3::from([0.0; 3]))

View File

@@ -7,12 +7,13 @@ use self::pointer::Pointer;
use self::tip::Tip;
use super::fields::Field;
use super::spatial::{get_spatial_parent_flex, parse_transform, Spatial};
use super::spatial::{find_spatial_parent, parse_transform, Spatial};
use super::Node;
use crate::core::client::Client;
use crate::core::eventloop::FRAME;
use crate::core::registry::Registry;
use anyhow::{anyhow, ensure, Result};
use crate::nodes::fields::find_field;
use anyhow::{ensure, Result};
use glam::Mat4;
use nanoid::nanoid;
use parking_lot::Mutex;
@@ -227,19 +228,11 @@ pub fn create_input_handler_flex(
field_path: &'a str,
}
let info: CreateInputHandlerInfo = deserialize(data)?;
let node = Node::create(&calling_client, "/input/handler", info.name, true);
let parent = get_spatial_parent_flex(&calling_client, info.parent_path)?;
let parent = find_spatial_parent(&calling_client, info.parent_path)?;
let transform = parse_transform(info.transform, true, true, false)?;
let field = calling_client
.scenegraph
.get_node(info.field_path)
.ok_or_else(|| anyhow!("Field not found"))?
.field
.get()
.ok_or_else(|| anyhow!("Field node is not a field"))?
.clone();
let field = find_field(&calling_client, info.field_path)?;
let node = node.add_to_scenegraph();
let node = Node::create(&calling_client, "/input/handler", info.name, true).add_to_scenegraph();
Spatial::add_to(&node, Some(parent), transform)?;
InputHandler::add_to(&node, &field)?;
Ok(())

View File

@@ -2,7 +2,7 @@ use super::{DistanceLink, InputSpecialization};
use crate::core::client::Client;
use crate::nodes::fields::Field;
use crate::nodes::input::{InputMethod, InputType};
use crate::nodes::spatial::{get_spatial_parent_flex, parse_transform, Spatial};
use crate::nodes::spatial::{find_spatial_parent, parse_transform, Spatial};
use crate::nodes::Node;
use anyhow::Result;
use glam::{vec3a, Mat4};
@@ -53,7 +53,7 @@ pub fn create_tip_flex(_node: &Node, calling_client: Arc<Client>, data: &[u8]) -
}
let info: CreateTipInfo = deserialize(data)?;
let node = Node::create(&calling_client, "/input/method/tip", info.name, true);
let parent = get_spatial_parent_flex(&calling_client, info.parent_path)?;
let parent = find_spatial_parent(&calling_client, info.parent_path)?;
let transform = parse_transform(info.transform, true, true, false)?;
let node = node.add_to_scenegraph();

View File

@@ -2,7 +2,7 @@ use super::{Item, ItemSpecialization, ItemType, ITEM_TYPE_INFO_ENVIRONMENT};
use crate::{
core::client::{Client, INTERNAL_CLIENT},
nodes::{
spatial::{get_spatial_parent_flex, parse_transform, Spatial},
spatial::{find_spatial_parent, parse_transform, Spatial},
Node,
},
};
@@ -56,7 +56,7 @@ pub(super) fn create_environment_item_flex(
let info: CreateEnvironmentItemInfo = deserialize(data)?;
let parent_name = format!("/item/{}/item/", ITEM_TYPE_INFO_ENVIRONMENT.type_name);
let node = Node::create(&INTERNAL_CLIENT, &parent_name, info.name, true);
let space = get_spatial_parent_flex(&calling_client, info.parent_path)?;
let space = find_spatial_parent(&calling_client, info.parent_path)?;
let transform = parse_transform(info.transform, true, true, false)?;
let node = node.add_to_scenegraph();
Spatial::add_to(&node, None, transform * space.global_transform())?;

View File

@@ -1,13 +1,13 @@
mod environment;
use self::environment::EnvironmentItem;
use super::fields::Field;
use super::spatial::{get_spatial_parent_flex, parse_transform, Spatial};
use super::spatial::{find_spatial_parent, parse_transform, Spatial};
use super::{Alias, Node};
use crate::core::client::{Client, INTERNAL_CLIENT};
use crate::core::nodelist::LifeLinkedNodeList;
use crate::core::registry::Registry;
use crate::nodes::fields::find_field;
use crate::wayland::panel_item::{register_panel_item_ui_flex, PanelItem};
use anyhow::{anyhow, ensure, Result};
use lazy_static::lazy_static;
@@ -356,20 +356,13 @@ pub(self) fn create_item_acceptor_flex(
}
let info: CreateItemAcceptorInfo = deserialize(data)?;
let parent_name = format!("/item/{}/acceptor/", ITEM_TYPE_INFO_ENVIRONMENT.type_name);
let space = get_spatial_parent_flex(&calling_client, info.parent_path)?;
let space = find_spatial_parent(&calling_client, info.parent_path)?;
let transform = parse_transform(info.transform, true, true, false)?;
let field = calling_client
.scenegraph
.get_node(info.field_path)
.ok_or_else(|| anyhow!("Field node not found"))?;
let field = field
.field
.get()
.ok_or_else(|| anyhow!("Field node is not a field"))?;
let field = find_field(&calling_client, info.field_path)?;
let node = Node::create(&INTERNAL_CLIENT, &parent_name, info.name, true).add_to_scenegraph();
Spatial::add_to(&node, Some(space), transform)?;
ItemAcceptor::add_to(&node, type_info, Arc::downgrade(field));
ItemAcceptor::add_to(&node, type_info, Arc::downgrade(&field));
node.item
.get()
.unwrap()

View File

@@ -145,6 +145,21 @@ impl Node {
self.local_methods.insert(name.to_string(), method);
}
pub fn get_aspect<F, T>(
&self,
node_name: &'static str,
aspect_type: &'static str,
aspect_fn: F,
) -> Result<Arc<T>>
where
F: FnOnce(&Node) -> &OnceCell<Arc<T>>,
{
aspect_fn(self)
.get()
.ok_or_else(|| anyhow!("{} is not a {} node", node_name, aspect_type))
.cloned()
}
pub fn send_local_signal(
&self,
calling_client: Arc<Client>,

View File

@@ -161,14 +161,7 @@ impl Spatial {
.spatial
.get()
.ok_or_else(|| anyhow!("Node doesn't have a spatial?"))?;
let relative_spatial = calling_client
.scenegraph
.get_node(deserialize(data)?)
.ok_or_else(|| anyhow!("Space not found"))?
.spatial
.get()
.ok_or_else(|| anyhow!("Reference space node is not a spatial"))?
.clone();
let relative_spatial = find_reference_space(&calling_client, deserialize(data)?)?;
let (scale, rotation, position) = Spatial::space_to_space_matrix(
Some(this_spatial.as_ref()),
@@ -192,16 +185,7 @@ impl Spatial {
let transform_args: TransformArgs = deserialize(data)?;
let reference_space_transform = transform_args
.reference_space_path
.map(|path| -> Result<Arc<Spatial>> {
Ok(calling_client
.scenegraph
.get_node(path)
.ok_or_else(|| anyhow!("Other spatial node not found"))?
.spatial
.get()
.ok_or_else(|| anyhow!("Node is not a Spatial!"))?
.clone())
})
.map(|path| find_reference_space(&calling_client, path))
.transpose()?;
node.spatial.get().unwrap().set_local_transform_components(
@@ -215,34 +199,18 @@ impl Spatial {
calling_client: Arc<Client>,
data: &[u8],
) -> Result<()> {
let parent = calling_client
.scenegraph
.get_node(deserialize(data)?)
.ok_or_else(|| anyhow!("Parent node not found"))?
.spatial
.get()
.ok_or_else(|| anyhow!("Parent node is not a Spatial!"))?
.clone();
let parent = find_spatial_parent(&calling_client, deserialize(data)?)?;
node.spatial
.get()
.unwrap()
.set_spatial_parent(Some(&parent))?;
Ok(())
.set_spatial_parent(Some(&parent))
}
pub fn set_spatial_parent_in_place_flex(
node: &Node,
calling_client: Arc<Client>,
data: &[u8],
) -> Result<()> {
let parent_path = flexbuffers::Reader::get_root(data)?.get_str()?;
let parent = calling_client
.scenegraph
.get_node(parent_path)
.ok_or_else(|| anyhow!("Parent node not found"))?
.spatial
.get()
.ok_or_else(|| anyhow!("Parent node is not a Spatial!"))?
.clone();
let parent = find_spatial_parent(&calling_client, deserialize(data)?)?;
node.spatial
.get()
.unwrap()
@@ -277,18 +245,27 @@ pub fn parse_transform(
))
}
pub fn get_spatial_parent_flex(
pub fn find_spatial(
calling_client: &Arc<Client>,
node_name: &'static str,
node_path: &str,
) -> anyhow::Result<Arc<Spatial>> {
Ok(calling_client
.get_node(node_name, node_path)?
.get_aspect(node_name, "spatial", |n| &n.spatial)?
.clone())
}
pub fn find_spatial_parent(
calling_client: &Arc<Client>,
node_path: &str,
) -> Result<Arc<Spatial>> {
Ok(calling_client
.scenegraph
.get_node(node_path)
.ok_or_else(|| anyhow!("Spatial parent node not found"))?
.spatial
.get()
.ok_or_else(|| anyhow!("Spatial parent node is not a spatial"))?
.clone())
) -> anyhow::Result<Arc<Spatial>> {
find_spatial(calling_client, "Spatial parent", node_path)
}
pub fn find_reference_space(
calling_client: &Arc<Client>,
node_path: &str,
) -> anyhow::Result<Arc<Spatial>> {
find_spatial(calling_client, "Reference space", node_path)
}
pub fn create_interface(client: &Arc<Client>) {
@@ -306,7 +283,7 @@ pub fn create_spatial_flex(_node: &Node, calling_client: Arc<Client>, data: &[u8
}
let info: CreateSpatialInfo = deserialize(data)?;
let node = Node::create(&calling_client, "/spatial/spatial", info.name, true);
let parent = get_spatial_parent_flex(&calling_client, info.parent_path)?;
let parent = find_spatial(&calling_client, "Spatial parent", info.parent_path)?;
let transform = parse_transform(info.transform, true, true, true)?;
let node = node.add_to_scenegraph();
Spatial::add_to(&node, Some(parent), transform)?;