feat: async methods
This commit is contained in:
20
Cargo.lock
generated
20
Cargo.lock
generated
@@ -138,17 +138,6 @@ dependencies = [
|
|||||||
"num-traits",
|
"num-traits",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "async-recursion"
|
|
||||||
version = "1.0.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "0e97ce7de6cf12de5d7226c73f5ba9811622f4db3a5b91b55c53e987e5f91cba"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn 2.0.28",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "async-trait"
|
name = "async-trait"
|
||||||
version = "0.1.73"
|
version = "0.1.73"
|
||||||
@@ -2034,9 +2023,10 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "stardust-xr"
|
name = "stardust-xr"
|
||||||
version = "0.13.0"
|
version = "0.14.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "996e151a9271144684a8ccb1d23d2949c5590bc37c4a12119d4f72f64462307e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
|
||||||
"cluFlock",
|
"cluFlock",
|
||||||
"color-rs",
|
"color-rs",
|
||||||
"dirs",
|
"dirs",
|
||||||
@@ -2054,6 +2044,8 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "stardust-xr-schemas"
|
name = "stardust-xr-schemas"
|
||||||
version = "1.5.1"
|
version = "1.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bd65a40d6e6e8dc993ea9832666cf4cdc09c1a329f38b48ec9704af26cba229b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"flatbuffers",
|
"flatbuffers",
|
||||||
"flexbuffers",
|
"flexbuffers",
|
||||||
@@ -2070,8 +2062,6 @@ dependencies = [
|
|||||||
name = "stardust-xr-server"
|
name = "stardust-xr-server"
|
||||||
version = "0.42.1"
|
version = "0.42.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-recursion",
|
|
||||||
"async-trait",
|
|
||||||
"atty",
|
"atty",
|
||||||
"clap",
|
"clap",
|
||||||
"color-eyre",
|
"color-eyre",
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ tokio = { version = "1.27.0", features = ["rt-multi-thread", "signal"] }
|
|||||||
send_wrapper = "0.6.0"
|
send_wrapper = "0.6.0"
|
||||||
prisma = "0.1.1"
|
prisma = "0.1.1"
|
||||||
xkbcommon = { version = "0.5.0", default-features = false, optional = true }
|
xkbcommon = { version = "0.5.0", default-features = false, optional = true }
|
||||||
stardust-xr = "0.13.0"
|
stardust-xr = "0.14.0"
|
||||||
directories = "5.0.0"
|
directories = "5.0.0"
|
||||||
serde = { version = "1.0.160", features = ["derive"] }
|
serde = { version = "1.0.160", features = ["derive"] }
|
||||||
tracing = "0.1.37"
|
tracing = "0.1.37"
|
||||||
@@ -60,8 +60,6 @@ tracing-subscriber = { version = "0.3.17", features = ["env-filter"] }
|
|||||||
global_counter = "0.2.2"
|
global_counter = "0.2.2"
|
||||||
rand = "0.8.5"
|
rand = "0.8.5"
|
||||||
atty = "0.2.14"
|
atty = "0.2.14"
|
||||||
async-trait = "0.1.73"
|
|
||||||
async-recursion = "1.0.4"
|
|
||||||
|
|
||||||
[dependencies.stereokit]
|
[dependencies.stereokit]
|
||||||
default-features = false
|
default-features = false
|
||||||
@@ -89,7 +87,7 @@ optional = true
|
|||||||
# path = "../stereokit-rs"
|
# path = "../stereokit-rs"
|
||||||
# [patch.crates-io.stereokit-sys]
|
# [patch.crates-io.stereokit-sys]
|
||||||
# path = "../stereokit-sys"
|
# path = "../stereokit-sys"
|
||||||
[patch.crates-io.stardust-xr]
|
# [patch.crates-io.stardust-xr]
|
||||||
path = "../core/core"
|
# path = "../core/core"
|
||||||
# [patch.crates-io.stardust-xr-schemas]
|
# [patch.crates-io.stardust-xr-schemas]
|
||||||
# path = "../core/schemas"
|
# path = "../core/schemas"
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
use crate::nodes::Node;
|
use crate::nodes::Node;
|
||||||
use crate::{core::client::Client, nodes::Message};
|
use crate::{core::client::Client, nodes::Message};
|
||||||
use async_trait::async_trait;
|
|
||||||
use color_eyre::eyre::Result;
|
use color_eyre::eyre::Result;
|
||||||
use once_cell::sync::OnceCell;
|
use once_cell::sync::OnceCell;
|
||||||
use stardust_xr::scenegraph;
|
use stardust_xr::scenegraph;
|
||||||
use stardust_xr::scenegraph::ScenegraphError;
|
use stardust_xr::scenegraph::ScenegraphError;
|
||||||
use std::os::fd::OwnedFd;
|
use std::os::fd::OwnedFd;
|
||||||
use std::sync::{Arc, Weak};
|
use std::sync::{Arc, Weak};
|
||||||
|
use tokio::sync::oneshot;
|
||||||
use tracing::{debug, debug_span, instrument};
|
use tracing::{debug, debug_span, instrument};
|
||||||
|
|
||||||
use core::hash::BuildHasherDefault;
|
use core::hash::BuildHasherDefault;
|
||||||
@@ -51,7 +51,17 @@ impl Scenegraph {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
pub struct MethodResponseSender(oneshot::Sender<Result<(Vec<u8>, Vec<OwnedFd>), ScenegraphError>>);
|
||||||
|
impl MethodResponseSender {
|
||||||
|
pub fn send(self, t: Result<Message, ScenegraphError>) {
|
||||||
|
let _ = self.0.send(t.map(|m| (m.data, m.fds)));
|
||||||
|
}
|
||||||
|
pub fn wrap_sync<F: FnOnce() -> color_eyre::eyre::Result<Message>>(self, f: F) {
|
||||||
|
self.send(f().map_err(|e| ScenegraphError::MethodError {
|
||||||
|
error: e.to_string(),
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
}
|
||||||
impl scenegraph::Scenegraph for Scenegraph {
|
impl scenegraph::Scenegraph for Scenegraph {
|
||||||
fn send_signal(
|
fn send_signal(
|
||||||
&self,
|
&self,
|
||||||
@@ -76,29 +86,31 @@ impl scenegraph::Scenegraph for Scenegraph {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
async fn execute_method(
|
fn execute_method(
|
||||||
&self,
|
&self,
|
||||||
path: &str,
|
path: &str,
|
||||||
method: &str,
|
method: &str,
|
||||||
data: &[u8],
|
data: &[u8],
|
||||||
fds: Vec<OwnedFd>,
|
fds: Vec<OwnedFd>,
|
||||||
) -> Result<(Vec<u8>, Vec<OwnedFd>), ScenegraphError> {
|
response: oneshot::Sender<Result<(Vec<u8>, Vec<OwnedFd>), ScenegraphError>>,
|
||||||
|
) {
|
||||||
let Some(client) = self.get_client() else {
|
let Some(client) = self.get_client() else {
|
||||||
return Err(ScenegraphError::MethodNotFound);
|
let _ = response.send(Err(ScenegraphError::MethodNotFound));
|
||||||
|
return;
|
||||||
};
|
};
|
||||||
debug!(path, method, "Handle method");
|
debug!(path, method, "Handle method");
|
||||||
let message = self
|
let Some(node) = self.get_node(path) else {
|
||||||
.get_node(path)
|
let _ = response.send(Err(ScenegraphError::NodeNotFound));
|
||||||
.ok_or(ScenegraphError::NodeNotFound)?
|
return;
|
||||||
.execute_local_method(
|
};
|
||||||
client,
|
node.execute_local_method(
|
||||||
method,
|
client,
|
||||||
Message {
|
method,
|
||||||
data: data.to_vec(),
|
Message {
|
||||||
fds,
|
data: data.to_vec(),
|
||||||
},
|
fds,
|
||||||
)
|
},
|
||||||
.await?;
|
MethodResponseSender(response),
|
||||||
Ok((message.data, message.fds))
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ use super::alias::AliasInfo;
|
|||||||
use super::spatial::Spatial;
|
use super::spatial::Spatial;
|
||||||
use super::{Message, Node};
|
use super::{Message, Node};
|
||||||
use crate::core::client::Client;
|
use crate::core::client::Client;
|
||||||
|
use crate::core::scenegraph::MethodResponseSender;
|
||||||
use crate::nodes::spatial::find_reference_space;
|
use crate::nodes::spatial::find_reference_space;
|
||||||
use color_eyre::eyre::Result;
|
use color_eyre::eyre::Result;
|
||||||
use glam::{vec2, vec3a, Vec3, Vec3A};
|
use glam::{vec2, vec3a, Vec3, Vec3A};
|
||||||
@@ -137,82 +138,94 @@ fn field_distance_flex(
|
|||||||
node: &Node,
|
node: &Node,
|
||||||
calling_client: Arc<Client>,
|
calling_client: Arc<Client>,
|
||||||
message: Message,
|
message: Message,
|
||||||
) -> Result<Message> {
|
response: MethodResponseSender,
|
||||||
#[derive(Deserialize)]
|
) {
|
||||||
struct FieldInfoArgs<'a> {
|
response.wrap_sync(move || {
|
||||||
reference_space_path: &'a str,
|
#[derive(Deserialize)]
|
||||||
point: Vector3<f32>,
|
struct FieldInfoArgs<'a> {
|
||||||
}
|
reference_space_path: &'a str,
|
||||||
let args: FieldInfoArgs = deserialize(message.as_ref())?;
|
point: Vector3<f32>,
|
||||||
let reference_space = find_reference_space(&calling_client, args.reference_space_path)?;
|
}
|
||||||
|
let args: FieldInfoArgs = deserialize(message.as_ref())?;
|
||||||
|
let reference_space = find_reference_space(&calling_client, args.reference_space_path)?;
|
||||||
|
|
||||||
let distance = node
|
let distance = node
|
||||||
.field
|
.field
|
||||||
.get()
|
.get()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.distance(reference_space.as_ref(), args.point.into());
|
.distance(reference_space.as_ref(), args.point.into());
|
||||||
Ok(serialize(distance)?.into())
|
Ok(serialize(distance)?.into())
|
||||||
|
});
|
||||||
}
|
}
|
||||||
fn field_normal_flex(
|
fn field_normal_flex(
|
||||||
node: &Node,
|
node: &Node,
|
||||||
calling_client: Arc<Client>,
|
calling_client: Arc<Client>,
|
||||||
message: Message,
|
message: Message,
|
||||||
) -> Result<Message> {
|
response: MethodResponseSender,
|
||||||
#[derive(Deserialize)]
|
) {
|
||||||
struct FieldInfoArgs<'a> {
|
response.wrap_sync(move || {
|
||||||
reference_space_path: &'a str,
|
#[derive(Deserialize)]
|
||||||
point: Vector3<f32>,
|
struct FieldInfoArgs<'a> {
|
||||||
}
|
reference_space_path: &'a str,
|
||||||
let args: FieldInfoArgs = deserialize(message.as_ref())?;
|
point: Vector3<f32>,
|
||||||
let reference_space = find_reference_space(&calling_client, args.reference_space_path)?;
|
}
|
||||||
|
let args: FieldInfoArgs = deserialize(message.as_ref())?;
|
||||||
|
let reference_space = find_reference_space(&calling_client, args.reference_space_path)?;
|
||||||
|
|
||||||
let normal = node.field.get().as_ref().unwrap().normal(
|
let normal = node.field.get().as_ref().unwrap().normal(
|
||||||
reference_space.as_ref(),
|
reference_space.as_ref(),
|
||||||
args.point.into(),
|
args.point.into(),
|
||||||
0.001,
|
0.001,
|
||||||
);
|
);
|
||||||
Ok(serialize(mint::Vector3::from(normal))?.into())
|
Ok(serialize(mint::Vector3::from(normal))?.into())
|
||||||
|
});
|
||||||
}
|
}
|
||||||
fn field_closest_point_flex(
|
fn field_closest_point_flex(
|
||||||
node: &Node,
|
node: &Node,
|
||||||
calling_client: Arc<Client>,
|
calling_client: Arc<Client>,
|
||||||
message: Message,
|
message: Message,
|
||||||
) -> Result<Message> {
|
response: MethodResponseSender,
|
||||||
#[derive(Deserialize)]
|
) {
|
||||||
struct FieldInfoArgs<'a> {
|
response.wrap_sync(move || {
|
||||||
reference_space_path: &'a str,
|
#[derive(Deserialize)]
|
||||||
point: Vector3<f32>,
|
struct FieldInfoArgs<'a> {
|
||||||
}
|
reference_space_path: &'a str,
|
||||||
let args: FieldInfoArgs = deserialize(message.as_ref())?;
|
point: Vector3<f32>,
|
||||||
let reference_space = find_reference_space(&calling_client, args.reference_space_path)?;
|
}
|
||||||
|
let args: FieldInfoArgs = deserialize(message.as_ref())?;
|
||||||
|
let reference_space = find_reference_space(&calling_client, args.reference_space_path)?;
|
||||||
|
|
||||||
let closest_point = node.field.get().as_ref().unwrap().closest_point(
|
let closest_point = node.field.get().as_ref().unwrap().closest_point(
|
||||||
reference_space.as_ref(),
|
reference_space.as_ref(),
|
||||||
args.point.into(),
|
args.point.into(),
|
||||||
0.001,
|
0.001,
|
||||||
);
|
);
|
||||||
Ok(serialize(mint::Vector3::from(closest_point))?.into())
|
Ok(serialize(mint::Vector3::from(closest_point))?.into())
|
||||||
|
});
|
||||||
}
|
}
|
||||||
fn field_ray_march_flex(
|
fn field_ray_march_flex(
|
||||||
node: &Node,
|
node: &Node,
|
||||||
calling_client: Arc<Client>,
|
calling_client: Arc<Client>,
|
||||||
message: Message,
|
message: Message,
|
||||||
) -> Result<Message> {
|
response: MethodResponseSender,
|
||||||
#[derive(Deserialize)]
|
) {
|
||||||
struct FieldInfoArgs<'a> {
|
response.wrap_sync(move || {
|
||||||
reference_space_path: &'a str,
|
#[derive(Deserialize)]
|
||||||
ray_origin: Vector3<f32>,
|
struct FieldInfoArgs<'a> {
|
||||||
ray_direction: Vector3<f32>,
|
reference_space_path: &'a str,
|
||||||
}
|
ray_origin: Vector3<f32>,
|
||||||
let args: FieldInfoArgs = deserialize(message.as_ref())?;
|
ray_direction: Vector3<f32>,
|
||||||
let reference_space = find_reference_space(&calling_client, args.reference_space_path)?;
|
}
|
||||||
|
let args: FieldInfoArgs = deserialize(message.as_ref())?;
|
||||||
|
let reference_space = find_reference_space(&calling_client, args.reference_space_path)?;
|
||||||
|
|
||||||
let ray_march_result = node.field.get().unwrap().ray_march(Ray {
|
let ray_march_result = node.field.get().unwrap().ray_march(Ray {
|
||||||
origin: args.ray_origin.into(),
|
origin: args.ray_origin.into(),
|
||||||
direction: args.ray_direction.into(),
|
direction: args.ray_direction.into(),
|
||||||
space: reference_space,
|
space: reference_space,
|
||||||
|
});
|
||||||
|
Ok(serialize(ray_march_result)?.into())
|
||||||
});
|
});
|
||||||
Ok(serialize(ray_march_result)?.into())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum Field {
|
pub enum Field {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ use crate::{
|
|||||||
core::{
|
core::{
|
||||||
client::{Client, INTERNAL_CLIENT},
|
client::{Client, INTERNAL_CLIENT},
|
||||||
registry::Registry,
|
registry::Registry,
|
||||||
|
scenegraph::MethodResponseSender,
|
||||||
},
|
},
|
||||||
nodes::{
|
nodes::{
|
||||||
drawable::{model::ModelPart, shaders::UNLIT_SHADER_BYTES, Drawable},
|
drawable::{model::ModelPart, shaders::UNLIT_SHADER_BYTES, Drawable},
|
||||||
@@ -11,7 +12,7 @@ use crate::{
|
|||||||
Message, Node,
|
Message, Node,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use color_eyre::eyre::{bail, Result};
|
use color_eyre::eyre::{bail, eyre, Result};
|
||||||
use glam::Mat4;
|
use glam::Mat4;
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use mint::{RowMatrix4, Vector2};
|
use mint::{RowMatrix4, Vector2};
|
||||||
@@ -31,7 +32,7 @@ use stereokit::{
|
|||||||
lazy_static! {
|
lazy_static! {
|
||||||
pub(super) static ref ITEM_TYPE_INFO_CAMERA: TypeInfo = TypeInfo {
|
pub(super) static ref ITEM_TYPE_INFO_CAMERA: TypeInfo = TypeInfo {
|
||||||
type_name: "camera",
|
type_name: "camera",
|
||||||
aliased_local_signals: vec!["frame"],
|
aliased_local_signals: vec!["apply_preview_material", "frame"],
|
||||||
aliased_local_methods: vec![],
|
aliased_local_methods: vec![],
|
||||||
aliased_remote_signals: vec![],
|
aliased_remote_signals: vec![],
|
||||||
ui: Default::default(),
|
ui: Default::default(),
|
||||||
@@ -71,19 +72,26 @@ impl CameraItem {
|
|||||||
apply_to: Registry::new(),
|
apply_to: Registry::new(),
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
// node.add_local_method("frame", CameraItem::frame_flex);
|
node.add_local_method("frame", CameraItem::frame_flex);
|
||||||
node.add_local_signal(
|
node.add_local_signal(
|
||||||
"apply_preview_material",
|
"apply_preview_material",
|
||||||
CameraItem::apply_preview_material_flex,
|
CameraItem::apply_preview_material_flex,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// fn frame_flex(node: &Node, _calling_client: Arc<Client>, message: Message) -> Result<Message> {
|
fn frame_flex(
|
||||||
// let ItemType::Camera(camera) = &node.item.get().unwrap().specialization else {
|
node: &Node,
|
||||||
// return Err(eyre!("Wrong item type?"))
|
_calling_client: Arc<Client>,
|
||||||
// };
|
_message: Message,
|
||||||
// Ok(serialize(())?.into())
|
response: MethodResponseSender,
|
||||||
// }
|
) {
|
||||||
|
response.wrap_sync(move || {
|
||||||
|
let ItemType::Camera(_camera) = &node.item.get().unwrap().specialization else {
|
||||||
|
return Err(eyre!("Wrong item type?"))
|
||||||
|
};
|
||||||
|
Ok(serialize(())?.into())
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
fn apply_preview_material_flex(
|
fn apply_preview_material_flex(
|
||||||
node: &Node,
|
node: &Node,
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ use crate::{
|
|||||||
core::{
|
core::{
|
||||||
client::{Client, INTERNAL_CLIENT},
|
client::{Client, INTERNAL_CLIENT},
|
||||||
registry::Registry,
|
registry::Registry,
|
||||||
|
scenegraph::MethodResponseSender,
|
||||||
},
|
},
|
||||||
nodes::{
|
nodes::{
|
||||||
items::TypeInfo,
|
items::TypeInfo,
|
||||||
@@ -50,11 +51,14 @@ impl EnvironmentItem {
|
|||||||
node: &Node,
|
node: &Node,
|
||||||
_calling_client: Arc<Client>,
|
_calling_client: Arc<Client>,
|
||||||
_message: Message,
|
_message: Message,
|
||||||
) -> Result<Message> {
|
response: MethodResponseSender,
|
||||||
let ItemType::Environment(environment_item) = &node.item.get().unwrap().specialization else {
|
) {
|
||||||
|
response.wrap_sync(move || {
|
||||||
|
let ItemType::Environment(environment_item) = &node.item.get().unwrap().specialization else {
|
||||||
return Err(eyre!("Wrong item type?"))
|
return Err(eyre!("Wrong item type?"))
|
||||||
};
|
};
|
||||||
Ok(serialize(environment_item.path.as_str())?.into())
|
Ok(serialize(environment_item.path.as_str())?.into())
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn serialize_start_data(&self, id: &str) -> Result<Message> {
|
pub fn serialize_start_data(&self, id: &str) -> Result<Message> {
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ pub mod root;
|
|||||||
pub mod spatial;
|
pub mod spatial;
|
||||||
pub mod startup;
|
pub mod startup;
|
||||||
|
|
||||||
use async_recursion::async_recursion;
|
|
||||||
use color_eyre::eyre::{eyre, Result};
|
use color_eyre::eyre::{eyre, Result};
|
||||||
use core::hash::BuildHasherDefault;
|
use core::hash::BuildHasherDefault;
|
||||||
use dashmap::DashMap;
|
use dashmap::DashMap;
|
||||||
@@ -23,15 +22,14 @@ use stardust_xr::messenger::MessageSenderHandle;
|
|||||||
use stardust_xr::scenegraph::ScenegraphError;
|
use stardust_xr::scenegraph::ScenegraphError;
|
||||||
use stardust_xr::schemas::flex::deserialize;
|
use stardust_xr::schemas::flex::deserialize;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::future::Future;
|
|
||||||
use std::os::fd::OwnedFd;
|
use std::os::fd::OwnedFd;
|
||||||
use std::pin::Pin;
|
|
||||||
use std::sync::{Arc, Weak};
|
use std::sync::{Arc, Weak};
|
||||||
use std::vec::Vec;
|
use std::vec::Vec;
|
||||||
use tracing::{debug_span, instrument};
|
use tracing::instrument;
|
||||||
|
|
||||||
use crate::core::client::Client;
|
use crate::core::client::Client;
|
||||||
use crate::core::registry::Registry;
|
use crate::core::registry::Registry;
|
||||||
|
use crate::core::scenegraph::MethodResponseSender;
|
||||||
|
|
||||||
use self::alias::Alias;
|
use self::alias::Alias;
|
||||||
use self::audio::Sound;
|
use self::audio::Sound;
|
||||||
@@ -63,11 +61,7 @@ impl AsRef<[u8]> for Message {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub type Signal = fn(&Node, Arc<Client>, Message) -> Result<()>;
|
pub type Signal = fn(&Node, Arc<Client>, Message) -> Result<()>;
|
||||||
pub type Method = fn(
|
pub type Method = fn(&Node, Arc<Client>, Message, MethodResponseSender);
|
||||||
&Node,
|
|
||||||
Arc<Client>,
|
|
||||||
Message,
|
|
||||||
) -> Pin<Box<dyn Future<Output = Result<Message>> + Send + Sync + 'static>>;
|
|
||||||
|
|
||||||
pub struct Node {
|
pub struct Node {
|
||||||
pub enabled: Arc<AtomicBool>,
|
pub enabled: Arc<AtomicBool>,
|
||||||
@@ -193,15 +187,8 @@ impl Node {
|
|||||||
pub fn add_local_signal(&self, name: &str, signal: Signal) {
|
pub fn add_local_signal(&self, name: &str, signal: Signal) {
|
||||||
self.local_signals.insert(name.to_string(), signal);
|
self.local_signals.insert(name.to_string(), signal);
|
||||||
}
|
}
|
||||||
pub fn add_local_method<F: Future<Output = Result<Message>> + Send + Sync + 'static>(
|
pub fn add_local_method(&self, name: &str, method: Method) {
|
||||||
&self,
|
self.local_methods.insert(name.to_string(), method);
|
||||||
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>(
|
pub fn get_aspect<F, T>(
|
||||||
@@ -243,41 +230,37 @@ impl Node {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[async_recursion]
|
pub fn execute_local_method(
|
||||||
pub async fn execute_local_method(
|
|
||||||
&self,
|
&self,
|
||||||
calling_client: Arc<Client>,
|
calling_client: Arc<Client>,
|
||||||
method: &str,
|
method: &str,
|
||||||
message: Message,
|
message: Message,
|
||||||
) -> Result<Message, ScenegraphError> {
|
response: MethodResponseSender,
|
||||||
|
) {
|
||||||
if let Some(alias) = self.alias.get() {
|
if let Some(alias) = self.alias.get() {
|
||||||
if !alias.info.server_methods.iter().any(|e| e == &method) {
|
if !alias.info.server_methods.iter().any(|e| e == &method) {
|
||||||
return Err(ScenegraphError::MethodNotFound);
|
response.send(Err(ScenegraphError::MethodNotFound));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
alias
|
let Some(alias) = alias.original.upgrade() else {
|
||||||
.original
|
response.send(Err(ScenegraphError::BrokenAlias));
|
||||||
.upgrade()
|
return;
|
||||||
.ok_or(ScenegraphError::BrokenAlias)?
|
};
|
||||||
.execute_local_method(
|
alias.execute_local_method(
|
||||||
calling_client,
|
calling_client,
|
||||||
method,
|
method,
|
||||||
Message {
|
Message {
|
||||||
data: message.data.clone(),
|
data: message.data.clone(),
|
||||||
fds: Vec::new(),
|
fds: Vec::new(),
|
||||||
},
|
},
|
||||||
)
|
response,
|
||||||
.await
|
)
|
||||||
} else {
|
} else {
|
||||||
let method = self
|
let Some(method) = self.local_methods.get(method) else {
|
||||||
.local_methods
|
response.send(Err(ScenegraphError::MethodNotFound));
|
||||||
.get(method)
|
return;
|
||||||
.ok_or(ScenegraphError::MethodNotFound)?;
|
};
|
||||||
|
method(self, calling_client, message, response);
|
||||||
method(self, calling_client, message)
|
|
||||||
.await
|
|
||||||
.map_err(|error| ScenegraphError::MethodError {
|
|
||||||
error: error.to_string(),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[instrument(level = "debug", skip_all)]
|
#[instrument(level = "debug", skip_all)]
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ use self::zone::{create_zone_flex, Zone};
|
|||||||
use super::{Message, Node};
|
use super::{Message, Node};
|
||||||
use crate::core::client::Client;
|
use crate::core::client::Client;
|
||||||
use crate::core::registry::Registry;
|
use crate::core::registry::Registry;
|
||||||
|
use crate::core::scenegraph::MethodResponseSender;
|
||||||
use color_eyre::eyre::{ensure, eyre, Result};
|
use color_eyre::eyre::{ensure, eyre, Result};
|
||||||
use glam::{vec3a, Mat4, Quat};
|
use glam::{vec3a, Mat4, Quat};
|
||||||
use mint::Vector3;
|
use mint::Vector3;
|
||||||
@@ -233,64 +234,71 @@ impl Spatial {
|
|||||||
node: &Node,
|
node: &Node,
|
||||||
calling_client: Arc<Client>,
|
calling_client: Arc<Client>,
|
||||||
message: Message,
|
message: Message,
|
||||||
) -> Result<Message> {
|
response: MethodResponseSender,
|
||||||
let this_spatial = node
|
) {
|
||||||
.spatial
|
response.wrap_sync(move || {
|
||||||
.get()
|
let this_spatial = node
|
||||||
.ok_or_else(|| eyre!("Node doesn't have a spatial?"))?;
|
.spatial
|
||||||
let relative_spatial_path: Option<&str> = deserialize(message.as_ref())?;
|
.get()
|
||||||
let bounds = if let Some(relative_spatial_path) = relative_spatial_path {
|
.ok_or_else(|| eyre!("Node doesn't have a spatial?"))?;
|
||||||
let relative_spatial = find_reference_space(&calling_client, relative_spatial_path)?;
|
let relative_spatial_path: Option<&str> = deserialize(message.as_ref())?;
|
||||||
let center =
|
let bounds = if let Some(relative_spatial_path) = relative_spatial_path {
|
||||||
Spatial::space_to_space_matrix(Some(&this_spatial), Some(&relative_spatial))
|
let relative_spatial =
|
||||||
.transform_point3([0.0; 3].into());
|
find_reference_space(&calling_client, relative_spatial_path)?;
|
||||||
let bounds: Bounds = Bounds {
|
let center =
|
||||||
center,
|
Spatial::space_to_space_matrix(Some(&this_spatial), Some(&relative_spatial))
|
||||||
dimensions: [0.0; 3].into(),
|
.transform_point3([0.0; 3].into());
|
||||||
|
let bounds: Bounds = Bounds {
|
||||||
|
center,
|
||||||
|
dimensions: [0.0; 3].into(),
|
||||||
|
};
|
||||||
|
bounds_grow_to_fit_box(
|
||||||
|
bounds,
|
||||||
|
this_spatial.get_bounding_box(),
|
||||||
|
Some(Spatial::space_to_space_matrix(
|
||||||
|
Some(&this_spatial),
|
||||||
|
Some(&relative_spatial),
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
this_spatial.get_bounding_box()
|
||||||
};
|
};
|
||||||
bounds_grow_to_fit_box(
|
|
||||||
bounds,
|
|
||||||
this_spatial.get_bounding_box(),
|
|
||||||
Some(Spatial::space_to_space_matrix(
|
|
||||||
Some(&this_spatial),
|
|
||||||
Some(&relative_spatial),
|
|
||||||
)),
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
this_spatial.get_bounding_box()
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(serialize((
|
Ok(serialize((
|
||||||
mint::Vector3::from(bounds.center),
|
mint::Vector3::from(bounds.center),
|
||||||
mint::Vector3::from(bounds.dimensions),
|
mint::Vector3::from(bounds.dimensions),
|
||||||
))?
|
))?
|
||||||
.into())
|
.into())
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_transform_flex(
|
pub fn get_transform_flex(
|
||||||
node: &Node,
|
node: &Node,
|
||||||
calling_client: Arc<Client>,
|
calling_client: Arc<Client>,
|
||||||
message: Message,
|
message: Message,
|
||||||
) -> Result<Message> {
|
response: MethodResponseSender,
|
||||||
let this_spatial = node
|
) {
|
||||||
.spatial
|
response.wrap_sync(move || {
|
||||||
.get()
|
let this_spatial = node
|
||||||
.ok_or_else(|| eyre!("Node doesn't have a spatial?"))?;
|
.spatial
|
||||||
let relative_spatial =
|
.get()
|
||||||
find_reference_space(&calling_client, deserialize(message.as_ref())?)?;
|
.ok_or_else(|| eyre!("Node doesn't have a spatial?"))?;
|
||||||
|
let relative_spatial =
|
||||||
|
find_reference_space(&calling_client, deserialize(message.as_ref())?)?;
|
||||||
|
|
||||||
let (scale, rotation, position) = Spatial::space_to_space_matrix(
|
let (scale, rotation, position) = Spatial::space_to_space_matrix(
|
||||||
Some(this_spatial.as_ref()),
|
Some(this_spatial.as_ref()),
|
||||||
Some(relative_spatial.as_ref()),
|
Some(relative_spatial.as_ref()),
|
||||||
)
|
)
|
||||||
.to_scale_rotation_translation();
|
.to_scale_rotation_translation();
|
||||||
|
|
||||||
Ok(serialize((
|
Ok(serialize((
|
||||||
mint::Vector3::from(position),
|
mint::Vector3::from(position),
|
||||||
mint::Quaternion::from(rotation),
|
mint::Quaternion::from(rotation),
|
||||||
mint::Vector3::from(scale),
|
mint::Vector3::from(scale),
|
||||||
))?
|
))?
|
||||||
.into())
|
.into())
|
||||||
|
});
|
||||||
}
|
}
|
||||||
pub fn set_transform_flex(
|
pub fn set_transform_flex(
|
||||||
node: &Node,
|
node: &Node,
|
||||||
@@ -354,70 +362,79 @@ impl Spatial {
|
|||||||
node: &Node,
|
node: &Node,
|
||||||
calling_client: Arc<Client>,
|
calling_client: Arc<Client>,
|
||||||
message: Message,
|
message: Message,
|
||||||
) -> Result<Message> {
|
response: MethodResponseSender,
|
||||||
let (point, fields): (Vector3<f32>, Vec<Option<&str>>) = deserialize(message.as_ref())?;
|
) {
|
||||||
let spatial = node.spatial.get().unwrap();
|
response.wrap_sync(move || {
|
||||||
|
let (point, fields): (Vector3<f32>, Vec<Option<&str>>) = deserialize(message.as_ref())?;
|
||||||
|
let spatial = node.spatial.get().unwrap();
|
||||||
|
|
||||||
let output = fields
|
let output = fields
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|f| {
|
.map(|f| {
|
||||||
calling_client
|
calling_client
|
||||||
.get_node("Field", f?)
|
.get_node("Field", f?)
|
||||||
.ok()?
|
.ok()?
|
||||||
.get_aspect("Field", "field", |n| &n.field)
|
.get_aspect("Field", "field", |n| &n.field)
|
||||||
.ok()
|
.ok()
|
||||||
.cloned()
|
.cloned()
|
||||||
})
|
})
|
||||||
.map(|f| f.map(|f| f.distance(spatial, point.into())))
|
.map(|f| f.map(|f| f.distance(spatial, point.into())))
|
||||||
.collect::<Vec<Option<f32>>>();
|
.collect::<Vec<Option<f32>>>();
|
||||||
|
|
||||||
Ok(serialize(output)?.into())
|
Ok(serialize(output)?.into())
|
||||||
|
});
|
||||||
}
|
}
|
||||||
pub fn field_normal_flex(
|
pub fn field_normal_flex(
|
||||||
node: &Node,
|
node: &Node,
|
||||||
calling_client: Arc<Client>,
|
calling_client: Arc<Client>,
|
||||||
message: Message,
|
message: Message,
|
||||||
) -> Result<Message> {
|
response: MethodResponseSender,
|
||||||
let (point, fields): (Vector3<f32>, Vec<Option<&str>>) = deserialize(message.as_ref())?;
|
) {
|
||||||
let spatial = node.spatial.get().unwrap();
|
response.wrap_sync(move || {
|
||||||
|
let (point, fields): (Vector3<f32>, Vec<Option<&str>>) = deserialize(message.as_ref())?;
|
||||||
|
let spatial = node.spatial.get().unwrap();
|
||||||
|
|
||||||
let output = fields
|
let output = fields
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|f| {
|
.map(|f| {
|
||||||
calling_client
|
calling_client
|
||||||
.get_node("Field", f?)
|
.get_node("Field", f?)
|
||||||
.ok()?
|
.ok()?
|
||||||
.get_aspect("Field", "field", |n| &n.field)
|
.get_aspect("Field", "field", |n| &n.field)
|
||||||
.ok()
|
.ok()
|
||||||
.cloned()
|
.cloned()
|
||||||
})
|
})
|
||||||
.map(|f| f.map(|f| Vector3::from(f.normal(spatial, point.into(), 0.001))))
|
.map(|f| f.map(|f| Vector3::from(f.normal(spatial, point.into(), 0.001))))
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
Ok(serialize(output)?.into())
|
Ok(serialize(output)?.into())
|
||||||
|
});
|
||||||
}
|
}
|
||||||
pub fn field_closest_point_flex(
|
pub fn field_closest_point_flex(
|
||||||
node: &Node,
|
node: &Node,
|
||||||
calling_client: Arc<Client>,
|
calling_client: Arc<Client>,
|
||||||
message: Message,
|
message: Message,
|
||||||
) -> Result<Message> {
|
response: MethodResponseSender,
|
||||||
let (point, fields): (Vector3<f32>, Vec<Option<&str>>) = deserialize(message.as_ref())?;
|
) {
|
||||||
let spatial = node.spatial.get().unwrap();
|
response.wrap_sync(move || {
|
||||||
|
let (point, fields): (Vector3<f32>, Vec<Option<&str>>) = deserialize(message.as_ref())?;
|
||||||
|
let spatial = node.spatial.get().unwrap();
|
||||||
|
|
||||||
let output = fields
|
let output = fields
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|f| {
|
.map(|f| {
|
||||||
calling_client
|
calling_client
|
||||||
.get_node("Field", f?)
|
.get_node("Field", f?)
|
||||||
.ok()?
|
.ok()?
|
||||||
.get_aspect("Field", "field", |n| &n.field)
|
.get_aspect("Field", "field", |n| &n.field)
|
||||||
.ok()
|
.ok()
|
||||||
.cloned()
|
.cloned()
|
||||||
})
|
})
|
||||||
.map(|f| f.map(|f| Vector3::from(f.closest_point(spatial, point.into(), 0.001))))
|
.map(|f| f.map(|f| Vector3::from(f.closest_point(spatial, point.into(), 0.001))))
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
Ok(serialize(output)?.into())
|
Ok(serialize(output)?.into())
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument]
|
#[instrument]
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
#[cfg(feature = "xwayland")]
|
#[cfg(feature = "xwayland")]
|
||||||
use crate::wayland::xwayland::DISPLAY;
|
use crate::wayland::xwayland::DISPLAY;
|
||||||
use crate::{core::client::Client, wayland::WAYLAND_DISPLAY, STARDUST_INSTANCE};
|
use crate::{
|
||||||
|
core::{client::Client, scenegraph::MethodResponseSender},
|
||||||
|
wayland::WAYLAND_DISPLAY,
|
||||||
|
STARDUST_INSTANCE,
|
||||||
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
items::{ItemAcceptor, TypeInfo},
|
items::{ItemAcceptor, TypeInfo},
|
||||||
@@ -65,13 +69,16 @@ impl StartupSettings {
|
|||||||
node: &Node,
|
node: &Node,
|
||||||
_calling_client: Arc<Client>,
|
_calling_client: Arc<Client>,
|
||||||
_message: Message,
|
_message: Message,
|
||||||
) -> Result<Message> {
|
response: MethodResponseSender,
|
||||||
let id = nanoid::nanoid!();
|
) {
|
||||||
let data = serialize(&id)?;
|
response.wrap_sync(move || {
|
||||||
STARTUP_SETTINGS
|
let id = nanoid::nanoid!();
|
||||||
.lock()
|
let data = serialize(&id)?;
|
||||||
.insert(id, node.startup_settings.get().unwrap().lock().clone());
|
STARTUP_SETTINGS
|
||||||
Ok(data.into())
|
.lock()
|
||||||
|
.insert(id, node.startup_settings.get().unwrap().lock().clone());
|
||||||
|
Ok(data.into())
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl Debug for StartupSettings {
|
impl Debug for StartupSettings {
|
||||||
@@ -136,20 +143,23 @@ pub fn get_connection_environment_flex(
|
|||||||
_node: &Node,
|
_node: &Node,
|
||||||
_calling_client: Arc<Client>,
|
_calling_client: Arc<Client>,
|
||||||
_message: Message,
|
_message: Message,
|
||||||
) -> Result<Message> {
|
response: MethodResponseSender,
|
||||||
let mut env: FxHashMap<String, String> = FxHashMap::default();
|
) {
|
||||||
var_env_insert!(env, STARDUST_INSTANCE);
|
response.wrap_sync(move || {
|
||||||
#[cfg(feature = "wayland")]
|
let mut env: FxHashMap<String, String> = FxHashMap::default();
|
||||||
{
|
var_env_insert!(env, STARDUST_INSTANCE);
|
||||||
var_env_insert!(env, WAYLAND_DISPLAY);
|
#[cfg(feature = "wayland")]
|
||||||
#[cfg(feature = "xwayland")]
|
{
|
||||||
var_env_insert!(env, DISPLAY);
|
var_env_insert!(env, WAYLAND_DISPLAY);
|
||||||
env.insert("GDK_BACKEND".to_string(), "wayland".to_string());
|
#[cfg(feature = "xwayland")]
|
||||||
env.insert("QT_QPA_PLATFORM".to_string(), "wayland".to_string());
|
var_env_insert!(env, DISPLAY);
|
||||||
env.insert("MOZ_ENABLE_WAYLAND".to_string(), "1".to_string());
|
env.insert("GDK_BACKEND".to_string(), "wayland".to_string());
|
||||||
env.insert("CLUTTER_BACKEND".to_string(), "wayland".to_string());
|
env.insert("QT_QPA_PLATFORM".to_string(), "wayland".to_string());
|
||||||
env.insert("SDL_VIDEODRIVER".to_string(), "wayland".to_string());
|
env.insert("MOZ_ENABLE_WAYLAND".to_string(), "1".to_string());
|
||||||
}
|
env.insert("CLUTTER_BACKEND".to_string(), "wayland".to_string());
|
||||||
|
env.insert("SDL_VIDEODRIVER".to_string(), "wayland".to_string());
|
||||||
|
}
|
||||||
|
|
||||||
Ok(serialize(env)?.into())
|
Ok(serialize(env)?.into())
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user