diff --git a/Cargo.lock b/Cargo.lock index d37e251..3b5a79d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -38,21 +38,6 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "250f629c0161ad8107cf89319e990051fae62832fd343083bea452d93e2205fd" -[[package]] -name = "android-tzdata" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" - -[[package]] -name = "android_system_properties" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" -dependencies = [ - "libc", -] - [[package]] name = "angle" version = "0.5.0" @@ -154,10 +139,21 @@ dependencies = [ ] [[package]] -name = "async-trait" -version = "0.1.72" +name = "async-recursion" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc6dde6e4ed435a4c1ee4e73592f5ba9da2151af10076cc04858746af9352d09" +checksum = "0e97ce7de6cf12de5d7226c73f5ba9811622f4db3a5b91b55c53e987e5f91cba" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.28", +] + +[[package]] +name = "async-trait" +version = "0.1.73" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" dependencies = [ "proc-macro2", "quote", @@ -287,12 +283,6 @@ version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42" -[[package]] -name = "bumpalo" -version = "3.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" - [[package]] name = "bytemuck" version = "1.13.1" @@ -370,21 +360,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "chrono" -version = "0.4.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5" -dependencies = [ - "android-tzdata", - "iana-time-zone", - "js-sys", - "num-traits", - "time", - "wasm-bindgen", - "winapi", -] - [[package]] name = "clang-sys" version = "1.6.1" @@ -534,12 +509,6 @@ dependencies = [ "tracing-subscriber", ] -[[package]] -name = "core-foundation-sys" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" - [[package]] name = "crc32fast" version = "1.3.2" @@ -895,7 +864,7 @@ checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" dependencies = [ "cfg-if", "libc", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi", ] [[package]] @@ -1097,29 +1066,6 @@ dependencies = [ "tokio-io-timeout", ] -[[package]] -name = "iana-time-zone" -version = "0.1.57" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fad5b825842d2b38bd206f3e81d6957625fd7f0a361e345c30e01a0ae2dd613" -dependencies = [ - "android_system_properties", - "core-foundation-sys", - "iana-time-zone-haiku", - "js-sys", - "wasm-bindgen", - "windows", -] - -[[package]] -name = "iana-time-zone-haiku" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" -dependencies = [ - "cc", -] - [[package]] name = "indenter" version = "0.3.3" @@ -1192,15 +1138,6 @@ version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" -[[package]] -name = "js-sys" -version = "0.3.64" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" -dependencies = [ - "wasm-bindgen", -] - [[package]] name = "khronos_api" version = "3.1.0" @@ -1364,7 +1301,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" dependencies = [ "libc", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi", "windows-sys", ] @@ -2098,10 +2035,8 @@ dependencies = [ [[package]] name = "stardust-xr" version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f493d5557c543404778beeba7051bc7bf537541b91cbd2b67983515675acba8" dependencies = [ - "chrono", + "async-trait", "cluFlock", "color-rs", "dirs", @@ -2119,8 +2054,6 @@ dependencies = [ [[package]] name = "stardust-xr-schemas" version = "1.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd65a40d6e6e8dc993ea9832666cf4cdc09c1a329f38b48ec9704af26cba229b" dependencies = [ "flatbuffers", "flexbuffers", @@ -2137,6 +2070,8 @@ dependencies = [ name = "stardust-xr-server" version = "0.42.1" dependencies = [ + "async-recursion", + "async-trait", "atty", "clap", "color-eyre", @@ -2277,17 +2212,6 @@ dependencies = [ "once_cell", ] -[[package]] -name = "time" -version = "0.1.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" -dependencies = [ - "libc", - "wasi 0.10.0+wasi-snapshot-preview1", - "winapi", -] - [[package]] name = "tokio" version = "1.29.1" @@ -2550,72 +2474,12 @@ dependencies = [ "try-lock", ] -[[package]] -name = "wasi" -version = "0.10.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" - [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" -[[package]] -name = "wasm-bindgen" -version = "0.2.87" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" -dependencies = [ - "cfg-if", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.87" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" -dependencies = [ - "bumpalo", - "log", - "once_cell", - "proc-macro2", - "quote", - "syn 2.0.28", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.87" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.87" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.28", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.87" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" - [[package]] name = "wayland-backend" version = "0.1.2" @@ -2747,15 +2611,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -[[package]] -name = "windows" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" -dependencies = [ - "windows-targets", -] - [[package]] name = "windows-sys" version = "0.48.0" diff --git a/Cargo.toml b/Cargo.toml index 3397e1f..051b23d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -60,6 +60,8 @@ tracing-subscriber = { version = "0.3.17", features = ["env-filter"] } global_counter = "0.2.2" rand = "0.8.5" atty = "0.2.14" +async-trait = "0.1.73" +async-recursion = "1.0.4" [dependencies.stereokit] default-features = false @@ -87,7 +89,7 @@ optional = true # path = "../stereokit-rs" # [patch.crates-io.stereokit-sys] # path = "../stereokit-sys" -# [patch.crates-io.stardust-xr] -# path = "../core/core" +[patch.crates-io.stardust-xr] +path = "../core/core" # [patch.crates-io.stardust-xr-schemas] # path = "../core/schemas" diff --git a/src/core/scenegraph.rs b/src/core/scenegraph.rs index a8dd85b..3fc7b33 100644 --- a/src/core/scenegraph.rs +++ b/src/core/scenegraph.rs @@ -1,5 +1,6 @@ use crate::nodes::Node; use crate::{core::client::Client, nodes::Message}; +use async_trait::async_trait; use color_eyre::eyre::Result; use once_cell::sync::OnceCell; use stardust_xr::scenegraph; @@ -50,6 +51,7 @@ impl Scenegraph { } } +#[async_trait] impl scenegraph::Scenegraph for Scenegraph { fn send_signal( &self, @@ -58,7 +60,9 @@ impl scenegraph::Scenegraph for Scenegraph { data: &[u8], fds: Vec, ) -> Result<(), ScenegraphError> { - let Some(client) = self.get_client() else {return Err(ScenegraphError::SignalNotFound)}; + 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)? @@ -72,27 +76,29 @@ impl scenegraph::Scenegraph for Scenegraph { ) }) } - fn execute_method( + async fn execute_method( &self, path: &str, method: &str, data: &[u8], fds: Vec, ) -> Result<(Vec, Vec), ScenegraphError> { - let Some(client) = self.get_client() else {return Err(ScenegraphError::MethodNotFound)}; - debug_span!("Handle method", path, method).in_scope(|| { - let message = self - .get_node(path) - .ok_or(ScenegraphError::NodeNotFound)? - .execute_local_method( - client, - method, - Message { - data: data.to_vec(), - fds, - }, - )?; - Ok((message.data, message.fds)) - }) + let Some(client) = self.get_client() else { + return Err(ScenegraphError::MethodNotFound); + }; + debug!(path, method, "Handle method"); + let message = self + .get_node(path) + .ok_or(ScenegraphError::NodeNotFound)? + .execute_local_method( + client, + method, + Message { + data: data.to_vec(), + fds, + }, + ) + .await?; + Ok((message.data, message.fds)) } } diff --git a/src/nodes/mod.rs b/src/nodes/mod.rs index 3bd719f..193eb69 100644 --- a/src/nodes/mod.rs +++ b/src/nodes/mod.rs @@ -10,6 +10,7 @@ pub mod root; pub mod spatial; pub mod startup; +use async_recursion::async_recursion; use color_eyre::eyre::{eyre, Result}; use core::hash::BuildHasherDefault; use dashmap::DashMap; @@ -22,7 +23,9 @@ use stardust_xr::messenger::MessageSenderHandle; use stardust_xr::scenegraph::ScenegraphError; use stardust_xr::schemas::flex::deserialize; use std::fmt::Debug; +use std::future::Future; use std::os::fd::OwnedFd; +use std::pin::Pin; use std::sync::{Arc, Weak}; use std::vec::Vec; use tracing::{debug_span, instrument}; @@ -60,7 +63,11 @@ impl AsRef<[u8]> for Message { } pub type Signal = fn(&Node, Arc, Message) -> Result<()>; -pub type Method = fn(&Node, Arc, Message) -> Result; +pub type Method = fn( + &Node, + Arc, + Message, +) -> Pin> + Send + Sync + 'static>>; pub struct Node { pub enabled: Arc, @@ -186,8 +193,15 @@ impl Node { pub fn add_local_signal(&self, name: &str, signal: Signal) { self.local_signals.insert(name.to_string(), signal); } - pub fn add_local_method(&self, name: &str, method: Method) { - self.local_methods.insert(name.to_string(), method); + pub fn add_local_method> + Send + Sync + 'static>( + &self, + name: &str, + method: fn(&Node, Arc, Message) -> F, + ) { + self.local_methods + .insert(name.to_string(), |node, calling_client, message| { + Box::Pin(method(node, calling_client, message)) + }); } pub fn get_aspect( @@ -229,7 +243,8 @@ impl Node { }) } } - pub fn execute_local_method( + #[async_recursion] + pub async fn execute_local_method( &self, calling_client: Arc, method: &str, @@ -251,19 +266,18 @@ impl Node { fds: Vec::new(), }, ) + .await } else { let method = self .local_methods .get(method) .ok_or(ScenegraphError::MethodNotFound)?; - debug_span!("Handle method").in_scope(|| { - method(self, calling_client, message).map_err(|error| { - ScenegraphError::MethodError { - error: error.to_string(), - } + method(self, calling_client, message) + .await + .map_err(|error| ScenegraphError::MethodError { + error: error.to_string(), }) - }) } } #[instrument(level = "debug", skip_all)]