refactor(idl,spatial): make zone use idl
This commit is contained in:
4
Cargo.lock
generated
4
Cargo.lock
generated
@@ -2063,7 +2063,7 @@ checksum = "2f2b15926089e5526bb2dd738a2eb0e59034356e06eb71e1cd912358c0e62c4d"
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "stardust-xr"
|
name = "stardust-xr"
|
||||||
version = "0.14.1"
|
version = "0.14.1"
|
||||||
source = "git+https://github.com/StardustXR/core.git?branch=feat/idl#c7e27806c671d0ad262801583ec30acbf710a143"
|
source = "git+https://github.com/StardustXR/core.git?branch=feat/idl#530b1fe5aa33f782fbf28026410ba00dd23da16d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cluFlock",
|
"cluFlock",
|
||||||
"color-rs",
|
"color-rs",
|
||||||
@@ -2083,7 +2083,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "stardust-xr-schemas"
|
name = "stardust-xr-schemas"
|
||||||
version = "1.5.3"
|
version = "1.5.3"
|
||||||
source = "git+https://github.com/StardustXR/core.git?branch=feat/idl#c7e27806c671d0ad262801583ec30acbf710a143"
|
source = "git+https://github.com/StardustXR/core.git?branch=feat/idl#530b1fe5aa33f782fbf28026410ba00dd23da16d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"flatbuffers",
|
"flatbuffers",
|
||||||
"flexbuffers",
|
"flexbuffers",
|
||||||
|
|||||||
@@ -29,10 +29,6 @@ pub fn codegen_data_protocol(_input: proc_macro::TokenStream) -> proc_macro::Tok
|
|||||||
codegen_protocol(DATA_PROTOCOL)
|
codegen_protocol(DATA_PROTOCOL)
|
||||||
}
|
}
|
||||||
#[proc_macro]
|
#[proc_macro]
|
||||||
pub fn codegen_zone_protocol(_input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
|
||||||
codegen_protocol(ZONE_PROTOCOL)
|
|
||||||
}
|
|
||||||
#[proc_macro]
|
|
||||||
pub fn codegen_audio_protocol(_input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
pub fn codegen_audio_protocol(_input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||||
codegen_protocol(AUDIO_PROTOCOL)
|
codegen_protocol(AUDIO_PROTOCOL)
|
||||||
}
|
}
|
||||||
@@ -40,18 +36,6 @@ pub fn codegen_audio_protocol(_input: proc_macro::TokenStream) -> proc_macro::To
|
|||||||
pub fn codegen_drawable_protocol(_input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
pub fn codegen_drawable_protocol(_input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||||
codegen_protocol(DRAWABLE_PROTOCOL)
|
codegen_protocol(DRAWABLE_PROTOCOL)
|
||||||
}
|
}
|
||||||
#[proc_macro]
|
|
||||||
pub fn codegen_drawable_lines_protocol(_input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
|
||||||
codegen_protocol(DRAWABLE_LINES_PROTOCOL)
|
|
||||||
}
|
|
||||||
#[proc_macro]
|
|
||||||
pub fn codegen_drawable_model_protocol(_input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
|
||||||
codegen_protocol(DRAWABLE_MODEL_PROTOCOL)
|
|
||||||
}
|
|
||||||
#[proc_macro]
|
|
||||||
pub fn codegen_drawable_text_protocol(_input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
|
||||||
codegen_protocol(DRAWABLE_TEXT_PROTOCOL)
|
|
||||||
}
|
|
||||||
// #[proc_macro]
|
// #[proc_macro]
|
||||||
// pub fn codegen_input_protocol(_input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
// pub fn codegen_input_protocol(_input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||||
// codegen_protocol(INPUT_PROTOCOL)
|
// codegen_protocol(INPUT_PROTOCOL)
|
||||||
@@ -59,6 +43,22 @@ pub fn codegen_drawable_text_protocol(_input: proc_macro::TokenStream) -> proc_m
|
|||||||
|
|
||||||
fn codegen_protocol(protocol: &'static str) -> proc_macro::TokenStream {
|
fn codegen_protocol(protocol: &'static str) -> proc_macro::TokenStream {
|
||||||
let protocol = Protocol::parse(protocol).unwrap();
|
let protocol = Protocol::parse(protocol).unwrap();
|
||||||
|
let interface = protocol
|
||||||
|
.interface
|
||||||
|
.map(|p| {
|
||||||
|
let virtual_aspect_name = p.path[1..]
|
||||||
|
.split('/')
|
||||||
|
.map(ToString::to_string)
|
||||||
|
.reduce(|a, b| format!("{a}_{b}"))
|
||||||
|
.unwrap_or_default()
|
||||||
|
+ "_interface";
|
||||||
|
generate_aspect(&Aspect {
|
||||||
|
name: virtual_aspect_name,
|
||||||
|
description: protocol.description.clone(),
|
||||||
|
members: p.members,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.unwrap_or_default();
|
||||||
let custom_enums = protocol
|
let custom_enums = protocol
|
||||||
.custom_enums
|
.custom_enums
|
||||||
.iter()
|
.iter()
|
||||||
@@ -89,14 +89,7 @@ fn codegen_protocol(protocol: &'static str) -> proc_macro::TokenStream {
|
|||||||
// .map(generate_node)
|
// .map(generate_node)
|
||||||
// .reduce(fold_tokens)
|
// .reduce(fold_tokens)
|
||||||
// .unwrap_or_default();
|
// .unwrap_or_default();
|
||||||
// let interfaces = protocol
|
quote!(#custom_enums #custom_unions #custom_structs #aspects #interface).into()
|
||||||
// .interfaces
|
|
||||||
// .iter()
|
|
||||||
// .map(generate_interface)
|
|
||||||
// .reduce(fold_tokens)
|
|
||||||
// .unwrap_or_default();
|
|
||||||
// quote!(#custom_enums #custom_unions #custom_structs #aspects #nodes #interfaces).into()
|
|
||||||
quote!(#custom_enums #custom_unions #custom_structs #aspects).into()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate_custom_enum(custom_enum: &CustomEnum) -> TokenStream {
|
fn generate_custom_enum(custom_enum: &CustomEnum) -> TokenStream {
|
||||||
@@ -167,15 +160,6 @@ fn generate_custom_struct(custom_struct: &CustomStruct) -> TokenStream {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate_interface(interface: &Interface) -> TokenStream {
|
|
||||||
interface
|
|
||||||
.members
|
|
||||||
.iter()
|
|
||||||
.map(generate_member)
|
|
||||||
.reduce(fold_tokens)
|
|
||||||
.unwrap_or_default()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn generate_node(node: &Node) -> TokenStream {
|
fn generate_node(node: &Node) -> TokenStream {
|
||||||
let node_name = Ident::new(&node.name, Span::call_site());
|
let node_name = Ident::new(&node.name, Span::call_site());
|
||||||
let description = &node.description;
|
let description = &node.description;
|
||||||
@@ -219,8 +203,8 @@ fn generate_aspect(aspect: &Aspect) -> TokenStream {
|
|||||||
let description = &aspect.description;
|
let description = &aspect.description;
|
||||||
let (client_members, server_members) = aspect.members.iter().split(|m| m.side == Side::Server);
|
let (client_members, server_members) = aspect.members.iter().split(|m| m.side == Side::Server);
|
||||||
|
|
||||||
let aspect_handler_name = Ident::new(
|
let client_mod_name = Ident::new(
|
||||||
&format!("{}Handler", &aspect.name.to_case(Case::Pascal)),
|
&format!("{}_client", &aspect.name.to_case(Case::Snake)),
|
||||||
Span::call_site(),
|
Span::call_site(),
|
||||||
);
|
);
|
||||||
let client_side_members = client_members
|
let client_side_members = client_members
|
||||||
@@ -228,8 +212,7 @@ fn generate_aspect(aspect: &Aspect) -> TokenStream {
|
|||||||
.reduce(fold_tokens)
|
.reduce(fold_tokens)
|
||||||
.map(|t| {
|
.map(|t| {
|
||||||
quote! {
|
quote! {
|
||||||
#[doc = #description]
|
pub mod #client_mod_name {
|
||||||
pub trait #aspect_handler_name: Send + Sync + 'static {
|
|
||||||
#t
|
#t
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -252,7 +235,7 @@ fn generate_aspect(aspect: &Aspect) -> TokenStream {
|
|||||||
.reduce(fold_tokens)
|
.reduce(fold_tokens)
|
||||||
.map(|members| {
|
.map(|members| {
|
||||||
quote! {
|
quote! {
|
||||||
fn add_node_members(node: &Node) {
|
fn add_node_members(node: &crate::nodes::Node) {
|
||||||
#members
|
#members
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -268,6 +251,10 @@ fn generate_aspect(aspect: &Aspect) -> TokenStream {
|
|||||||
quote!(#client_side_members #server_side_members)
|
quote!(#client_side_members #server_side_members)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn generate_interface_member(interface_path: &str, member: &Member) -> TokenStream {
|
||||||
|
Default::default()
|
||||||
|
}
|
||||||
|
|
||||||
fn generate_member(member: &Member) -> TokenStream {
|
fn generate_member(member: &Member) -> TokenStream {
|
||||||
let name_str = &member.name;
|
let name_str = &member.name;
|
||||||
let name = Ident::new(&member.name.to_case(Case::Snake), Span::call_site());
|
let name = Ident::new(&member.name.to_case(Case::Snake), Span::call_site());
|
||||||
@@ -276,10 +263,11 @@ fn generate_member(member: &Member) -> TokenStream {
|
|||||||
let side = member.side;
|
let side = member.side;
|
||||||
let _type = member._type;
|
let _type = member._type;
|
||||||
|
|
||||||
let first_args = if member.side == Side::Server {
|
let first_args = match member.side {
|
||||||
quote!(_node: std::sync::Arc<crate::nodes::Node>, _calling_client: std::sync::Arc<crate::core::client::Client>, _fds: Vec<std::os::fd::OwnedFd>)
|
Side::Server => {
|
||||||
} else {
|
quote!(_node: std::sync::Arc<crate::nodes::Node>, _calling_client: std::sync::Arc<crate::core::client::Client>, _fds: Vec<std::os::fd::OwnedFd>)
|
||||||
quote!(&mut self)
|
}
|
||||||
|
Side::Client => quote!(_node: &crate::nodes::Node),
|
||||||
};
|
};
|
||||||
let argument_decls = member
|
let argument_decls = member
|
||||||
.arguments
|
.arguments
|
||||||
@@ -301,38 +289,19 @@ fn generate_member(member: &Member) -> TokenStream {
|
|||||||
|
|
||||||
match (side, _type) {
|
match (side, _type) {
|
||||||
(Side::Client, MemberType::Method) => {
|
(Side::Client, MemberType::Method) => {
|
||||||
let body = if let Some(interface_path) = &member.interface_path {
|
|
||||||
quote! {
|
|
||||||
let data = stardust_xr::schemas::flex::serialize(&(#argument_uses))?;
|
|
||||||
let result = client.message_sender_handle.method(#interface_path, #name_str, &data, Vec::new())?.await?;
|
|
||||||
Ok(stardust_xr::schemas::flex::deserialize(&result.into_message())?)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
quote! {
|
|
||||||
self.node().execute_remote_method(#name_str, &(#argument_uses)).await
|
|
||||||
}
|
|
||||||
};
|
|
||||||
quote! {
|
quote! {
|
||||||
#[doc = #description]
|
#[doc = #description]
|
||||||
async fn #name(#argument_decls) -> crate::node::NodeResult<#return_type> {
|
pub async fn #name(#argument_decls) -> color_eyre::eyre::Result<#return_type> {
|
||||||
#body
|
_node.execute_remote_method(#name_str, &(#argument_uses)).await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(Side::Client, MemberType::Signal) => {
|
(Side::Client, MemberType::Signal) => {
|
||||||
let body = if let Some(interface_path) = &member.interface_path {
|
|
||||||
quote! {
|
|
||||||
client.message_sender_handle.signal(#interface_path, #name_str, &stardust_xr::schemas::flex::serialize(&(#argument_uses))?, Vec::new())
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
quote! {
|
|
||||||
self.node().send_remote_signal(#name_str, &(#argument_uses))
|
|
||||||
}
|
|
||||||
};
|
|
||||||
quote! {
|
quote! {
|
||||||
#[doc = #description]
|
#[doc = #description]
|
||||||
fn #name(#argument_decls) -> crate::node::NodeResult<#return_type> {
|
pub fn #name(#argument_decls) -> color_eyre::eyre::Result<()> {
|
||||||
#body
|
let serialized = stardust_xr::schemas::flex::serialize((#argument_uses))?;
|
||||||
|
_node.send_remote_signal(#name_str, serialized)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -345,7 +314,7 @@ fn generate_member(member: &Member) -> TokenStream {
|
|||||||
(Side::Server, MemberType::Signal) => {
|
(Side::Server, MemberType::Signal) => {
|
||||||
quote! {
|
quote! {
|
||||||
#[doc = #description]
|
#[doc = #description]
|
||||||
fn #name(#argument_decls) -> color_eyre::eyre::Result<#return_type>;
|
fn #name(#argument_decls) -> color_eyre::eyre::Result<()>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -424,11 +393,11 @@ fn generate_argument_deserialize(
|
|||||||
ArgumentType::Color => quote!(color::rgba_linear!(#name[0], #name[1], #name[2], #name[3])),
|
ArgumentType::Color => quote!(color::rgba_linear!(#name[0], #name[1], #name[2], #name[3])),
|
||||||
ArgumentType::Vec(v) => {
|
ArgumentType::Vec(v) => {
|
||||||
let mapping = generate_argument_deserialize("a", v, false);
|
let mapping = generate_argument_deserialize("a", v, false);
|
||||||
quote!(#name.iter().map(|a| Ok(#mapping)).collect::<Result<Vec<_>, crate::node::NodeError>>()?)
|
quote!(#name.iter().map(|a| Ok(#mapping)).collect::<color_eyre::eyre::Result<Vec<_>>>()?)
|
||||||
}
|
}
|
||||||
ArgumentType::Map(v) => {
|
ArgumentType::Map(v) => {
|
||||||
let mapping = generate_argument_deserialize("a", v, false);
|
let mapping = generate_argument_deserialize("a", v, false);
|
||||||
quote!(#name.iter().map(|(k, a)| Ok((k, #mapping))).collect::<Result<rustc_hash::FxHashMap<String, _>, crate::node::NodeError>>()?)
|
quote!(#name.iter().map(|(k, a)| Ok((k, #mapping))).collect::<color_eyre::eyre::Result<rustc_hash::FxHashMap<String, _>>>()?)
|
||||||
}
|
}
|
||||||
_ => quote!(#name),
|
_ => quote!(#name),
|
||||||
}
|
}
|
||||||
@@ -444,24 +413,24 @@ fn generate_argument_serialize(
|
|||||||
_type,
|
_type,
|
||||||
return_info: _,
|
return_info: _,
|
||||||
} => match optional {
|
} => match optional {
|
||||||
true => quote!(#name.map(|n| n.node().get_path()).transpose()?),
|
true => quote!(#name.map(|n| n.get_path())),
|
||||||
false => quote!(#name.node().get_path()?),
|
false => quote!(#name.get_path()),
|
||||||
},
|
},
|
||||||
ArgumentType::Color => quote!([#name.c.r, #name.c.g, #name.c.b, #name.a]),
|
ArgumentType::Color => quote!([#name.c.r, #name.c.g, #name.c.b, #name.a]),
|
||||||
ArgumentType::Vec(v) => {
|
ArgumentType::Vec(v) => {
|
||||||
let mapping = generate_argument_serialize("a", v, false);
|
let mapping = generate_argument_serialize("a", v, false);
|
||||||
quote!(#name.iter().map(|a| Ok(#mapping)).collect::<Result<Vec<_>, crate::node::NodeError>>()?)
|
quote!(#name.iter().map(|a| Ok(#mapping)).collect::<color_eyre::eyre::Result<Vec<_>>>()?)
|
||||||
}
|
}
|
||||||
ArgumentType::Map(v) => {
|
ArgumentType::Map(v) => {
|
||||||
let mapping = generate_argument_serialize("a", v, false);
|
let mapping = generate_argument_serialize("a", v, false);
|
||||||
quote!(#name.iter().map(|(k, a)| Ok((k, #mapping))).collect::<Result<rustc_hash::FxHashMap<String, _>, crate::node::NodeError>>()?)
|
quote!(#name.iter().map(|(k, a)| Ok((k, #mapping))).collect::<color_eyre::eyre::Result<rustc_hash::FxHashMap<String, _>>>()?)
|
||||||
}
|
}
|
||||||
_ => quote!(#name),
|
_ => quote!(#name),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn generate_argument_decl(argument: &Argument, returned: bool) -> TokenStream {
|
fn generate_argument_decl(argument: &Argument, owned_values: bool) -> TokenStream {
|
||||||
let name = Ident::new(&argument.name.to_case(Case::Snake), Span::call_site());
|
let name = Ident::new(&argument.name.to_case(Case::Snake), Span::call_site());
|
||||||
let mut _type = generate_argument_type(&argument._type, returned);
|
let mut _type = generate_argument_type(&argument._type, owned_values);
|
||||||
if argument.optional {
|
if argument.optional {
|
||||||
_type = quote!(Option<#_type>);
|
_type = quote!(Option<#_type>);
|
||||||
}
|
}
|
||||||
@@ -560,7 +529,11 @@ fn generate_argument_type(argument_type: &ArgumentType, owned: bool) -> TokenStr
|
|||||||
_type,
|
_type,
|
||||||
return_info: _,
|
return_info: _,
|
||||||
} => {
|
} => {
|
||||||
quote!(Arc<crate::nodes::Node>)
|
if !owned {
|
||||||
|
quote!(&std::sync::Arc<crate::nodes::Node>)
|
||||||
|
} else {
|
||||||
|
quote!(std::sync::Arc<crate::nodes::Node>)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -264,3 +264,6 @@ pub fn find_field(client: &Client, path: &str) -> Result<Arc<Field>> {
|
|||||||
.get_aspect("Field", "info", |n| &n.field)
|
.get_aspect("Field", "info", |n| &n.field)
|
||||||
.cloned()
|
.cloned()
|
||||||
}
|
}
|
||||||
|
pub fn get_field(node: &Node) -> Result<Arc<Field>> {
|
||||||
|
node.get_aspect("Field", "info", |n| &n.field).cloned()
|
||||||
|
}
|
||||||
|
|||||||
@@ -15,11 +15,11 @@ use once_cell::sync::OnceCell;
|
|||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use portable_atomic::{AtomicBool, Ordering};
|
use portable_atomic::{AtomicBool, Ordering};
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
|
use serde::{de::DeserializeOwned, Serialize};
|
||||||
use stardust_xr::messenger::MessageSenderHandle;
|
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, serialize};
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::future::Future;
|
|
||||||
use std::os::fd::OwnedFd;
|
use std::os::fd::OwnedFd;
|
||||||
use std::sync::{Arc, Weak};
|
use std::sync::{Arc, Weak};
|
||||||
use std::vec::Vec;
|
use std::vec::Vec;
|
||||||
@@ -290,29 +290,26 @@ impl Node {
|
|||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
pub fn execute_remote_method(
|
pub async fn execute_remote_method_typed<S: Serialize, D: DeserializeOwned>(
|
||||||
&self,
|
&self,
|
||||||
method: &str,
|
method: &str,
|
||||||
message: impl Into<Message>,
|
input: S,
|
||||||
) -> Result<impl Future<Output = Result<Message>>> {
|
fds: Vec<OwnedFd>,
|
||||||
let message = message.into();
|
) -> Result<(D, Vec<OwnedFd>)> {
|
||||||
let message_sender_handle = self
|
let message_sender_handle = self
|
||||||
.message_sender_handle
|
.message_sender_handle
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.ok_or(eyre!("Messenger does not exist for this node"))?;
|
.ok_or(eyre!("Messenger does not exist for this node"))?;
|
||||||
|
|
||||||
let future =
|
let serialized = serialize(input)?;
|
||||||
message_sender_handle.method(self.path.as_str(), method, &message.data, message.fds)?;
|
let result = message_sender_handle
|
||||||
|
.method(self.path.as_str(), method, &serialized, fds)?
|
||||||
|
.await
|
||||||
|
.map_err(|e| eyre!(e))?;
|
||||||
|
|
||||||
Ok(async {
|
let (message, fds) = result.into_components();
|
||||||
match future.await {
|
let deserialized: D = deserialize(&message)?;
|
||||||
Ok(m) => {
|
Ok((deserialized, fds))
|
||||||
let (data, fds) = m.into_components();
|
|
||||||
Ok(Message { data, fds })
|
|
||||||
}
|
|
||||||
Err(e) => Err(eyre!(e)),
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl Debug for Node {
|
impl Debug for Node {
|
||||||
|
|||||||
@@ -13,11 +13,9 @@ use color_eyre::eyre::Result;
|
|||||||
use glam::Mat4;
|
use glam::Mat4;
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use stardust_xr::schemas::flex::{deserialize, serialize};
|
use stardust_xr::schemas::flex::{deserialize, serialize};
|
||||||
use tracing::instrument;
|
|
||||||
|
|
||||||
use std::future::Future;
|
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
use tracing::instrument;
|
||||||
|
|
||||||
static ROOT_REGISTRY: Registry<Root> = Registry::new();
|
static ROOT_REGISTRY: Registry<Root> = Registry::new();
|
||||||
|
|
||||||
@@ -96,11 +94,12 @@ impl Root {
|
|||||||
spatial.set_spatial_parent(None).unwrap();
|
spatial.set_spatial_parent(None).unwrap();
|
||||||
spatial.set_local_transform(transform);
|
spatial.set_local_transform(transform);
|
||||||
}
|
}
|
||||||
pub fn save_state(&self) -> impl Future<Output = Result<ClientStateInternal>> {
|
pub async fn save_state(&self) -> Result<ClientStateInternal> {
|
||||||
let future = self
|
Ok(self
|
||||||
.node
|
.node
|
||||||
.execute_remote_method("save_state", Message::default());
|
.execute_remote_method_typed("save_state", (), Vec::new())
|
||||||
async move { Ok(deserialize(&future?.await?.data)?) }
|
.await?
|
||||||
|
.0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
pub mod zone;
|
pub mod zone;
|
||||||
|
|
||||||
use self::zone::{create_zone_flex, Zone};
|
use self::zone::Zone;
|
||||||
use super::{Message, Node};
|
use super::fields::get_field;
|
||||||
|
use super::Node;
|
||||||
use crate::core::client::Client;
|
use crate::core::client::Client;
|
||||||
use crate::core::registry::Registry;
|
use crate::core::registry::Registry;
|
||||||
use color_eyre::eyre::{ensure, eyre, Result};
|
use color_eyre::eyre::{ensure, eyre, Result};
|
||||||
@@ -10,8 +11,6 @@ use mint::Vector3;
|
|||||||
use nanoid::nanoid;
|
use nanoid::nanoid;
|
||||||
use once_cell::sync::OnceCell;
|
use once_cell::sync::OnceCell;
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use serde::Deserialize;
|
|
||||||
use stardust_xr::schemas::flex::deserialize;
|
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::os::fd::OwnedFd;
|
use std::os::fd::OwnedFd;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
@@ -123,7 +122,7 @@ impl Spatial {
|
|||||||
}
|
}
|
||||||
pub fn global_transform(&self) -> Mat4 {
|
pub fn global_transform(&self) -> Mat4 {
|
||||||
match self.get_parent() {
|
match self.get_parent() {
|
||||||
Some(value) => value.global_transform() * *self.transform.lock(),
|
Some(parent) => parent.global_transform() * *self.transform.lock(),
|
||||||
None => *self.transform.lock(),
|
None => *self.transform.lock(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -275,7 +274,7 @@ impl SpatialAspect for Spatial {
|
|||||||
.spatial
|
.spatial
|
||||||
.get()
|
.get()
|
||||||
.ok_or_else(|| eyre!("Node doesn't have a spatial?"))?;
|
.ok_or_else(|| eyre!("Node doesn't have a spatial?"))?;
|
||||||
let relative_spatial = get_spatial(&relative_to, "Relative node", "Spatial")?;
|
let relative_spatial = get_spatial(&relative_to, "Relative node")?;
|
||||||
let center =
|
let center =
|
||||||
Spatial::space_to_space_matrix(Some(&this_spatial), Some(&relative_spatial))
|
Spatial::space_to_space_matrix(Some(&this_spatial), Some(&relative_spatial))
|
||||||
.transform_point3([0.0; 3].into());
|
.transform_point3([0.0; 3].into());
|
||||||
@@ -311,7 +310,7 @@ impl SpatialAspect for Spatial {
|
|||||||
.spatial
|
.spatial
|
||||||
.get()
|
.get()
|
||||||
.ok_or_else(|| eyre!("Node doesn't have a spatial?"))?;
|
.ok_or_else(|| eyre!("Node doesn't have a spatial?"))?;
|
||||||
let relative_spatial = get_spatial(&relative_to, "Relative node", "Spatial")?;
|
let relative_spatial = get_spatial(&relative_to, "Relative node")?;
|
||||||
|
|
||||||
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()),
|
||||||
@@ -352,7 +351,7 @@ impl SpatialAspect for Spatial {
|
|||||||
.spatial
|
.spatial
|
||||||
.get()
|
.get()
|
||||||
.ok_or_else(|| eyre!("Node doesn't have a spatial?"))?;
|
.ok_or_else(|| eyre!("Node doesn't have a spatial?"))?;
|
||||||
let relative_spatial = get_spatial(&relative_to, "Relative node", "Spatial")?;
|
let relative_spatial = get_spatial(&relative_to, "Relative node")?;
|
||||||
|
|
||||||
this_spatial.set_local_transform_components(Some(&relative_spatial), transform);
|
this_spatial.set_local_transform_components(Some(&relative_spatial), transform);
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -368,7 +367,7 @@ impl SpatialAspect for Spatial {
|
|||||||
.spatial
|
.spatial
|
||||||
.get()
|
.get()
|
||||||
.ok_or_else(|| eyre!("Node doesn't have a spatial?"))?;
|
.ok_or_else(|| eyre!("Node doesn't have a spatial?"))?;
|
||||||
let parent = get_spatial(&parent, "Parent", "Spatial")?;
|
let parent = get_spatial(&parent, "Parent")?;
|
||||||
|
|
||||||
this_spatial.set_spatial_parent(Some(parent))?;
|
this_spatial.set_spatial_parent(Some(parent))?;
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -384,7 +383,7 @@ impl SpatialAspect for Spatial {
|
|||||||
.spatial
|
.spatial
|
||||||
.get()
|
.get()
|
||||||
.ok_or_else(|| eyre!("Node doesn't have a spatial?"))?;
|
.ok_or_else(|| eyre!("Node doesn't have a spatial?"))?;
|
||||||
let parent = get_spatial(&parent, "Parent", "Spatial")?;
|
let parent = get_spatial(&parent, "Parent")?;
|
||||||
|
|
||||||
this_spatial.set_spatial_parent_in_place(Some(parent))?;
|
this_spatial.set_spatial_parent_in_place(Some(parent))?;
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -461,35 +460,52 @@ pub fn find_spatial_parent(calling_client: &Arc<Client>, node_path: &str) -> Res
|
|||||||
pub fn find_reference_space(calling_client: &Arc<Client>, node_path: &str) -> Result<Arc<Spatial>> {
|
pub fn find_reference_space(calling_client: &Arc<Client>, node_path: &str) -> Result<Arc<Spatial>> {
|
||||||
find_spatial(calling_client, "Reference space", node_path)
|
find_spatial(calling_client, "Reference space", node_path)
|
||||||
}
|
}
|
||||||
pub fn get_spatial(node: &Arc<Node>, node_name: &str, aspect_name: &str) -> Result<Arc<Spatial>> {
|
pub fn get_spatial(node: &Arc<Node>, node_name: &str) -> Result<Arc<Spatial>> {
|
||||||
node.get_aspect(node_name, aspect_name, |n| &n.spatial)
|
node.get_aspect(node_name, "spatial", |n| &n.spatial)
|
||||||
.cloned()
|
.cloned()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct SpatialInterface;
|
||||||
|
impl SpatialInterfaceAspect for SpatialInterface {
|
||||||
|
fn create_spatial(
|
||||||
|
_node: Arc<Node>,
|
||||||
|
calling_client: Arc<Client>,
|
||||||
|
_fds: Vec<OwnedFd>,
|
||||||
|
name: String,
|
||||||
|
parent: Arc<Node>,
|
||||||
|
transform: Transform,
|
||||||
|
zoneable: bool,
|
||||||
|
) -> Result<()> {
|
||||||
|
let parent = get_spatial(&parent, "Spatial parent")?;
|
||||||
|
let transform = parse_transform(transform, true, true, true);
|
||||||
|
let node =
|
||||||
|
Node::create(&calling_client, "/spatial/spatial", &name, true).add_to_scenegraph()?;
|
||||||
|
Spatial::add_to(&node, Some(parent), transform, zoneable)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
fn create_zone(
|
||||||
|
_node: Arc<Node>,
|
||||||
|
calling_client: Arc<Client>,
|
||||||
|
_fds: Vec<OwnedFd>,
|
||||||
|
name: String,
|
||||||
|
parent: Arc<Node>,
|
||||||
|
transform: Transform,
|
||||||
|
field: Arc<Node>,
|
||||||
|
) -> Result<()> {
|
||||||
|
let parent = get_spatial(&parent, "Spatial parent")?;
|
||||||
|
let transform = parse_transform(transform, true, true, false);
|
||||||
|
let field = get_field(&field)?;
|
||||||
|
|
||||||
|
let node =
|
||||||
|
Node::create(&calling_client, "/spatial/zone", &name, true).add_to_scenegraph()?;
|
||||||
|
let space = Spatial::add_to(&node, Some(parent), transform, false)?;
|
||||||
|
Zone::add_to(&node, space, &field);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn create_interface(client: &Arc<Client>) -> Result<()> {
|
pub fn create_interface(client: &Arc<Client>) -> Result<()> {
|
||||||
let node = Node::create(client, "", "spatial", false);
|
let node = Node::create(client, "", "spatial", false);
|
||||||
node.add_local_signal("create_spatial", create_spatial_flex);
|
<SpatialInterface as SpatialInterfaceAspect>::add_node_members(&node);
|
||||||
node.add_local_signal("create_zone", create_zone_flex);
|
|
||||||
node.add_to_scenegraph().map(|_| ())
|
node.add_to_scenegraph().map(|_| ())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_spatial_flex(
|
|
||||||
_node: Arc<Node>,
|
|
||||||
calling_client: Arc<Client>,
|
|
||||||
message: Message,
|
|
||||||
) -> Result<()> {
|
|
||||||
#[derive(Deserialize)]
|
|
||||||
struct CreateSpatialInfo<'a> {
|
|
||||||
name: &'a str,
|
|
||||||
parent_path: &'a str,
|
|
||||||
transform: Transform,
|
|
||||||
zoneable: bool,
|
|
||||||
}
|
|
||||||
let info: CreateSpatialInfo = deserialize(message.as_ref())?;
|
|
||||||
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()?;
|
|
||||||
Spatial::add_to(&node, Some(parent), transform, info.zoneable)?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,20 +1,19 @@
|
|||||||
use super::{find_spatial, Spatial, ZONEABLE_REGISTRY};
|
use super::{get_spatial, Spatial, ZoneAspect, ZONEABLE_REGISTRY};
|
||||||
use crate::{
|
use crate::{
|
||||||
core::{client::Client, registry::Registry},
|
core::{client::Client, registry::Registry},
|
||||||
nodes::{
|
nodes::{
|
||||||
alias::{Alias, AliasInfo},
|
alias::{Alias, AliasInfo},
|
||||||
fields::{find_field, Field},
|
fields::Field,
|
||||||
spatial::{find_spatial_parent, parse_transform, Transform},
|
Node,
|
||||||
Message, Node,
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use color_eyre::eyre::Result;
|
|
||||||
use glam::vec3a;
|
use glam::vec3a;
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use serde::Deserialize;
|
use std::{
|
||||||
use stardust_xr::schemas::flex::{deserialize, serialize};
|
os::fd::OwnedFd,
|
||||||
use std::sync::{Arc, Weak};
|
sync::{Arc, Weak},
|
||||||
|
};
|
||||||
|
|
||||||
pub fn capture(spatial: &Arc<Spatial>, zone: &Arc<Zone>) {
|
pub fn capture(spatial: &Arc<Spatial>, zone: &Arc<Zone>) {
|
||||||
let old_distance = spatial.zone_distance();
|
let old_distance = spatial.zone_distance();
|
||||||
@@ -31,10 +30,7 @@ pub fn capture(spatial: &Arc<Spatial>, zone: &Arc<Zone>) {
|
|||||||
let Some(node) = zone.spatial.node.upgrade() else {
|
let Some(node) = zone.spatial.node.upgrade() else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
let Ok(message) = serialize(&spatial.uid) else {
|
let _ = super::zone_client::capture(&node, &spatial.uid);
|
||||||
return;
|
|
||||||
};
|
|
||||||
let _ = node.send_remote_signal("capture", message);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn release(spatial: &Spatial) {
|
pub fn release(spatial: &Spatial) {
|
||||||
@@ -45,10 +41,7 @@ pub fn release(spatial: &Spatial) {
|
|||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
spatial_zone.captured.remove(spatial);
|
spatial_zone.captured.remove(spatial);
|
||||||
let Ok(message) = serialize(&spatial.uid) else {
|
let _ = super::zone_client::release(&node, &spatial.uid);
|
||||||
return;
|
|
||||||
};
|
|
||||||
let _ = node.send_remote_signal("release", message);
|
|
||||||
}
|
}
|
||||||
*spatial_zone = Weak::new();
|
*spatial_zone = Weak::new();
|
||||||
}
|
}
|
||||||
@@ -67,26 +60,18 @@ impl Zone {
|
|||||||
zoneables: Mutex::new(FxHashMap::default()),
|
zoneables: Mutex::new(FxHashMap::default()),
|
||||||
captured: Registry::new(),
|
captured: Registry::new(),
|
||||||
});
|
});
|
||||||
node.add_local_signal("capture", Zone::capture_flex);
|
<Zone as ZoneAspect>::add_node_members(node);
|
||||||
node.add_local_signal("release", Zone::release_flex);
|
|
||||||
node.add_local_signal("update", Zone::update);
|
|
||||||
let _ = node.zone.set(zone.clone());
|
let _ = node.zone.set(zone.clone());
|
||||||
zone
|
zone
|
||||||
}
|
}
|
||||||
fn capture_flex(node: Arc<Node>, calling_client: Arc<Client>, message: Message) -> Result<()> {
|
}
|
||||||
let zone = node.zone.get().unwrap();
|
impl ZoneAspect for Zone {
|
||||||
let capture_path: &str = deserialize(message.as_ref())?;
|
#[doc = ""]
|
||||||
let spatial = find_spatial(&calling_client, "Spatial", capture_path)?;
|
fn update(
|
||||||
capture(&spatial, zone);
|
node: Arc<Node>,
|
||||||
Ok(())
|
_calling_client: Arc<Client>,
|
||||||
}
|
_fds: Vec<OwnedFd>,
|
||||||
fn release_flex(_node: Arc<Node>, calling_client: Arc<Client>, message: Message) -> Result<()> {
|
) -> color_eyre::eyre::Result<()> {
|
||||||
let capture_path: &str = deserialize(message.as_ref())?;
|
|
||||||
let spatial = find_spatial(&calling_client, "Spatial", capture_path)?;
|
|
||||||
release(&spatial);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
fn update(node: Arc<Node>, _calling_client: Arc<Client>, _message: Message) -> Result<()> {
|
|
||||||
let zone = node.zone.get().unwrap();
|
let zone = node.zone.get().unwrap();
|
||||||
let Some(field) = zone.field.upgrade() else {
|
let Some(field) = zone.field.upgrade() else {
|
||||||
return Err(color_eyre::eyre::eyre!("Zone's field has been destroyed"));
|
return Err(color_eyre::eyre::eyre!("Zone's field has been destroyed"));
|
||||||
@@ -140,17 +125,45 @@ impl Zone {
|
|||||||
})
|
})
|
||||||
.collect::<FxHashMap<String, Arc<Node>>>();
|
.collect::<FxHashMap<String, Arc<Node>>>();
|
||||||
|
|
||||||
for entered_uid in zoneables.keys().filter(|k| !old_zoneables.contains_key(*k)) {
|
for (uid, zoneable) in zoneables
|
||||||
node.send_remote_signal("enter", serialize(entered_uid)?)?;
|
.iter()
|
||||||
|
.filter(|(k, _)| !old_zoneables.contains_key(*k))
|
||||||
|
{
|
||||||
|
super::zone_client::enter(&node, uid, zoneable)?;
|
||||||
}
|
}
|
||||||
for left_uid in old_zoneables.keys().filter(|k| !zoneables.contains_key(*k)) {
|
for left_uid in old_zoneables.keys().filter(|k| !zoneables.contains_key(*k)) {
|
||||||
node.send_remote_signal("leave", serialize(left_uid)?)?;
|
super::zone_client::leave(&node, &left_uid)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
*old_zoneables = zoneables;
|
*old_zoneables = zoneables;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[doc = ""]
|
||||||
|
fn capture(
|
||||||
|
node: Arc<Node>,
|
||||||
|
_calling_client: Arc<Client>,
|
||||||
|
_fds: Vec<OwnedFd>,
|
||||||
|
spatial: Arc<Node>,
|
||||||
|
) -> color_eyre::eyre::Result<()> {
|
||||||
|
let zone = node.zone.get().unwrap();
|
||||||
|
let spatial = get_spatial(&spatial, "Spatial")?;
|
||||||
|
capture(&spatial, zone);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[doc = ""]
|
||||||
|
fn release(
|
||||||
|
_node: Arc<Node>,
|
||||||
|
_calling_client: Arc<Client>,
|
||||||
|
_fds: Vec<OwnedFd>,
|
||||||
|
spatial: Arc<Node>,
|
||||||
|
) -> color_eyre::eyre::Result<()> {
|
||||||
|
let spatial = get_spatial(&spatial, "Spatial")?;
|
||||||
|
release(&spatial);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
impl Drop for Zone {
|
impl Drop for Zone {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
@@ -159,27 +172,3 @@ impl Drop for Zone {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_zone_flex(
|
|
||||||
_node: Arc<Node>,
|
|
||||||
calling_client: Arc<Client>,
|
|
||||||
message: Message,
|
|
||||||
) -> Result<()> {
|
|
||||||
#[derive(Deserialize)]
|
|
||||||
struct CreateZoneInfo<'a> {
|
|
||||||
name: &'a str,
|
|
||||||
parent_path: &'a str,
|
|
||||||
transform: Transform,
|
|
||||||
field_path: &'a str,
|
|
||||||
}
|
|
||||||
let info: CreateZoneInfo = deserialize(message.as_ref())?;
|
|
||||||
let parent = find_spatial_parent(&calling_client, info.parent_path)?;
|
|
||||||
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 space = Spatial::add_to(&node, Some(parent), transform, false)?;
|
|
||||||
Zone::add_to(&node, space, &field);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user