feat: Start converting method calls to async
This commit is contained in:
@@ -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<OwnedFd>,
|
||||
) -> 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<OwnedFd>,
|
||||
) -> Result<(Vec<u8>, Vec<OwnedFd>), 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))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Client>, Message) -> Result<()>;
|
||||
pub type Method = fn(&Node, Arc<Client>, Message) -> Result<Message>;
|
||||
pub type Method = fn(
|
||||
&Node,
|
||||
Arc<Client>,
|
||||
Message,
|
||||
) -> Pin<Box<dyn Future<Output = Result<Message>> + Send + Sync + 'static>>;
|
||||
|
||||
pub struct Node {
|
||||
pub enabled: Arc<AtomicBool>,
|
||||
@@ -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<F: Future<Output = Result<Message>> + Send + Sync + 'static>(
|
||||
&self,
|
||||
name: &str,
|
||||
method: fn(&Node, Arc<Client>, Message) -> F,
|
||||
) {
|
||||
self.local_methods
|
||||
.insert(name.to_string(), |node, calling_client, message| {
|
||||
Box::Pin(method(node, calling_client, message))
|
||||
});
|
||||
}
|
||||
|
||||
pub fn get_aspect<F, T>(
|
||||
@@ -229,7 +243,8 @@ impl Node {
|
||||
})
|
||||
}
|
||||
}
|
||||
pub fn execute_local_method(
|
||||
#[async_recursion]
|
||||
pub async fn execute_local_method(
|
||||
&self,
|
||||
calling_client: Arc<Client>,
|
||||
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)]
|
||||
|
||||
Reference in New Issue
Block a user