From 529b86fa910040c1a5539fe8b0b9d086ad5f1eaa Mon Sep 17 00:00:00 2001 From: Nova Date: Wed, 25 Jan 2023 11:50:53 -0500 Subject: [PATCH] refactor: remove many unwrap calls --- src/core/client.rs | 22 +++++++-------- src/core/eventloop.rs | 5 +++- src/core/scenegraph.rs | 10 ++++--- src/main.rs | 43 +++++++++++++++++++----------- src/nodes/alias.rs | 37 ++++++++++++------------- src/nodes/data.rs | 26 +++++++++--------- src/nodes/drawable/lines.rs | 2 +- src/nodes/drawable/mod.rs | 4 +-- src/nodes/drawable/model.rs | 30 ++++++++++----------- src/nodes/drawable/text.rs | 2 +- src/nodes/fields/box.rs | 2 +- src/nodes/fields/cylinder.rs | 2 +- src/nodes/fields/mod.rs | 4 +-- src/nodes/fields/sphere.rs | 2 +- src/nodes/fields/torus.rs | 2 +- src/nodes/hmd.rs | 10 ++++--- src/nodes/input/mod.rs | 9 ++++--- src/nodes/input/tip.rs | 2 +- src/nodes/items/environment.rs | 5 ++-- src/nodes/items/mod.rs | 27 +++++++++---------- src/nodes/mod.rs | 8 ++++-- src/nodes/root.rs | 8 +++--- src/nodes/spatial/mod.rs | 6 ++--- src/nodes/spatial/zone.rs | 6 +++-- src/nodes/startup.rs | 13 ++++----- src/objects/input/mouse_pointer.rs | 9 ++++--- 26 files changed, 163 insertions(+), 133 deletions(-) diff --git a/src/core/client.rs b/src/core/client.rs index 1423079..b52010a 100644 --- a/src/core/client.rs +++ b/src/core/client.rs @@ -66,7 +66,7 @@ pub struct Client { pub startup_settings: Option, } impl Client { - pub fn from_connection(connection: UnixStream) -> Arc { + pub fn from_connection(connection: UnixStream) -> Result> { let pid = connection.peer_cred().ok().and_then(|c| c.pid()); let env = pid.and_then(|pid| get_env(pid).ok()); let exe = pid.and_then(|pid| fs::read_link(format!("/proc/{}/exe", pid)).ok()); @@ -98,15 +98,15 @@ impl Client { startup_settings, }); let _ = client.scenegraph.client.set(Arc::downgrade(&client)); - let _ = client.root.set(Root::create(&client)); - hmd::make_alias(&client); - spatial::create_interface(&client); - fields::create_interface(&client); - drawable::create_interface(&client); - data::create_interface(&client); - items::create_interface(&client); - input::create_interface(&client); - startup::create_interface(&client); + let _ = client.root.set(Root::create(&client)?); + hmd::make_alias(&client)?; + spatial::create_interface(&client)?; + fields::create_interface(&client)?; + drawable::create_interface(&client)?; + data::create_interface(&client)?; + items::create_interface(&client)?; + input::create_interface(&client)?; + startup::create_interface(&client)?; let pid_printable = pid .map(|pid| pid.to_string()) @@ -160,7 +160,7 @@ impl Client { ) }); - client + Ok(client) } #[inline] diff --git a/src/core/eventloop.rs b/src/core/eventloop.rs index 8f988cf..6a08ada 100644 --- a/src/core/eventloop.rs +++ b/src/core/eventloop.rs @@ -6,6 +6,7 @@ use std::sync::atomic::AtomicU64; use std::sync::Arc; use tokio::net::UnixListener; use tokio::task::JoinHandle; +use tracing::error; pub static FRAME: AtomicU64 = AtomicU64::new(0); @@ -20,7 +21,9 @@ impl EventLoop { let join_handle = task::new(|| "event loop", async move { loop { let Ok((socket, _)) = socket.accept().await else { continue }; - Client::from_connection(socket); + if let Err(e) = Client::from_connection(socket) { + error!(?e, "Unable to create client from connection"); + } } })?; let event_loop = Arc::new(EventLoop { join_handle }); diff --git a/src/core/scenegraph.rs b/src/core/scenegraph.rs index 143548a..28d6b4c 100644 --- a/src/core/scenegraph.rs +++ b/src/core/scenegraph.rs @@ -18,8 +18,8 @@ pub struct Scenegraph { } impl Scenegraph { - pub fn get_client(&self) -> Arc { - self.client.get().unwrap().upgrade().unwrap() + pub fn get_client(&self) -> Option> { + self.client.get()?.upgrade() } pub fn add_node(&self, node: Node) -> Arc { @@ -51,10 +51,11 @@ impl Scenegraph { impl scenegraph::Scenegraph for Scenegraph { fn send_signal(&self, path: &str, method: &str, data: &[u8]) -> Result<(), ScenegraphError> { + let Some(client) = self.get_client() else {return Err(ScenegraphError::SignalNotFound)}; debug_span!("Handle signal", path, method).in_scope(|| { self.get_node(path) .ok_or(ScenegraphError::NodeNotFound)? - .send_local_signal(self.get_client(), method, data) + .send_local_signal(client, method, data) }) } fn execute_method( @@ -63,10 +64,11 @@ impl scenegraph::Scenegraph for Scenegraph { method: &str, data: &[u8], ) -> Result, ScenegraphError> { + let Some(client) = self.get_client() else {return Err(ScenegraphError::MethodNotFound)}; debug_span!("Handle method", path, method).in_scope(|| { self.get_node(path) .ok_or(ScenegraphError::NodeNotFound)? - .execute_local_method(self.get_client(), method, data) + .execute_local_method(client, method, data) }) } } diff --git a/src/main.rs b/src/main.rs index b8b4f5d..846a012 100644 --- a/src/main.rs +++ b/src/main.rs @@ -27,7 +27,7 @@ use stereokit::render::StereoKitRender; use stereokit::texture::Texture; use stereokit::time::StereoKitTime; use tokio::{runtime::Handle, sync::oneshot}; -use tracing::{debug_span, info}; +use tracing::{debug_span, error, info}; use tracing_subscriber::{fmt, prelude::*, EnvFilter}; #[derive(Parser)] @@ -71,7 +71,10 @@ fn main() -> Result<()> { .with_filter(EnvFilter::from_default_env()); registry.with(log_layer).init(); - let project_dirs = ProjectDirs::from("", "", "stardust").unwrap(); + let project_dirs = ProjectDirs::from("", "", "stardust"); + if project_dirs.is_none() { + error!("Unable to get Stardust project directories, default skybox and startup script will not work."); + } let cli_args = Arc::new(CliArgs::parse()); let stereokit = stereokit::Settings::default() @@ -92,10 +95,14 @@ fn main() -> Result<()> { // Skytex/light stuff { - let skytex_path = project_dirs.config_dir().join("skytex.hdr"); - if let Some((tex, light)) = skytex_path - .exists() - .then(|| Texture::from_cubemap_equirectangular(&stereokit, &skytex_path, true, 100)) + if let Some((tex, light)) = project_dirs + .as_ref() + .and_then(|dirs| { + let skytex_path = dirs.config_dir().join("skytex.hdr"); + skytex_path.exists().then(|| { + Texture::from_cubemap_equirectangular(&stereokit, &skytex_path, true, 100) + }) + }) .flatten() { stereokit.set_skytex(&tex); @@ -111,7 +118,7 @@ fn main() -> Result<()> { } } - let mouse_pointer = cli_args.flatscreen.then(MousePointer::new); + let mouse_pointer = cli_args.flatscreen.then(MousePointer::new).transpose()?; let mut hands = (!cli_args.flatscreen).then(|| (SkHand::new(Handed::Left), SkHand::new(Handed::Right))); let mut controllers = (!cli_args.flatscreen && !cli_args.disable_controller).then(|| { @@ -140,13 +147,18 @@ fn main() -> Result<()> { let mut wayland = wayland::Wayland::new()?; info!("Stardust ready!"); - let _startup = Command::new(project_dirs.config_dir().join("startup")) - .env("WAYLAND_DISPLAY", &wayland.socket_name) - .env( - "STARDUST_INSTANCE", - event_loop_info.socket_path.file_name().unwrap(), - ) - .spawn(); + if let Some(project_dirs) = project_dirs.as_ref() { + let _startup = Command::new(project_dirs.config_dir().join("startup")) + .env("WAYLAND_DISPLAY", &wayland.socket_name) + .env( + "STARDUST_INSTANCE", + event_loop_info + .socket_path + .file_name() + .expect("Stardust socket path not found"), + ) + .spawn(); + } let mut last_frame_delta = Duration::ZERO; let mut sleep_duration = Duration::ZERO; @@ -222,7 +234,8 @@ async fn event_loop( info_sender: oneshot::Sender, stop_rx: oneshot::Receiver<()>, ) -> color_eyre::eyre::Result<()> { - let socket_path = server::get_free_socket_path().unwrap(); + let socket_path = + server::get_free_socket_path().expect("Unable to find a free stardust socket path"); let _event_loop = EventLoop::new(socket_path.clone()).expect("Couldn't create server socket"); info!("Init event loop"); info!( diff --git a/src/nodes/alias.rs b/src/nodes/alias.rs index 5570001..9bfad57 100644 --- a/src/nodes/alias.rs +++ b/src/nodes/alias.rs @@ -1,6 +1,6 @@ -use crate::core::client::Client; - use super::Node; +use crate::core::client::Client; +use color_eyre::eyre::{ensure, Result}; use std::sync::{Arc, Weak}; #[derive(Debug, Default, Clone)] @@ -24,22 +24,23 @@ impl Alias { name: &str, original: &Arc, info: AliasInfo, - ) -> Option> { - let node_free = client - .scenegraph - .get_node(&(parent.to_string() + "/" + name)) - .is_none(); + ) -> Result> { + ensure!( + client + .scenegraph + .get_node(&(parent.to_string() + "/" + name)) + .is_none(), + "Node already exists" + ); - node_free.then(|| { - let node = Node::create(client, parent, name, true).add_to_scenegraph(); - let alias = Alias { - node: Arc::downgrade(&node), - original: Arc::downgrade(original), - info, - }; - let alias = original.aliases.add(alias); - let _ = node.alias.set(alias); - node - }) + let node = Node::create(client, parent, name, true).add_to_scenegraph()?; + let alias = Alias { + node: Arc::downgrade(&node), + original: Arc::downgrade(original), + info, + }; + let alias = original.aliases.add(alias); + let _ = node.alias.set(alias); + Ok(node) } } diff --git a/src/nodes/data.rs b/src/nodes/data.rs index 6a15a47..4fa65c4 100644 --- a/src/nodes/data.rs +++ b/src/nodes/data.rs @@ -69,9 +69,8 @@ impl PulseSender { aliases: LifeLinkedNodeMap::default(), }; let sender = PULSE_SENDER_REGISTRY.add(sender); - let _ = node.pulse_sender.set(sender); + let _ = node.pulse_sender.set(sender.clone()); node.add_local_signal("send_data", PulseSender::send_data_flex); - let sender = node.pulse_sender.get().unwrap(); for receiver in PULSE_RECEIVER_REGISTRY.get_valid_contents() { sender.handle_new_receiver(&receiver); } @@ -95,7 +94,7 @@ impl PulseSender { ..Default::default() }, ); - if let Some(rx_alias) = rx_alias { + if let Ok(rx_alias) = rx_alias { self.aliases.add(receiver.uid.clone(), &rx_alias); if let Some(rx_field_node) = receiver.field.spatial_ref().node.upgrade() { @@ -110,7 +109,7 @@ impl PulseSender { ..Default::default() }, ); - if let Some(rx_field_alias) = rx_field_alias { + if let Ok(rx_field_alias) = rx_field_alias { self.aliases .add(receiver.uid.clone() + "-field", &rx_field_alias); } @@ -140,15 +139,16 @@ impl PulseSender { rotation: rotation.into(), }; - let _ = tx_node.send_remote_signal("new_receiver", &serialize(info).unwrap()); + let Ok(data) = serialize(info) else {return}; + let _ = tx_node.send_remote_signal("new_receiver", &data); } fn handle_drop_receiver(&self, uid: String) { - if let Some(tx_node) = self.node.upgrade() { - let _ = tx_node.send_remote_signal("drop_receiver", &serialize(&uid).unwrap()); - } self.aliases.remove(&uid); - self.aliases.remove(&(uid + "-field")); + self.aliases.remove(&(uid.clone() + "-field")); + let Some(tx_node) = self.node.upgrade() else {return}; + let Ok(data) = serialize(&uid) else {return}; + let _ = tx_node.send_remote_signal("drop_receiver", &data); } fn send_data_flex(node: &Node, calling_client: Arc, data: &[u8]) -> Result<()> { @@ -222,11 +222,11 @@ impl Drop for PulseReceiver { } } -pub fn create_interface(client: &Arc) { +pub fn create_interface(client: &Arc) -> Result<()> { let node = Node::create(client, "", "data", false); node.add_local_signal("create_pulse_sender", create_pulse_sender_flex); node.add_local_signal("create_pulse_receiver", create_pulse_receiver_flex); - node.add_to_scenegraph(); + node.add_to_scenegraph().map(|_| ()) } pub fn create_pulse_sender_flex( @@ -249,7 +249,7 @@ pub fn create_pulse_sender_flex( let mask = Mask(info.mask); mask.get_mask()?; - let node = node.add_to_scenegraph(); + let node = node.add_to_scenegraph()?; Spatial::add_to(&node, Some(parent), transform, false)?; PulseSender::add_to(&node, mask)?; Ok(()) @@ -276,7 +276,7 @@ pub fn create_pulse_receiver_flex( let mask = Mask(info.mask); mask.get_mask()?; - let node = node.add_to_scenegraph(); + let node = node.add_to_scenegraph()?; Spatial::add_to(&node, Some(parent), transform, false)?; PulseReceiver::add_to(&node, field, mask)?; Ok(()) diff --git a/src/nodes/drawable/lines.rs b/src/nodes/drawable/lines.rs index e53e929..54a0003 100644 --- a/src/nodes/drawable/lines.rs +++ b/src/nodes/drawable/lines.rs @@ -130,7 +130,7 @@ pub fn create_flex(_node: &Node, calling_client: Arc, data: &[u8]) -> Re p.color[2] = p.color[2].powf(2.2); } - let node = node.add_to_scenegraph(); + let node = node.add_to_scenegraph()?; Spatial::add_to(&node, Some(parent), transform, false)?; Lines::add_to(&node, info.points, info.cyclic)?; Ok(()) diff --git a/src/nodes/drawable/mod.rs b/src/nodes/drawable/mod.rs index fffe915..56f08ff 100644 --- a/src/nodes/drawable/mod.rs +++ b/src/nodes/drawable/mod.rs @@ -12,13 +12,13 @@ use std::{path::PathBuf, sync::Arc}; use stereokit::{lifecycle::StereoKitDraw, render::StereoKitRender, texture::Texture}; use tracing::instrument; -pub fn create_interface(client: &Arc) { +pub fn create_interface(client: &Arc) -> Result<()> { let node = Node::create(client, "", "drawable", false); node.add_local_signal("create_lines", lines::create_flex); node.add_local_signal("create_model", model::create_flex); node.add_local_signal("create_text", text::create_flex); node.add_local_signal("set_sky_file", set_sky_file_flex); - node.add_to_scenegraph(); + node.add_to_scenegraph().map(|_| ()) } #[instrument(level = "debug", skip(sk))] diff --git a/src/nodes/drawable/model.rs b/src/nodes/drawable/model.rs index 66554fa..b634e74 100644 --- a/src/nodes/drawable/model.rs +++ b/src/nodes/drawable/model.rs @@ -118,7 +118,7 @@ pub struct Model { space: Arc, resource_id: ResourceID, pending_model_path: OnceCell, - pending_material_parameters: Mutex>, + pending_material_parameters: Mutex>, pub pending_material_replacements: Mutex>>>, sk_model: OnceCell>, } @@ -179,7 +179,7 @@ impl Model { .unwrap() .pending_material_parameters .lock() - .insert((info.idx, info.name), info.value); + .insert((info.idx as i32, info.name), info.value); Ok(()) } @@ -204,22 +204,20 @@ impl Model { material_replacements.clear(); } - { + if let Some(client) = self.space.node.upgrade().and_then(|n| n.client.upgrade()) { let mut material_parameters = self.pending_material_parameters.lock(); - for ((material_idx, parameter_name), parameter_value) in material_parameters.iter() + for ((material_idx, parameter_name), parameter_value) in material_parameters.drain() { - if let Some(material) = sk_model.get_material(sk, *material_idx as i32) { - let new_material = material.clone(); - parameter_value.apply_to_material( - &self.space.node.upgrade().unwrap().client.upgrade().unwrap(), // TODO: don't unwrap - sk, - &new_material, - parameter_name.as_str(), - ); - sk_model.set_material(sk, *material_idx as i32, &new_material); - } + let Some(material) = sk_model.get_material(sk, material_idx) else {continue}; + let new_material = material.clone(); + parameter_value.apply_to_material( + &client, + sk, + &new_material, + parameter_name.as_str(), + ); + sk_model.set_material(sk, material_idx, &new_material); } - material_parameters.clear(); } let global_transform = self.space.global_transform().into(); @@ -254,7 +252,7 @@ pub fn create_flex(_node: &Node, calling_client: Arc, data: &[u8]) -> Re let node = Node::create(&calling_client, "/drawable/model", info.name, true); 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(); + let node = node.add_to_scenegraph()?; Spatial::add_to(&node, Some(parent), transform, false)?; Model::add_to(&node, info.resource)?; Ok(()) diff --git a/src/nodes/drawable/text.rs b/src/nodes/drawable/text.rs index 47ab688..76fe8d1 100644 --- a/src/nodes/drawable/text.rs +++ b/src/nodes/drawable/text.rs @@ -192,7 +192,7 @@ pub fn create_flex(_node: &Node, calling_client: Arc, data: &[u8]) -> Re let transform = parse_transform(info.transform, true, true, true); let color = Rgba::from_slice(&info.color); - let node = node.add_to_scenegraph(); + let node = node.add_to_scenegraph()?; Spatial::add_to(&node, Some(parent), transform, false)?; Text::add_to( &node, diff --git a/src/nodes/fields/box.rs b/src/nodes/fields/box.rs index 49365dc..763edbe 100644 --- a/src/nodes/fields/box.rs +++ b/src/nodes/fields/box.rs @@ -75,7 +75,7 @@ pub fn create_box_field_flex(_node: &Node, calling_client: Arc, data: &[ let node = Node::create(&calling_client, "/field", info.name, true); 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(); + let node = node.add_to_scenegraph()?; Spatial::add_to(&node, Some(parent), transform, false)?; BoxField::add_to(&node, info.size)?; Ok(()) diff --git a/src/nodes/fields/cylinder.rs b/src/nodes/fields/cylinder.rs index a468471..19c5943 100644 --- a/src/nodes/fields/cylinder.rs +++ b/src/nodes/fields/cylinder.rs @@ -81,7 +81,7 @@ pub fn create_cylinder_field_flex( let node = Node::create(&calling_client, "/field", info.name, true); 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(); + let node = node.add_to_scenegraph()?; Spatial::add_to(&node, Some(parent), transform, false)?; CylinderField::add_to(&node, info.length, info.radius)?; Ok(()) diff --git a/src/nodes/fields/mod.rs b/src/nodes/fields/mod.rs index 08e0174..019854b 100644 --- a/src/nodes/fields/mod.rs +++ b/src/nodes/fields/mod.rs @@ -217,13 +217,13 @@ impl Deref for Field { } } -pub fn create_interface(client: &Arc) { +pub fn create_interface(client: &Arc) -> Result<()> { let node = Node::create(client, "", "field", false); node.add_local_signal("create_box_field", create_box_field_flex); node.add_local_signal("create_cylinder_field", create_cylinder_field_flex); node.add_local_signal("create_sphere_field", create_sphere_field_flex); node.add_local_signal("create_torus_field", create_torus_field_flex); - node.add_to_scenegraph(); + node.add_to_scenegraph().map(|_| ()) } pub fn find_field(client: &Client, path: &str) -> Result> { diff --git a/src/nodes/fields/sphere.rs b/src/nodes/fields/sphere.rs index 008a0df..9d90dd6 100644 --- a/src/nodes/fields/sphere.rs +++ b/src/nodes/fields/sphere.rs @@ -81,7 +81,7 @@ pub fn create_sphere_field_flex( .unwrap_or_else(|| Vector3::from([0.0; 3])) .into(), ); - let node = node.add_to_scenegraph(); + let node = node.add_to_scenegraph()?; Spatial::add_to(&node, Some(parent), transform, false)?; SphereField::add_to(&node, info.radius)?; Ok(()) diff --git a/src/nodes/fields/torus.rs b/src/nodes/fields/torus.rs index 0674aac..d92bc0a 100644 --- a/src/nodes/fields/torus.rs +++ b/src/nodes/fields/torus.rs @@ -81,7 +81,7 @@ pub fn create_torus_field_flex( let node = Node::create(&calling_client, "/field", info.name, true); 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(); + let node = node.add_to_scenegraph()?; Spatial::add_to(&node, Some(parent), transform, false)?; TorusField::add_to(&node, info.radius_a, info.radius_b)?; Ok(()) diff --git a/src/nodes/hmd.rs b/src/nodes/hmd.rs index 199393f..5d94064 100644 --- a/src/nodes/hmd.rs +++ b/src/nodes/hmd.rs @@ -3,6 +3,7 @@ use crate::{ core::client::{Client, INTERNAL_CLIENT}, nodes::alias::AliasInfo, }; +use color_eyre::eyre::Result; use glam::{vec3, Mat4}; use std::sync::Arc; use stereokit::input::StereoKitInput; @@ -14,14 +15,17 @@ lazy_static::lazy_static! { fn create() -> Arc { let node = Arc::new(Node::create(&INTERNAL_CLIENT, "", "hmd", false)); - Spatial::add_to(&node, None, Mat4::IDENTITY, false).unwrap(); + Spatial::add_to(&node, None, Mat4::IDENTITY, false).expect("Unable to make spatial for HMD"); node } #[instrument(level = "debug", name = "Update HMD Pose", skip(sk))] pub fn frame(sk: &impl StereoKitInput) { - let spatial = HMD.spatial.get().unwrap(); + let spatial = HMD + .spatial + .get() + .expect("Unable to get spatial to update HMD"); let hmd_pose = sk.input_head(); *spatial.transform.lock() = Mat4::from_scale_rotation_translation( vec3(1.0, 1.0, 1.0), @@ -30,7 +34,7 @@ pub fn frame(sk: &impl StereoKitInput) { ); } -pub fn make_alias(client: &Arc) -> Option> { +pub fn make_alias(client: &Arc) -> Result> { Alias::create( client, "", diff --git a/src/nodes/input/mod.rs b/src/nodes/input/mod.rs index 1840958..f1fc082 100644 --- a/src/nodes/input/mod.rs +++ b/src/nodes/input/mod.rs @@ -190,7 +190,7 @@ impl InputHandler { #[instrument(level = "debug", skip(self, distance_link))] fn send_input(&self, frame: u64, distance_link: &DistanceLink, datamap: Datamap) { let data = distance_link.serialize(datamap); - let node = self.node.upgrade().unwrap(); + let Some(node) = self.node.upgrade() else {return}; let method = Arc::downgrade(&distance_link.method); let handler = Arc::downgrade(&distance_link.handler); @@ -226,11 +226,11 @@ impl Drop for InputHandler { } } -pub fn create_interface(client: &Arc) { +pub fn create_interface(client: &Arc) -> Result<()> { let node = Node::create(client, "", "input", false); node.add_local_signal("create_input_handler", create_input_handler_flex); node.add_local_signal("create_input_method_tip", tip::create_tip_flex); - node.add_to_scenegraph(); + node.add_to_scenegraph().map(|_| ()) } pub fn create_input_handler_flex( @@ -250,7 +250,8 @@ pub fn create_input_handler_flex( let transform = parse_transform(info.transform, true, true, true); let field = find_field(&calling_client, info.field_path)?; - let node = Node::create(&calling_client, "/input/handler", info.name, true).add_to_scenegraph(); + let node = + Node::create(&calling_client, "/input/handler", info.name, true).add_to_scenegraph()?; Spatial::add_to(&node, Some(parent), transform, false)?; InputHandler::add_to(&node, &field)?; Ok(()) diff --git a/src/nodes/input/tip.rs b/src/nodes/input/tip.rs index 6faf0c2..021015e 100644 --- a/src/nodes/input/tip.rs +++ b/src/nodes/input/tip.rs @@ -59,7 +59,7 @@ pub fn create_tip_flex(_node: &Node, calling_client: Arc, data: &[u8]) - 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(); + let node = node.add_to_scenegraph()?; Spatial::add_to(&node, Some(parent), transform, false)?; InputMethod::add_to( &node, diff --git a/src/nodes/items/environment.rs b/src/nodes/items/environment.rs index f43563c..cbd9671 100644 --- a/src/nodes/items/environment.rs +++ b/src/nodes/items/environment.rs @@ -74,12 +74,13 @@ pub(super) fn create_environment_item_flex( let space = find_spatial_parent(&calling_client, info.parent_path)?; let transform = parse_transform(info.transform, true, true, false); - let node = Node::create(&INTERNAL_CLIENT, &parent_name, info.name, false).add_to_scenegraph(); + let node = + Node::create(&INTERNAL_CLIENT, &parent_name, info.name, false).add_to_scenegraph()?; Spatial::add_to(&node, None, transform * space.global_transform(), false)?; EnvironmentItem::add_to(&node, info.item_data); node.item .get() .unwrap() - .make_alias_named(&calling_client, &parent_name, info.name); + .make_alias_named(&calling_client, &parent_name, info.name)?; Ok(()) } diff --git a/src/nodes/items/mod.rs b/src/nodes/items/mod.rs index 1468d4f..6eaeeee 100644 --- a/src/nodes/items/mod.rs +++ b/src/nodes/items/mod.rs @@ -18,7 +18,6 @@ use parking_lot::Mutex; use serde::Deserialize; use stardust_xr::schemas::flex::{deserialize, serialize}; use stardust_xr::values::Transform; - use std::hash::Hash; use std::ops::Deref; use std::sync::{Arc, Weak}; @@ -123,7 +122,7 @@ impl Item { client: &Arc, parent: &str, name: &str, - ) -> Option> { + ) -> Result> { Alias::create( client, parent, @@ -148,7 +147,7 @@ impl Item { }, ) } - fn make_alias(&self, client: &Arc, parent: &str) -> Option> { + fn make_alias(&self, client: &Arc, parent: &str) -> Result> { self.make_alias_named(client, parent, &self.uid) } @@ -230,8 +229,7 @@ impl ItemUI { let Some(node) = self.node.upgrade() else { return }; let Some(client) = node.get_client() else { return }; - if let Some(alias_node) = item.make_alias(&client, &(node.get_path().to_string() + "/item")) - { + if let Ok(alias_node) = item.make_alias(&client, &(node.get_path().to_string() + "/item")) { self.item_aliases.add(item.uid.clone(), &alias_node); } @@ -268,10 +266,10 @@ impl ItemUI { &client, &format!("/item/{}/acceptor", self.type_info.type_name), ); - if let Some(alias) = alias { + if let Ok(alias) = alias { self.acceptor_aliases.add(acceptor.uid.clone(), &alias); } - if let Some(field_alias) = field_alias { + if let Some(Ok(field_alias)) = field_alias { self.acceptor_field_aliases .add(acceptor.uid.clone(), &field_alias); } @@ -326,7 +324,7 @@ impl ItemAcceptor { &self, client: &Arc, parent: &str, - ) -> (Option>, Option>) { + ) -> (Result>, Option>>) { let acceptor_node = &self.node.upgrade().unwrap(); let acceptor_alias = Alias::create( client, @@ -339,7 +337,7 @@ impl ItemAcceptor { }, ); - let acceptor_field_alias = acceptor_alias.as_ref().and_then(|acceptor_alias| { + let acceptor_field_alias = acceptor_alias.as_ref().ok().map(|acceptor_alias| { Alias::create( client, acceptor_alias.get_path(), @@ -355,7 +353,7 @@ impl ItemAcceptor { let Some(node) = self.node.upgrade() else { return }; let Some(client) = node.get_client() else { return }; - if let Some(alias_node) = item.make_alias(&client, &node.path) { + if let Ok(alias_node) = item.make_alias(&client, &node.path) { self.accepted.add(item.uid.clone(), &alias_node); } let _ = node.send_remote_signal( @@ -379,7 +377,7 @@ impl Drop for ItemAcceptor { } } -pub fn create_interface(client: &Arc) { +pub fn create_interface(client: &Arc) -> Result<()> { let node = Node::create(client, "", "item", false); node.add_local_signal( "create_environment_item", @@ -387,7 +385,7 @@ pub fn create_interface(client: &Arc) { ); node.add_local_signal("register_item_ui", register_item_ui_flex); node.add_local_signal("create_item_acceptor", create_item_acceptor_flex); - node.add_to_scenegraph(); + node.add_to_scenegraph().map(|_| ()) } fn type_info(name: &str) -> Result<&'static TypeInfo> { @@ -406,7 +404,8 @@ pub fn register_item_ui_flex(_node: &Node, calling_client: Arc, data: &[ } let info: RegisterItemUIInfo = deserialize(data)?; let type_info = type_info(info.item_type)?; - let ui = Node::create(&calling_client, "/item", type_info.type_name, true).add_to_scenegraph(); + let ui = + Node::create(&calling_client, "/item", type_info.type_name, true).add_to_scenegraph()?; ItemUI::add_to(&ui, type_info)?; Ok(()) } @@ -432,7 +431,7 @@ fn create_item_acceptor_flex(_node: &Node, calling_client: Arc, data: &[ info.name, true, ) - .add_to_scenegraph(); + .add_to_scenegraph()?; Spatial::add_to(&node, Some(space), transform, false)?; ItemAcceptor::add_to(&node, type_info, field); Ok(()) diff --git a/src/nodes/mod.rs b/src/nodes/mod.rs index 1c26ba4..1468eea 100644 --- a/src/nodes/mod.rs +++ b/src/nodes/mod.rs @@ -133,8 +133,12 @@ impl Node { node.add_local_signal("destroy", Node::destroy_flex); node } - pub fn add_to_scenegraph(self) -> Arc { - self.get_client().unwrap().scenegraph.add_node(self) + pub fn add_to_scenegraph(self) -> Result> { + Ok(self + .get_client() + .ok_or_else(|| eyre!("Internal: Unable to get client"))? + .scenegraph + .add_node(self)) } pub fn destroy(&self) { if let Some(client) = self.get_client() { diff --git a/src/nodes/root.rs b/src/nodes/root.rs index 7e1d567..523a991 100644 --- a/src/nodes/root.rs +++ b/src/nodes/root.rs @@ -17,11 +17,11 @@ pub struct Root { logic_step: AtomicBool, } impl Root { - pub fn create(client: &Arc) -> Arc { + pub fn create(client: &Arc) -> Result> { let node = Node::create(client, "", "", false); node.add_local_signal("subscribe_logic_step", Root::subscribe_logic_step); node.add_local_signal("set_base_prefixes", Root::set_base_prefixes); - let node = node.add_to_scenegraph(); + let node = node.add_to_scenegraph()?; let _ = Spatial::add_to( &node, None, @@ -33,10 +33,10 @@ impl Root { false, ); - ROOT_REGISTRY.add(Root { + Ok(ROOT_REGISTRY.add(Root { node, logic_step: AtomicBool::from(false), - }) + })) } fn subscribe_logic_step(_node: &Node, calling_client: Arc, _data: &[u8]) -> Result<()> { diff --git a/src/nodes/spatial/mod.rs b/src/nodes/spatial/mod.rs index 5d59ffb..fa3e067 100644 --- a/src/nodes/spatial/mod.rs +++ b/src/nodes/spatial/mod.rs @@ -345,11 +345,11 @@ pub fn find_reference_space( find_spatial(calling_client, "Reference space", node_path) } -pub fn create_interface(client: &Arc) { +pub fn create_interface(client: &Arc) -> Result<()> { let node = Node::create(client, "", "spatial", false); node.add_local_signal("create_spatial", create_spatial_flex); node.add_local_signal("create_zone", create_zone_flex); - node.add_to_scenegraph(); + node.add_to_scenegraph().map(|_| ()) } pub fn create_spatial_flex(_node: &Node, calling_client: Arc, data: &[u8]) -> Result<()> { @@ -364,7 +364,7 @@ pub fn create_spatial_flex(_node: &Node, calling_client: Arc, data: &[u8 let node = Node::create(&calling_client, "/spatial/spatial", info.name, true); 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(); + let node = node.add_to_scenegraph()?; Spatial::add_to(&node, Some(parent), transform, info.zoneable)?; Ok(()) } diff --git a/src/nodes/spatial/zone.rs b/src/nodes/spatial/zone.rs index fb9e886..3faf906 100644 --- a/src/nodes/spatial/zone.rs +++ b/src/nodes/spatial/zone.rs @@ -122,7 +122,8 @@ impl Zone { local_methods: vec!["get_transform"], ..Default::default() }, - )?; + ) + .ok()?; Some((zoneable.uid.clone(), alias)) }) .collect::>>(); @@ -160,7 +161,8 @@ pub fn create_zone_flex(_node: &Node, calling_client: Arc, data: &[u8]) let transform = parse_transform(info.transform, true, true, false); let field = find_field(&calling_client, info.field_path)?; - let node = Node::create(&calling_client, "/spatial/zone", info.name, true).add_to_scenegraph(); + let node = + Node::create(&calling_client, "/spatial/zone", info.name, true).add_to_scenegraph()?; let space = Spatial::add_to(&node, Some(parent), transform, false)?; Zone::add_to(&node, space, &field); Ok(()) diff --git a/src/nodes/startup.rs b/src/nodes/startup.rs index 9ea2381..a549eab 100644 --- a/src/nodes/startup.rs +++ b/src/nodes/startup.rs @@ -26,9 +26,9 @@ pub struct StartupSettings { } impl StartupSettings { pub fn add_to(node: &Arc) { - node.startup_settings - .set(Mutex::new(StartupSettings::default())) - .unwrap(); + let _ = node + .startup_settings + .set(Mutex::new(StartupSettings::default())); } fn set_root_flex(node: &Node, calling_client: Arc, data: &[u8]) -> Result<()> { @@ -83,10 +83,10 @@ impl Debug for StartupSettings { } } -pub fn create_interface(client: &Arc) { +pub fn create_interface(client: &Arc) -> Result<()> { let node = Node::create(client, "", "startup", false); node.add_local_signal("create_startup_settings", create_startup_settings_flex); - node.add_to_scenegraph(); + node.add_to_scenegraph().map(|_| ()) } pub fn create_startup_settings_flex( @@ -95,7 +95,8 @@ pub fn create_startup_settings_flex( data: &[u8], ) -> Result<()> { let name = flexbuffers::Reader::get_root(data)?.get_str()?; - let node = Node::create(&calling_client, "/startup/settings", name, true).add_to_scenegraph(); + let node = + Node::create(&calling_client, "/startup/settings", name, true).add_to_scenegraph()?; StartupSettings::add_to(&node); node.add_local_signal("set_root", StartupSettings::set_root_flex); diff --git a/src/objects/input/mouse_pointer.rs b/src/objects/input/mouse_pointer.rs index 1cb5cf2..8597042 100644 --- a/src/objects/input/mouse_pointer.rs +++ b/src/objects/input/mouse_pointer.rs @@ -8,6 +8,7 @@ use crate::{ Node, }, }; +use color_eyre::eyre::Result; use glam::{vec3, Mat4}; use nanoid::nanoid; use stardust_xr::{schemas::flat::Datamap, values::Transform}; @@ -24,8 +25,8 @@ pub struct MousePointer { keyboard_sender: Arc, } impl MousePointer { - pub fn new() -> Self { - let node = Node::create(&INTERNAL_CLIENT, "", &nanoid!(), false).add_to_scenegraph(); + pub fn new() -> Result { + let node = Node::create(&INTERNAL_CLIENT, "", &nanoid!(), false).add_to_scenegraph()?; let spatial = Spatial::add_to(&node, None, Mat4::IDENTITY, false).unwrap(); let pointer = InputMethod::add_to(&node, InputType::Pointer(Pointer::default()), None).unwrap(); @@ -39,12 +40,12 @@ impl MousePointer { }; let keyboard_sender = PulseSender::add_to(&node, keyboard_mask).unwrap(); - MousePointer { + Ok(MousePointer { node, spatial, pointer, keyboard_sender, - } + }) } #[instrument(level = "debug", name = "Update Flatscreen Pointer Ray", skip_all)] pub fn update(&self, sk: &impl StereoKitInput) {