feat: initial IDL
This commit is contained in:
85
Cargo.lock
generated
85
Cargo.lock
generated
@@ -502,6 +502,15 @@ dependencies = [
|
||||
"tracing-subscriber",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "convert_case"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca"
|
||||
dependencies = [
|
||||
"unicode-segmentation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crc32fast"
|
||||
version = "1.3.2"
|
||||
@@ -582,7 +591,7 @@ version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412"
|
||||
dependencies = [
|
||||
"libloading 0.7.4",
|
||||
"libloading 0.8.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1090,6 +1099,17 @@ version = "1.0.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38"
|
||||
|
||||
[[package]]
|
||||
name = "kdl"
|
||||
version = "4.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "062c875482ccb676fd40c804a40e3824d4464c18c364547456d1c8e8e951ae47"
|
||||
dependencies = [
|
||||
"miette",
|
||||
"nom",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "khronos_api"
|
||||
version = "3.1.0"
|
||||
@@ -1226,6 +1246,29 @@ dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "miette"
|
||||
version = "5.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "59bb584eaeeab6bd0226ccf3509a69d7936d148cf3d036ad350abe35e8c6856e"
|
||||
dependencies = [
|
||||
"miette-derive",
|
||||
"once_cell",
|
||||
"thiserror",
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "miette-derive"
|
||||
version = "5.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49e7bc1560b95a3c4a25d03de42fe76ca718ab92d1a22a55b9b4cf67b3ae635c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.37",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mime"
|
||||
version = "0.3.17"
|
||||
@@ -1616,9 +1659,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.67"
|
||||
version = "1.0.78"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328"
|
||||
checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
@@ -2011,10 +2054,16 @@ dependencies = [
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "split-iter"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2f2b15926089e5526bb2dd738a2eb0e59034356e06eb71e1cd912358c0e62c4d"
|
||||
|
||||
[[package]]
|
||||
name = "stardust-xr"
|
||||
version = "0.14.1"
|
||||
source = "git+https://github.com/StardustXR/core.git#975331f9739a9f6cb90ec75813b7720c86225848"
|
||||
source = "git+https://github.com/StardustXR/core.git?branch=feat/idl#c7e27806c671d0ad262801583ec30acbf710a143"
|
||||
dependencies = [
|
||||
"cluFlock",
|
||||
"color-rs",
|
||||
@@ -2034,11 +2083,12 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "stardust-xr-schemas"
|
||||
version = "1.5.3"
|
||||
source = "git+https://github.com/StardustXR/core.git#975331f9739a9f6cb90ec75813b7720c86225848"
|
||||
source = "git+https://github.com/StardustXR/core.git?branch=feat/idl#c7e27806c671d0ad262801583ec30acbf710a143"
|
||||
dependencies = [
|
||||
"flatbuffers",
|
||||
"flexbuffers",
|
||||
"glam 0.24.2",
|
||||
"kdl",
|
||||
"manifest-dir-macros",
|
||||
"mint",
|
||||
"ouroboros",
|
||||
@@ -2077,6 +2127,7 @@ dependencies = [
|
||||
"serde_repr",
|
||||
"smithay",
|
||||
"stardust-xr",
|
||||
"stardust-xr-server-codegen",
|
||||
"stereokit",
|
||||
"tokio",
|
||||
"tracing",
|
||||
@@ -2087,6 +2138,18 @@ dependencies = [
|
||||
"xkbcommon",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "stardust-xr-server-codegen"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"convert_case",
|
||||
"mint",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"split-iter",
|
||||
"stardust-xr-schemas",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "static_assertions"
|
||||
version = "1.1.0"
|
||||
@@ -2446,6 +2509,18 @@ version = "1.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-segmentation"
|
||||
version = "1.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.1.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85"
|
||||
|
||||
[[package]]
|
||||
name = "utf8parse"
|
||||
version = "0.2.1"
|
||||
|
||||
@@ -8,6 +8,9 @@ license = "GPLv2"
|
||||
repository = "https://github.com/StardustXR/stardust-xr-server/"
|
||||
homepage = "https://stardustxr.org"
|
||||
|
||||
[workspace]
|
||||
members = ["codegen"]
|
||||
|
||||
[[bin]]
|
||||
name = "stardust-xr-server"
|
||||
path = "src/main.rs"
|
||||
@@ -98,6 +101,10 @@ optional = true
|
||||
|
||||
[dependencies.stardust-xr]
|
||||
git = "https://github.com/StardustXR/core.git"
|
||||
branch = "feat/idl"
|
||||
|
||||
[dependencies.stardust-xr-server-codegen]
|
||||
path = "codegen"
|
||||
|
||||
# [patch.crates-io.stereokit]
|
||||
# path = "../stereokit-rs"
|
||||
|
||||
18
codegen/Cargo.toml
Normal file
18
codegen/Cargo.toml
Normal file
@@ -0,0 +1,18 @@
|
||||
[package]
|
||||
edition = "2021"
|
||||
name = "stardust-xr-server-codegen"
|
||||
version = "0.1.0"
|
||||
|
||||
[lib]
|
||||
proc-macro = true
|
||||
|
||||
[dependencies]
|
||||
convert_case = "0.6.0"
|
||||
quote = "1.0.33"
|
||||
mint = "0.5.9"
|
||||
proc-macro2 = "1.0.71"
|
||||
split-iter = "0.1.0"
|
||||
|
||||
[dependencies.stardust-xr-schemas]
|
||||
git = "https://github.com/StardustXR/core.git"
|
||||
branch = "feat/idl"
|
||||
610
codegen/src/lib.rs
Normal file
610
codegen/src/lib.rs
Normal file
@@ -0,0 +1,610 @@
|
||||
use convert_case::{Case, Casing};
|
||||
use proc_macro2::{Ident, Span, TokenStream};
|
||||
use quote::{quote, ToTokens};
|
||||
use split_iter::Splittable;
|
||||
use stardust_xr_schemas::protocol::*;
|
||||
|
||||
fn fold_tokens(a: TokenStream, b: TokenStream) -> TokenStream {
|
||||
quote!(#a #b)
|
||||
}
|
||||
|
||||
// #[proc_macro]
|
||||
// pub fn codegen_root_protocol(_input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||
// codegen_protocol(ROOT_PROTOCOL)
|
||||
// }
|
||||
#[proc_macro]
|
||||
pub fn codegen_node_protocol(_input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||
codegen_protocol(NODE_PROTOCOL)
|
||||
}
|
||||
#[proc_macro]
|
||||
pub fn codegen_spatial_protocol(_input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||
codegen_protocol(SPATIAL_PROTOCOL)
|
||||
}
|
||||
#[proc_macro]
|
||||
pub fn codegen_field_protocol(_input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||
codegen_protocol(FIELD_PROTOCOL)
|
||||
}
|
||||
#[proc_macro]
|
||||
pub fn codegen_data_protocol(_input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||
codegen_protocol(DATA_PROTOCOL)
|
||||
}
|
||||
#[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 {
|
||||
codegen_protocol(AUDIO_PROTOCOL)
|
||||
}
|
||||
#[proc_macro]
|
||||
pub fn codegen_drawable_protocol(_input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||
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]
|
||||
// pub fn codegen_input_protocol(_input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||
// codegen_protocol(INPUT_PROTOCOL)
|
||||
// }
|
||||
|
||||
fn codegen_protocol(protocol: &'static str) -> proc_macro::TokenStream {
|
||||
let protocol = Protocol::parse(protocol).unwrap();
|
||||
let custom_enums = protocol
|
||||
.custom_enums
|
||||
.iter()
|
||||
.map(generate_custom_enum)
|
||||
.reduce(fold_tokens)
|
||||
.unwrap_or_default();
|
||||
let custom_unions = protocol
|
||||
.custom_unions
|
||||
.iter()
|
||||
.map(generate_custom_union)
|
||||
.reduce(fold_tokens)
|
||||
.unwrap_or_default();
|
||||
let custom_structs = protocol
|
||||
.custom_structs
|
||||
.iter()
|
||||
.map(generate_custom_struct)
|
||||
.reduce(fold_tokens)
|
||||
.unwrap_or_default();
|
||||
// let aspects = protocol
|
||||
// .aspects
|
||||
// .iter()
|
||||
// .map(generate_aspect)
|
||||
// .reduce(fold_tokens)
|
||||
// .unwrap_or_default();
|
||||
// let nodes = protocol
|
||||
// .nodes
|
||||
// .iter()
|
||||
// .map(generate_node)
|
||||
// .reduce(fold_tokens)
|
||||
// .unwrap_or_default();
|
||||
// let interfaces = protocol
|
||||
// .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).into()
|
||||
}
|
||||
|
||||
fn generate_custom_enum(custom_enum: &CustomEnum) -> TokenStream {
|
||||
let name = Ident::new(&custom_enum.name.to_case(Case::Pascal), Span::call_site());
|
||||
let description = &custom_enum.description;
|
||||
|
||||
let argument_decls = custom_enum
|
||||
.variants
|
||||
.iter()
|
||||
.map(|a| Ident::new(&a.to_case(Case::Pascal), Span::call_site()).to_token_stream())
|
||||
.reduce(|a, b| quote!(#a, #b))
|
||||
.unwrap_or_default();
|
||||
|
||||
quote! {
|
||||
#[doc = #description]
|
||||
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
|
||||
pub enum #name {#argument_decls}
|
||||
}
|
||||
}
|
||||
fn generate_custom_union(custom_union: &CustomUnion) -> TokenStream {
|
||||
let name = Ident::new(&custom_union.name.to_case(Case::Pascal), Span::call_site());
|
||||
let description = &custom_union.description;
|
||||
|
||||
let option_decls = custom_union
|
||||
.options
|
||||
.iter()
|
||||
.map(generate_union_option)
|
||||
.reduce(|a, b| quote!(#a, #b))
|
||||
.unwrap_or_default();
|
||||
|
||||
quote! {
|
||||
#[doc = #description]
|
||||
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum #name {#option_decls}
|
||||
}
|
||||
}
|
||||
fn generate_union_option(union_option: &UnionOption) -> TokenStream {
|
||||
let name = union_option
|
||||
.name
|
||||
.as_ref()
|
||||
.map(|n| n.to_case(Case::Pascal))
|
||||
.unwrap_or_else(|| argument_type_option_name(&union_option._type));
|
||||
let description = union_option
|
||||
.description
|
||||
.as_ref()
|
||||
.map(|d| quote!(#[doc = #d]))
|
||||
.unwrap_or_default();
|
||||
let identifier = Ident::new(&name, Span::call_site());
|
||||
let _type = generate_argument_type(&union_option._type, true);
|
||||
quote! (#description #identifier(#_type))
|
||||
}
|
||||
fn argument_type_option_name(argument_type: &ArgumentType) -> String {
|
||||
match argument_type {
|
||||
ArgumentType::Bool => "Bool".to_string(),
|
||||
ArgumentType::Int => "Int".to_string(),
|
||||
ArgumentType::UInt => "UInt".to_string(),
|
||||
ArgumentType::Float => "Float".to_string(),
|
||||
ArgumentType::Vec2 => "Vec2".to_string(),
|
||||
ArgumentType::Vec3 => "Vec3".to_string(),
|
||||
ArgumentType::Quat => "Quat".to_string(),
|
||||
ArgumentType::Color => "Color".to_string(),
|
||||
ArgumentType::String => "String".to_string(),
|
||||
ArgumentType::Bytes => "Bytes".to_string(),
|
||||
ArgumentType::Vec(v) => format!("{}Vector", argument_type_option_name(&v)),
|
||||
ArgumentType::Map(m) => format!("{}Map", argument_type_option_name(&m)),
|
||||
ArgumentType::Datamap => "Datamap".to_string(),
|
||||
ArgumentType::ResourceID => "ResourceID".to_string(),
|
||||
ArgumentType::Enum(e) => e.clone(),
|
||||
ArgumentType::Union(u) => u.clone(),
|
||||
ArgumentType::Struct(s) => s.clone(),
|
||||
ArgumentType::Node { _type, .. } => _type.clone(),
|
||||
}
|
||||
}
|
||||
fn generate_custom_struct(custom_struct: &CustomStruct) -> TokenStream {
|
||||
let name = Ident::new(&custom_struct.name.to_case(Case::Pascal), Span::call_site());
|
||||
let description = &custom_struct.description;
|
||||
|
||||
let argument_decls = custom_struct
|
||||
.fields
|
||||
.iter()
|
||||
.map(|a| generate_argument_decl(a, true))
|
||||
.reduce(|a, b| quote!(#a, #b))
|
||||
.unwrap_or_default();
|
||||
|
||||
quote! {
|
||||
#[doc = #description]
|
||||
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
|
||||
pub struct #name {#argument_decls}
|
||||
}
|
||||
}
|
||||
|
||||
fn generate_interface(interface: &Interface) -> TokenStream {
|
||||
interface
|
||||
.members
|
||||
.iter()
|
||||
.map(generate_member)
|
||||
.reduce(fold_tokens)
|
||||
.unwrap_or_default()
|
||||
}
|
||||
|
||||
fn generate_node(node: &Node) -> TokenStream {
|
||||
let node_name = Ident::new(&node.name, Span::call_site());
|
||||
let description = &node.description;
|
||||
|
||||
let aspects = node
|
||||
.aspects
|
||||
.iter()
|
||||
.map(|a| {
|
||||
let aspect_name = Ident::new(&format!("{a}Aspect"), Span::call_site());
|
||||
quote!(impl #aspect_name for #node_name {})
|
||||
})
|
||||
.reduce(fold_tokens)
|
||||
.unwrap_or_default();
|
||||
|
||||
quote! {
|
||||
#[doc = #description]
|
||||
#[derive(Debug)]
|
||||
pub struct #node_name (crate::node::Node);
|
||||
impl crate::node::NodeType for #node_name {
|
||||
fn node(&self) -> &crate::node::Node {
|
||||
&self.0
|
||||
}
|
||||
fn alias(&self) -> Self {
|
||||
#node_name(self.0.alias())
|
||||
}
|
||||
fn from_path(client: &std::sync::Arc<crate::client::Client>, path: String, destroyable: bool) -> Self {
|
||||
#node_name(crate::node::Node::from_path(client, path, destroyable))
|
||||
}
|
||||
}
|
||||
impl serde::Serialize for #node_name {
|
||||
fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
||||
let node_path = self.0.get_path().map_err(|e| serde::ser::Error::custom(e))?;
|
||||
serializer.serialize_str(&node_path)
|
||||
}
|
||||
}
|
||||
#aspects
|
||||
}
|
||||
}
|
||||
|
||||
fn generate_aspect(aspect: &Aspect) -> TokenStream {
|
||||
let description = &aspect.description;
|
||||
let (client_members, server_members) = aspect.members.iter().split(|m| m.side == Side::Server);
|
||||
|
||||
let aspect_handler_name = Ident::new(
|
||||
&format!("{}Handler", &aspect.name.to_case(Case::Pascal)),
|
||||
Span::call_site(),
|
||||
);
|
||||
let client_side_members = client_members
|
||||
.map(generate_member)
|
||||
.reduce(fold_tokens)
|
||||
.map(|t| {
|
||||
quote! {
|
||||
#[doc = #description]
|
||||
pub trait #aspect_handler_name: Send + Sync + 'static {
|
||||
#t
|
||||
}
|
||||
}
|
||||
})
|
||||
.unwrap_or_default();
|
||||
let aspect_wrap = aspect
|
||||
.members
|
||||
.iter()
|
||||
.filter(|m| m.side == Side::Client)
|
||||
.map(generate_handler)
|
||||
.reduce(fold_tokens).map(|handlers| {
|
||||
quote! {
|
||||
#[must_use = "Dropping this handler wrapper would immediately drop the handler"]
|
||||
fn wrap<H: #aspect_handler_name>(self, handler: H) -> NodeResult<crate::HandlerWrapper<Self, H>> {
|
||||
self.wrap_raw(std::sync::Arc::new(parking_lot::Mutex::new(handler)))
|
||||
}
|
||||
#[must_use = "Dropping this handler wrapper would immediately drop the handler"]
|
||||
fn wrap_raw<H: #aspect_handler_name>(self, handler: std::sync::Arc<parking_lot::Mutex<H>>) -> NodeResult<crate::HandlerWrapper<Self, H>> {
|
||||
let handler_wrapper = crate::HandlerWrapper::new_raw(self, handler);
|
||||
#handlers
|
||||
Ok(handler_wrapper)
|
||||
}
|
||||
}
|
||||
}).unwrap_or_default();
|
||||
|
||||
let aspect_trait_name = Ident::new(
|
||||
&format!("{}Aspect", &aspect.name.to_case(Case::Pascal)),
|
||||
Span::call_site(),
|
||||
);
|
||||
let server_side_members = server_members
|
||||
.map(generate_member)
|
||||
.reduce(fold_tokens)
|
||||
.unwrap_or_default();
|
||||
let server_side_members = quote! {
|
||||
#[doc = #description]
|
||||
pub trait #aspect_trait_name: crate::node::NodeType {
|
||||
#aspect_wrap
|
||||
#server_side_members
|
||||
}
|
||||
};
|
||||
quote!(#client_side_members #server_side_members)
|
||||
}
|
||||
|
||||
fn generate_member(member: &Member) -> TokenStream {
|
||||
let name_str = &member.name;
|
||||
let name = Ident::new(&member.name.to_case(Case::Snake), Span::call_site());
|
||||
let description = &member.description;
|
||||
|
||||
let side = member.side;
|
||||
let _type = member._type;
|
||||
|
||||
let first_arg = if member.interface_path.is_some() {
|
||||
quote!(client: &std::sync::Arc<crate::client::Client>)
|
||||
} else {
|
||||
if member.side == Side::Server {
|
||||
quote!(&self)
|
||||
} else {
|
||||
quote!(&mut self)
|
||||
}
|
||||
};
|
||||
let argument_decls = member
|
||||
.arguments
|
||||
.iter()
|
||||
.map(|a| generate_argument_decl(a, member.side == Side::Client))
|
||||
.fold(first_arg, |a, b| quote!(#a, #b));
|
||||
|
||||
let argument_uses = member
|
||||
.arguments
|
||||
.iter()
|
||||
.map(|a| generate_argument_serialize(&a.name, &a._type, a.optional))
|
||||
.reduce(|a, b| quote!(#a, #b))
|
||||
.unwrap_or_default();
|
||||
let return_type = member
|
||||
.return_type
|
||||
.as_ref()
|
||||
.map(|r| generate_argument_type(&r, true))
|
||||
.unwrap_or_else(|| quote!(()));
|
||||
|
||||
match (side, _type) {
|
||||
(Side::Server, 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! {
|
||||
#[doc = #description]
|
||||
async fn #name(#argument_decls) -> crate::node::NodeResult<#return_type> {
|
||||
#body
|
||||
}
|
||||
}
|
||||
}
|
||||
(Side::Server, MemberType::Signal) => {
|
||||
let mut 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))
|
||||
}
|
||||
};
|
||||
body = if let Some(ArgumentType::Node {
|
||||
_type: _,
|
||||
return_info,
|
||||
}) = &member.return_type
|
||||
{
|
||||
if let Some(return_info) = return_info {
|
||||
let parent = &return_info.parent;
|
||||
let name_argument = Ident::new(&return_info.name_argument, Span::call_site());
|
||||
let get_client = if member.interface_path.is_some() {
|
||||
quote!(client)
|
||||
} else {
|
||||
quote!(self.node().client()?)
|
||||
};
|
||||
quote! {
|
||||
#body?;
|
||||
Ok(<#return_type as crate::node::NodeType>::from_parent_name(#get_client, #parent, &#name_argument, true))
|
||||
}
|
||||
} else {
|
||||
quote! {
|
||||
Ok(#body?)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
quote! {
|
||||
Ok(#body?)
|
||||
}
|
||||
};
|
||||
quote! {
|
||||
#[doc = #description]
|
||||
fn #name(#argument_decls) -> crate::node::NodeResult<#return_type> {
|
||||
#body
|
||||
}
|
||||
}
|
||||
}
|
||||
(Side::Client, MemberType::Method) => {
|
||||
quote! {
|
||||
#[doc = #description]
|
||||
fn #name(#argument_decls) -> crate::node::MethodResult<#return_type>;
|
||||
}
|
||||
}
|
||||
(Side::Client, MemberType::Signal) => {
|
||||
quote! {
|
||||
#[doc = #description]
|
||||
fn #name(#argument_decls);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fn generate_handler(member: &Member) -> TokenStream {
|
||||
let name = &member.name;
|
||||
let name_ident = Ident::new(&name, Span::call_site());
|
||||
|
||||
let argument_names = member
|
||||
.arguments
|
||||
.iter()
|
||||
.map(generate_argument_name)
|
||||
.reduce(|a, b| quote!(#a, #b));
|
||||
let argument_types = member
|
||||
.arguments
|
||||
.iter()
|
||||
.map(|a| &a._type)
|
||||
.map(convert_deserializeable_argument_type)
|
||||
.map(|a| generate_argument_type(&a, true))
|
||||
.reduce(|a, b| quote!(#a, #b));
|
||||
// dbg!(&argument_types);
|
||||
let deserialize = argument_names
|
||||
.clone()
|
||||
.zip(argument_types)
|
||||
.map(|(argument_names, argument_types)| {
|
||||
quote!(let (#argument_names): (#argument_types) = stardust_xr::schemas::flex::deserialize(_data)?;)
|
||||
})
|
||||
.unwrap_or_default();
|
||||
let argument_uses = member
|
||||
.arguments
|
||||
.iter()
|
||||
.map(|a| generate_argument_deserialize(&a.name, &a._type, a.optional))
|
||||
.fold(TokenStream::default(), |a, b| quote!(#a, #b));
|
||||
let handler_wrapper_method_name = match member._type {
|
||||
MemberType::Signal => quote!(add_handled_signal),
|
||||
MemberType::Method => quote!(add_handled_method),
|
||||
};
|
||||
|
||||
quote! {
|
||||
handler_wrapper.#handler_wrapper_method_name(#name, |_node, _handler, _data, _fds| {
|
||||
#deserialize
|
||||
let _client = _node.client()?;
|
||||
let mut _handler_lock = _handler.lock();
|
||||
Ok(H::#name_ident(&mut *_handler_lock #argument_uses))
|
||||
})?;
|
||||
}
|
||||
}
|
||||
fn generate_argument_name(argument: &Argument) -> TokenStream {
|
||||
Ident::new(&argument.name.to_case(Case::Snake), Span::call_site()).to_token_stream()
|
||||
}
|
||||
fn generate_argument_deserialize(
|
||||
argument_name: &str,
|
||||
argument_type: &ArgumentType,
|
||||
optional: bool,
|
||||
) -> TokenStream {
|
||||
let name = Ident::new(&argument_name.to_case(Case::Snake), Span::call_site());
|
||||
match argument_type {
|
||||
ArgumentType::Node {
|
||||
_type,
|
||||
return_info: _,
|
||||
} => {
|
||||
let node_type = Ident::new(&_type.to_case(Case::Pascal), Span::call_site());
|
||||
match optional {
|
||||
true => quote!(#name.map(|n| #node_type::from_path(&_client, n, false))),
|
||||
false => quote!(#node_type::from_path(&_client, #name, false)),
|
||||
}
|
||||
}
|
||||
ArgumentType::Color => quote!(color::rgba_linear!(#name[0], #name[1], #name[2], #name[3])),
|
||||
ArgumentType::Vec(v) => {
|
||||
let mapping = generate_argument_deserialize("a", v, false);
|
||||
quote!(#name.iter().map(|a| Ok(#mapping)).collect::<Result<Vec<_>, crate::node::NodeError>>()?)
|
||||
}
|
||||
ArgumentType::Map(v) => {
|
||||
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),
|
||||
}
|
||||
}
|
||||
fn convert_deserializeable_argument_type(argument_type: &ArgumentType) -> ArgumentType {
|
||||
match argument_type {
|
||||
ArgumentType::Node { .. } => ArgumentType::String,
|
||||
f => f.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
fn generate_argument_serialize(
|
||||
argument_name: &str,
|
||||
argument_type: &ArgumentType,
|
||||
optional: bool,
|
||||
) -> TokenStream {
|
||||
let name = Ident::new(&argument_name.to_case(Case::Snake), Span::call_site());
|
||||
match argument_type {
|
||||
ArgumentType::Node {
|
||||
_type,
|
||||
return_info: _,
|
||||
} => match optional {
|
||||
true => quote!(#name.map(|n| n.node().get_path()).transpose()?),
|
||||
false => quote!(#name.node().get_path()?),
|
||||
},
|
||||
ArgumentType::Color => quote!([#name.c.r, #name.c.g, #name.c.b, #name.a]),
|
||||
ArgumentType::Vec(v) => {
|
||||
let mapping = generate_argument_serialize("a", v, false);
|
||||
quote!(#name.iter().map(|a| Ok(#mapping)).collect::<Result<Vec<_>, crate::node::NodeError>>()?)
|
||||
}
|
||||
ArgumentType::Map(v) => {
|
||||
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),
|
||||
}
|
||||
}
|
||||
fn generate_argument_decl(argument: &Argument, returned: bool) -> TokenStream {
|
||||
let name = Ident::new(&argument.name.to_case(Case::Snake), Span::call_site());
|
||||
let mut _type = generate_argument_type(&argument._type, returned);
|
||||
if argument.optional {
|
||||
_type = quote!(Option<#_type>);
|
||||
}
|
||||
quote!(#name: #_type)
|
||||
}
|
||||
fn generate_argument_type(argument_type: &ArgumentType, owned: bool) -> TokenStream {
|
||||
match argument_type {
|
||||
ArgumentType::Bool => quote!(bool),
|
||||
ArgumentType::Int => quote!(i32),
|
||||
ArgumentType::UInt => quote!(u32),
|
||||
ArgumentType::Float => quote!(f32),
|
||||
ArgumentType::Vec2 => quote!(mint::Vector2<f32>),
|
||||
ArgumentType::Vec3 => quote!(mint::Vector3<f32>),
|
||||
ArgumentType::Quat => quote!(mint::Quaternion<f32>),
|
||||
ArgumentType::Color => quote!(stardust_xr::values::Color),
|
||||
ArgumentType::Bytes => {
|
||||
if !owned {
|
||||
quote!(&[u8])
|
||||
} else {
|
||||
quote!(Vec<u8>)
|
||||
}
|
||||
}
|
||||
ArgumentType::String => {
|
||||
if !owned {
|
||||
quote!(&str)
|
||||
} else {
|
||||
quote!(String)
|
||||
}
|
||||
}
|
||||
ArgumentType::Vec(t) => {
|
||||
let t = generate_argument_type(&t, true);
|
||||
if !owned {
|
||||
quote!(&[#t])
|
||||
} else {
|
||||
quote!(Vec<#t>)
|
||||
}
|
||||
}
|
||||
ArgumentType::Map(t) => {
|
||||
let t = generate_argument_type(&t, true);
|
||||
|
||||
if !owned {
|
||||
quote!(&rustc_hash::FxHashMap<String, #t>)
|
||||
} else {
|
||||
quote!(rustc_hash::FxHashMap<String, #t>)
|
||||
}
|
||||
}
|
||||
ArgumentType::Datamap => {
|
||||
if !owned {
|
||||
quote!(&stardust_xr::values::Datamap)
|
||||
} else {
|
||||
quote!(stardust_xr::values::Datamap)
|
||||
}
|
||||
}
|
||||
ArgumentType::ResourceID => {
|
||||
if !owned {
|
||||
quote!(&stardust_xr::values::ResourceID)
|
||||
} else {
|
||||
quote!(stardust_xr::values::ResourceID)
|
||||
}
|
||||
}
|
||||
ArgumentType::Enum(e) => {
|
||||
let enum_name = Ident::new(&e.to_case(Case::Pascal), Span::call_site());
|
||||
quote!(#enum_name)
|
||||
}
|
||||
ArgumentType::Union(u) => {
|
||||
let union_name = Ident::new(&u.to_case(Case::Pascal), Span::call_site());
|
||||
quote!(#union_name)
|
||||
}
|
||||
ArgumentType::Struct(s) => {
|
||||
let struct_name = Ident::new(&s.to_case(Case::Pascal), Span::call_site());
|
||||
quote!(#struct_name)
|
||||
}
|
||||
ArgumentType::Node {
|
||||
_type,
|
||||
return_info: _,
|
||||
} => {
|
||||
if !owned {
|
||||
let aspect = Ident::new(
|
||||
&format!("{}Aspect", _type.to_case(Case::Pascal)),
|
||||
Span::call_site(),
|
||||
);
|
||||
quote!(&impl #aspect)
|
||||
} else {
|
||||
let node = Ident::new(&_type.to_case(Case::Pascal), Span::call_site());
|
||||
quote!(#node)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,4 +8,3 @@ pub mod registry;
|
||||
pub mod resource;
|
||||
pub mod scenegraph;
|
||||
pub mod task;
|
||||
pub mod typed_datamap;
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
#![allow(unused)]
|
||||
|
||||
use std::ops::{Deref, DerefMut};
|
||||
|
||||
use color_eyre::eyre::Result;
|
||||
use once_cell::sync::Lazy;
|
||||
use serde::{de::DeserializeOwned, Serialize};
|
||||
use stardust_xr::schemas::{
|
||||
flat::Datamap,
|
||||
flex::flexbuffers::{FlexbufferSerializer, Reader, ReaderError},
|
||||
};
|
||||
|
||||
use crate::nodes::Message;
|
||||
|
||||
pub struct TypedDatamap<T: DeserializeOwned + Serialize>(T);
|
||||
impl<T: DeserializeOwned + Serialize> TypedDatamap<T> {
|
||||
pub fn new(data: T) -> Self {
|
||||
TypedDatamap(data)
|
||||
}
|
||||
pub fn from_flex(message: Message) -> Result<Self> {
|
||||
let root = Reader::get_root(message.as_ref())?;
|
||||
T::deserialize(root).map(Self::new).map_err(|e| e.into())
|
||||
}
|
||||
pub fn to_datamap(&mut self) -> Result<Datamap> {
|
||||
let mut serializer = FlexbufferSerializer::default();
|
||||
self.0.serialize(&mut serializer)?;
|
||||
Datamap::new(serializer.take_buffer()).map_err(|e| e.into())
|
||||
}
|
||||
pub fn serialize(&mut self) -> Option<Vec<u8>> {
|
||||
let mut serializer = FlexbufferSerializer::default();
|
||||
self.0.serialize(&mut serializer).ok()?;
|
||||
// check if this is actually a map
|
||||
Reader::get_root(serializer.view()).ok()?.get_map().ok()?;
|
||||
Some(serializer.take_buffer())
|
||||
}
|
||||
}
|
||||
impl<T: DeserializeOwned + Serialize> Default for TypedDatamap<T>
|
||||
where
|
||||
T: Default,
|
||||
{
|
||||
fn default() -> Self {
|
||||
Self(T::default())
|
||||
}
|
||||
}
|
||||
impl<T: DeserializeOwned + Serialize> Deref for TypedDatamap<T> {
|
||||
type Target = T;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
impl<T: DeserializeOwned + Serialize> DerefMut for TypedDatamap<T> {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
&mut self.0
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@ use crate::core::client::Client;
|
||||
use crate::core::destroy_queue;
|
||||
use crate::core::registry::Registry;
|
||||
use crate::core::resource::ResourceID;
|
||||
use crate::nodes::spatial::{find_spatial_parent, parse_transform, Spatial};
|
||||
use crate::nodes::spatial::{find_spatial_parent, parse_transform, Spatial, Transform};
|
||||
use color_eyre::eyre::{ensure, eyre, Result};
|
||||
use glam::{vec3, Vec4Swizzles};
|
||||
use once_cell::sync::OnceCell;
|
||||
@@ -11,7 +11,7 @@ use parking_lot::Mutex;
|
||||
use send_wrapper::SendWrapper;
|
||||
use serde::Deserialize;
|
||||
use stardust_xr::schemas::flex::deserialize;
|
||||
use stardust_xr::values::Transform;
|
||||
|
||||
use std::ops::DerefMut;
|
||||
use std::{ffi::OsStr, path::PathBuf, sync::Arc};
|
||||
use stereokit::{Sound as SkSound, SoundInstance, StereoKitDraw};
|
||||
|
||||
@@ -7,7 +7,7 @@ use crate::core::node_collections::LifeLinkedNodeMap;
|
||||
use crate::core::registry::Registry;
|
||||
use crate::core::scenegraph::MethodResponseSender;
|
||||
use crate::nodes::fields::{find_field, FIELD_ALIAS_INFO};
|
||||
use crate::nodes::spatial::find_spatial_parent;
|
||||
use crate::nodes::spatial::{find_spatial_parent, Transform};
|
||||
use color_eyre::eyre::{bail, ensure, eyre, Result};
|
||||
use glam::vec3a;
|
||||
use lazy_static::lazy_static;
|
||||
@@ -17,7 +17,7 @@ use parking_lot::Mutex;
|
||||
use rustc_hash::FxHashMap;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use stardust_xr::schemas::flex::{deserialize, flexbuffers, serialize};
|
||||
use stardust_xr::values::Transform;
|
||||
|
||||
use std::fmt::Display;
|
||||
use std::sync::{Arc, Weak};
|
||||
|
||||
@@ -111,9 +111,15 @@ impl PulseSender {
|
||||
if !mask_matches(&self.mask, &receiver.mask) {
|
||||
return;
|
||||
}
|
||||
let Some(tx_node) = self.node.upgrade() else {return};
|
||||
let Some(tx_client) = tx_node.get_client() else {return};
|
||||
let Some(rx_node) = receiver.node.upgrade() else {return};
|
||||
let Some(tx_node) = self.node.upgrade() else {
|
||||
return;
|
||||
};
|
||||
let Some(tx_client) = tx_node.get_client() else {
|
||||
return;
|
||||
};
|
||||
let Some(rx_node) = receiver.node.upgrade() else {
|
||||
return;
|
||||
};
|
||||
// Receiver itself
|
||||
let rx_alias = Alias::create(
|
||||
&tx_client,
|
||||
@@ -167,7 +173,7 @@ impl PulseSender {
|
||||
rotation: rotation.into(),
|
||||
};
|
||||
|
||||
let Ok(data) = serialize(info) else {return};
|
||||
let Ok(data) = serialize(info) else { return };
|
||||
let _ = tx_node.send_remote_signal("new_receiver", data);
|
||||
}
|
||||
|
||||
@@ -175,8 +181,10 @@ impl PulseSender {
|
||||
let uid = receiver.uid.as_str();
|
||||
self.aliases.remove(uid);
|
||||
self.aliases.remove(&(uid.to_string() + "-field"));
|
||||
let Some(tx_node) = self.node.upgrade() else {return};
|
||||
let Ok(data) = serialize(&uid) else {return};
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -348,7 +356,9 @@ pub fn get_keymap_flex(
|
||||
response.wrap_sync(move || {
|
||||
let keymap_id: &str = deserialize(message.as_ref())?;
|
||||
let keymaps = KEYMAPS.lock();
|
||||
let Some(keymap) = keymaps.get(keymap_id) else {bail!("Could not find keymap. Try registering it")};
|
||||
let Some(keymap) = keymaps.get(keymap_id) else {
|
||||
bail!("Could not find keymap. Try registering it")
|
||||
};
|
||||
|
||||
Ok(serialize(keymap)?.into())
|
||||
});
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use crate::{
|
||||
core::{client::Client, registry::Registry},
|
||||
nodes::{
|
||||
spatial::{find_spatial_parent, parse_transform, Spatial},
|
||||
spatial::{find_spatial_parent, parse_transform, Spatial, Transform},
|
||||
Message, Node,
|
||||
},
|
||||
};
|
||||
@@ -12,7 +12,7 @@ use parking_lot::Mutex;
|
||||
use portable_atomic::{AtomicBool, Ordering};
|
||||
use prisma::{Flatten, Lerp, Rgba};
|
||||
use serde::Deserialize;
|
||||
use stardust_xr::{schemas::flex::deserialize, values::Transform};
|
||||
use stardust_xr::schemas::flex::deserialize;
|
||||
use std::{collections::VecDeque, sync::Arc};
|
||||
use stereokit::{bounds_grow_to_fit_pt, Bounds, Color128, LinePoint as SkLinePoint, StereoKitDraw};
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ use crate::core::node_collections::LifeLinkedNodeMap;
|
||||
use crate::core::registry::Registry;
|
||||
use crate::core::resource::ResourceID;
|
||||
use crate::nodes::drawable::Drawable;
|
||||
use crate::nodes::spatial::{find_spatial_parent, parse_transform, Spatial};
|
||||
use crate::nodes::spatial::{find_spatial_parent, parse_transform, Spatial, Transform};
|
||||
use crate::nodes::Message;
|
||||
use crate::SK_MULTITHREAD;
|
||||
use color_eyre::eyre::{bail, ensure, eyre, Result};
|
||||
@@ -16,7 +16,7 @@ use portable_atomic::{AtomicBool, Ordering};
|
||||
use rustc_hash::FxHashMap;
|
||||
use serde::Deserialize;
|
||||
use stardust_xr::schemas::flex::deserialize;
|
||||
use stardust_xr::values::Transform;
|
||||
|
||||
use std::ffi::OsStr;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::{Arc, Weak};
|
||||
|
||||
@@ -2,7 +2,7 @@ use crate::{
|
||||
core::{client::Client, destroy_queue, registry::Registry, resource::ResourceID},
|
||||
nodes::{
|
||||
drawable::Drawable,
|
||||
spatial::{find_spatial_parent, parse_transform, Spatial},
|
||||
spatial::{find_spatial_parent, parse_transform, Spatial, Transform},
|
||||
Message, Node,
|
||||
},
|
||||
};
|
||||
@@ -14,7 +14,7 @@ use parking_lot::Mutex;
|
||||
use portable_atomic::{AtomicBool, Ordering};
|
||||
use prisma::{Flatten, Rgba};
|
||||
use serde::Deserialize;
|
||||
use stardust_xr::{schemas::flex::deserialize, values::Transform};
|
||||
use stardust_xr::schemas::flex::deserialize;
|
||||
use std::{ffi::OsStr, path::PathBuf, sync::Arc};
|
||||
use stereokit::{named_colors::WHITE, Color128, StereoKitDraw, TextAlign, TextFit, TextStyle};
|
||||
|
||||
@@ -150,7 +150,9 @@ impl Text {
|
||||
_calling_client: Arc<Client>,
|
||||
message: Message,
|
||||
) -> Result<()> {
|
||||
let Some(Drawable::Text(text)) = node.drawable.get() else {bail!("Not a drawable??")};
|
||||
let Some(Drawable::Text(text)) = node.drawable.get() else {
|
||||
bail!("Not a drawable??")
|
||||
};
|
||||
|
||||
text.data.lock().character_height = deserialize(message.as_ref())?;
|
||||
Ok(())
|
||||
@@ -161,7 +163,9 @@ impl Text {
|
||||
_calling_client: Arc<Client>,
|
||||
message: Message,
|
||||
) -> Result<()> {
|
||||
let Some(Drawable::Text(text)) = node.drawable.get() else {bail!("Not a drawable??")};
|
||||
let Some(Drawable::Text(text)) = node.drawable.get() else {
|
||||
bail!("Not a drawable??")
|
||||
};
|
||||
|
||||
text.data.lock().text = deserialize(message.as_ref())?;
|
||||
Ok(())
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use super::{Field, FieldTrait, Node};
|
||||
use crate::core::client::Client;
|
||||
use crate::nodes::spatial::{find_spatial_parent, parse_transform, Spatial};
|
||||
use crate::nodes::spatial::{find_spatial_parent, parse_transform, Spatial, Transform};
|
||||
use crate::nodes::Message;
|
||||
use color_eyre::eyre::{ensure, Result};
|
||||
use glam::{vec3, vec3a, Vec3, Vec3A};
|
||||
@@ -8,7 +8,7 @@ use mint::Vector3;
|
||||
use parking_lot::Mutex;
|
||||
use serde::Deserialize;
|
||||
use stardust_xr::schemas::flex::deserialize;
|
||||
use stardust_xr::values::Transform;
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
pub struct BoxField {
|
||||
@@ -46,7 +46,9 @@ impl BoxField {
|
||||
_calling_client: Arc<Client>,
|
||||
message: Message,
|
||||
) -> Result<()> {
|
||||
let Field::Box(box_field) = node.field.get().unwrap().as_ref() else { return Ok(()) };
|
||||
let Field::Box(box_field) = node.field.get().unwrap().as_ref() else {
|
||||
return Ok(());
|
||||
};
|
||||
box_field.set_size(deserialize(message.as_ref())?);
|
||||
|
||||
Ok(())
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
use super::{Field, FieldTrait, Node};
|
||||
use crate::core::client::Client;
|
||||
use crate::nodes::spatial::{find_spatial_parent, parse_transform, Spatial};
|
||||
use crate::nodes::spatial::{find_spatial_parent, parse_transform, Spatial, Transform};
|
||||
use crate::nodes::Message;
|
||||
use color_eyre::eyre::{ensure, Result};
|
||||
use glam::{swizzles::*, vec2, Vec3A};
|
||||
use portable_atomic::AtomicF32;
|
||||
use serde::Deserialize;
|
||||
use stardust_xr::schemas::flex::deserialize;
|
||||
use stardust_xr::values::Transform;
|
||||
|
||||
use std::sync::atomic::Ordering;
|
||||
use std::sync::Arc;
|
||||
@@ -49,7 +48,9 @@ impl CylinderField {
|
||||
_calling_client: Arc<Client>,
|
||||
message: Message,
|
||||
) -> Result<()> {
|
||||
let Field::Cylinder(cylinder_field) = node.field.get().unwrap().as_ref() else { return Ok(()) };
|
||||
let Field::Cylinder(cylinder_field) = node.field.get().unwrap().as_ref() else {
|
||||
return Ok(());
|
||||
};
|
||||
let (length, radius) = deserialize(message.as_ref())?;
|
||||
cylinder_field.set_size(length, radius);
|
||||
Ok(())
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
use super::{Field, FieldTrait, Node};
|
||||
use crate::core::client::Client;
|
||||
use crate::nodes::spatial::{find_spatial_parent, parse_transform, Spatial};
|
||||
use crate::nodes::spatial::{find_spatial_parent, parse_transform, Spatial, Transform};
|
||||
use crate::nodes::Message;
|
||||
use color_eyre::eyre::{ensure, Result};
|
||||
use glam::{swizzles::*, vec2, Vec3A};
|
||||
use portable_atomic::AtomicF32;
|
||||
use serde::Deserialize;
|
||||
use stardust_xr::schemas::flex::deserialize;
|
||||
use stardust_xr::values::Transform;
|
||||
|
||||
use std::sync::atomic::Ordering;
|
||||
use std::sync::Arc;
|
||||
@@ -49,7 +48,9 @@ impl TorusField {
|
||||
_calling_client: Arc<Client>,
|
||||
message: Message,
|
||||
) -> Result<()> {
|
||||
let Field::Torus(torus_field) = node.field.get().unwrap().as_ref() else { return Ok(()) };
|
||||
let Field::Torus(torus_field) = node.field.get().unwrap().as_ref() else {
|
||||
return Ok(());
|
||||
};
|
||||
let (radius_a, radius_b) = deserialize(message.as_ref())?;
|
||||
torus_field.set_size(radius_a, radius_b);
|
||||
|
||||
|
||||
@@ -12,20 +12,19 @@ use super::{
|
||||
spatial::{find_spatial_parent, parse_transform, Spatial},
|
||||
Message, Node,
|
||||
};
|
||||
use crate::core::registry::Registry;
|
||||
use crate::core::{client::Client, node_collections::LifeLinkedNodeMap};
|
||||
use crate::{core::registry::Registry, nodes::spatial::Transform};
|
||||
use color_eyre::eyre::{ensure, Result};
|
||||
use glam::Mat4;
|
||||
use once_cell::sync::OnceCell;
|
||||
use parking_lot::Mutex;
|
||||
use portable_atomic::AtomicBool;
|
||||
use serde::Deserialize;
|
||||
use stardust_xr::schemas::{flat::InputData, flex::deserialize};
|
||||
use stardust_xr::schemas::{
|
||||
flat::{Datamap, InputDataType},
|
||||
flex::serialize,
|
||||
use stardust_xr::schemas::{flat::InputDataType, flex::serialize};
|
||||
use stardust_xr::{
|
||||
schemas::{flat::InputData, flex::deserialize},
|
||||
values::Datamap,
|
||||
};
|
||||
use stardust_xr::values::Transform;
|
||||
use std::ops::Deref;
|
||||
use std::sync::atomic::Ordering;
|
||||
use std::sync::{Arc, Weak};
|
||||
@@ -119,7 +118,10 @@ impl InputMethod {
|
||||
}
|
||||
fn set_datamap_flex(node: &Node, _calling_client: Arc<Client>, message: Message) -> Result<()> {
|
||||
let method = InputMethod::get(node)?;
|
||||
method.datamap.lock().replace(Datamap::new(message.data)?);
|
||||
method
|
||||
.datamap
|
||||
.lock()
|
||||
.replace(Datamap::from_raw(message.data)?);
|
||||
Ok(())
|
||||
}
|
||||
fn set_handlers_flex(node: &Node, calling_client: Arc<Client>, message: Message) -> Result<()> {
|
||||
@@ -139,9 +141,15 @@ impl InputMethod {
|
||||
}
|
||||
|
||||
fn make_alias(&self, handler: &InputHandler) {
|
||||
let Some(method_node) = self.node.upgrade() else {return};
|
||||
let Some(handler_node) = handler.node.upgrade() else {return};
|
||||
let Some(client) = handler_node.get_client() else {return};
|
||||
let Some(method_node) = self.node.upgrade() else {
|
||||
return;
|
||||
};
|
||||
let Some(handler_node) = handler.node.upgrade() else {
|
||||
return;
|
||||
};
|
||||
let Some(client) = handler_node.get_client() else {
|
||||
return;
|
||||
};
|
||||
let Ok(method_alias) = Alias::create(
|
||||
&client,
|
||||
handler_node.get_path(),
|
||||
@@ -151,7 +159,9 @@ impl InputMethod {
|
||||
server_signals: vec!["capture"],
|
||||
..Default::default()
|
||||
},
|
||||
) else {return};
|
||||
) else {
|
||||
return;
|
||||
};
|
||||
method_alias.enabled.store(false, Ordering::Relaxed);
|
||||
handler
|
||||
.method_aliases
|
||||
@@ -168,9 +178,15 @@ impl InputMethod {
|
||||
}
|
||||
|
||||
fn handle_new_handler(&self, handler: &InputHandler) {
|
||||
let Some(method_node) = self.node.upgrade() else {return};
|
||||
let Some(method_client) = method_node.get_client() else {return};
|
||||
let Some(handler_node) = handler.node.upgrade() else {return};
|
||||
let Some(method_node) = self.node.upgrade() else {
|
||||
return;
|
||||
};
|
||||
let Some(method_client) = method_node.get_client() else {
|
||||
return;
|
||||
};
|
||||
let Some(handler_node) = handler.node.upgrade() else {
|
||||
return;
|
||||
};
|
||||
// Receiver itself
|
||||
let Ok(handler_alias) = Alias::create(
|
||||
&method_client,
|
||||
@@ -181,32 +197,40 @@ impl InputMethod {
|
||||
server_methods: vec!["getTransform"],
|
||||
..Default::default()
|
||||
},
|
||||
) else {return};
|
||||
) else {
|
||||
return;
|
||||
};
|
||||
self.handler_aliases
|
||||
.add(handler.uid.clone(), &handler_alias);
|
||||
|
||||
if let Some(handler_field_node) = handler.field.spatial_ref().node.upgrade() {
|
||||
// Handler's field
|
||||
let Ok(rx_field_alias) = Alias::create(
|
||||
&method_client,
|
||||
handler_alias.get_path(),
|
||||
"field",
|
||||
&handler_field_node,
|
||||
FIELD_ALIAS_INFO.clone(),
|
||||
) else {return};
|
||||
&method_client,
|
||||
handler_alias.get_path(),
|
||||
"field",
|
||||
&handler_field_node,
|
||||
FIELD_ALIAS_INFO.clone(),
|
||||
) else {
|
||||
return;
|
||||
};
|
||||
self.handler_aliases
|
||||
.add(handler.uid.clone() + "-field", &rx_field_alias);
|
||||
}
|
||||
|
||||
let Ok(data) = serialize(&handler.uid) else {return};
|
||||
let Ok(data) = serialize(&handler.uid) else {
|
||||
return;
|
||||
};
|
||||
let _ = method_node.send_remote_signal("handler_created", data);
|
||||
}
|
||||
fn handle_drop_handler(&self, handler: &InputHandler) {
|
||||
let uid = handler.uid.as_str();
|
||||
self.handler_aliases.remove(uid);
|
||||
self.handler_aliases.remove(&(uid.to_string() + "-field"));
|
||||
let Some(tx_node) = self.node.upgrade() else {return};
|
||||
let Ok(data) = serialize(&uid) else {return};
|
||||
let Some(tx_node) = self.node.upgrade() else {
|
||||
return;
|
||||
};
|
||||
let Ok(data) = serialize(&uid) else { return };
|
||||
let _ = tx_node.send_remote_signal("handler_destroyed", data);
|
||||
}
|
||||
}
|
||||
@@ -299,7 +323,9 @@ impl InputHandler {
|
||||
distance_link: &DistanceLink,
|
||||
datamap: Datamap,
|
||||
) {
|
||||
let Some(node) = self.node.upgrade() else {return};
|
||||
let Some(node) = self.node.upgrade() else {
|
||||
return;
|
||||
};
|
||||
let _ = node.send_remote_signal("input", distance_link.serialize(order, captured, datamap));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,13 +2,14 @@ use super::{DistanceLink, InputSpecialization};
|
||||
use crate::core::client::Client;
|
||||
use crate::nodes::fields::{Field, Ray, RayMarchResult};
|
||||
use crate::nodes::input::{InputMethod, InputType};
|
||||
use crate::nodes::spatial::{find_spatial_parent, parse_transform, Spatial};
|
||||
use crate::nodes::spatial::{find_spatial_parent, parse_transform, Spatial, Transform};
|
||||
use crate::nodes::{Message, Node};
|
||||
use glam::{vec3, Mat4};
|
||||
use serde::Deserialize;
|
||||
use stardust_xr::schemas::flat::{Datamap, InputDataType, Pointer as FlatPointer};
|
||||
use stardust_xr::schemas::flat::{InputDataType, Pointer as FlatPointer};
|
||||
use stardust_xr::schemas::flex::deserialize;
|
||||
use stardust_xr::values::Transform;
|
||||
use stardust_xr::values::Datamap;
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
#[derive(Default)]
|
||||
@@ -86,7 +87,8 @@ pub fn create_pointer_flex(
|
||||
InputMethod::add_to(
|
||||
&node,
|
||||
InputType::Pointer(Pointer),
|
||||
info.datamap.and_then(|datamap| Datamap::new(datamap).ok()),
|
||||
info.datamap
|
||||
.and_then(|datamap| Datamap::from_raw(datamap).ok()),
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -2,14 +2,15 @@ use super::{DistanceLink, InputSpecialization};
|
||||
use crate::core::client::Client;
|
||||
use crate::nodes::fields::Field;
|
||||
use crate::nodes::input::{InputMethod, InputType};
|
||||
use crate::nodes::spatial::{find_spatial_parent, parse_transform, Spatial};
|
||||
use crate::nodes::spatial::{find_spatial_parent, parse_transform, Spatial, Transform};
|
||||
use crate::nodes::{Message, Node};
|
||||
use color_eyre::eyre::Result;
|
||||
use glam::{vec3a, Mat4};
|
||||
use serde::Deserialize;
|
||||
use stardust_xr::schemas::flat::{Datamap, InputDataType, Tip as FlatTip};
|
||||
use stardust_xr::schemas::flat::{InputDataType, Tip as FlatTip};
|
||||
use stardust_xr::schemas::flex::deserialize;
|
||||
use stardust_xr::values::Transform;
|
||||
use stardust_xr::values::Datamap;
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
#[derive(Default)]
|
||||
@@ -66,7 +67,8 @@ pub fn create_tip_flex(_node: &Node, calling_client: Arc<Client>, message: Messa
|
||||
InputType::Tip(Tip {
|
||||
radius: info.radius,
|
||||
}),
|
||||
info.datamap.and_then(|datamap| Datamap::new(datamap).ok()),
|
||||
info.datamap
|
||||
.and_then(|datamap| Datamap::from_raw(datamap).ok()),
|
||||
)?;
|
||||
node.add_local_signal("set_radius", Tip::set_radius);
|
||||
Ok(())
|
||||
|
||||
@@ -8,7 +8,7 @@ use crate::{
|
||||
nodes::{
|
||||
drawable::{model::ModelPart, shaders::UNLIT_SHADER_BYTES, Drawable},
|
||||
items::TypeInfo,
|
||||
spatial::{find_spatial_parent, parse_transform, Spatial},
|
||||
spatial::{find_spatial_parent, parse_transform, Spatial, Transform},
|
||||
Message, Node,
|
||||
},
|
||||
};
|
||||
@@ -20,10 +20,7 @@ use nanoid::nanoid;
|
||||
use once_cell::sync::OnceCell;
|
||||
use parking_lot::Mutex;
|
||||
use serde::Deserialize;
|
||||
use stardust_xr::{
|
||||
schemas::flex::{deserialize, serialize},
|
||||
values::Transform,
|
||||
};
|
||||
use stardust_xr::schemas::flex::{deserialize, serialize};
|
||||
use std::sync::Arc;
|
||||
use stereokit::{
|
||||
Color128, Material, Rect, RenderLayer, StereoKitDraw, Tex, TextureType, Transparency,
|
||||
@@ -87,7 +84,7 @@ impl CameraItem {
|
||||
) {
|
||||
response.wrap_sync(move || {
|
||||
let ItemType::Camera(_camera) = &node.item.get().unwrap().specialization else {
|
||||
return Err(eyre!("Wrong item type?"))
|
||||
return Err(eyre!("Wrong item type?"));
|
||||
};
|
||||
Ok(serialize(())?.into())
|
||||
});
|
||||
@@ -103,7 +100,11 @@ impl CameraItem {
|
||||
};
|
||||
let model_part_node =
|
||||
calling_client.get_node("Model part", deserialize(&message.data).unwrap())?;
|
||||
let Drawable::ModelPart(model_part) = model_part_node.get_aspect("Model part", "model part", |n| &n.drawable)? else {bail!("Drawable is not a model node")};
|
||||
let Drawable::ModelPart(model_part) =
|
||||
model_part_node.get_aspect("Model part", "model part", |n| &n.drawable)?
|
||||
else {
|
||||
bail!("Drawable is not a model node")
|
||||
};
|
||||
camera.applied_to.add_raw(model_part);
|
||||
camera.apply_to.add_raw(model_part);
|
||||
Ok(())
|
||||
@@ -155,7 +156,9 @@ impl CameraItem {
|
||||
|
||||
pub fn update(sk: &impl StereoKitDraw) {
|
||||
for camera in ITEM_TYPE_INFO_CAMERA.items.get_valid_contents() {
|
||||
let ItemType::Camera(camera) = &camera.specialization else {continue};
|
||||
let ItemType::Camera(camera) = &camera.specialization else {
|
||||
continue;
|
||||
};
|
||||
camera.update(sk);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ use crate::{
|
||||
},
|
||||
nodes::{
|
||||
items::TypeInfo,
|
||||
spatial::{find_spatial_parent, parse_transform, Spatial},
|
||||
spatial::{find_spatial_parent, parse_transform, Spatial, Transform},
|
||||
Message, Node,
|
||||
},
|
||||
};
|
||||
@@ -15,10 +15,7 @@ use color_eyre::eyre::{eyre, Result};
|
||||
use lazy_static::lazy_static;
|
||||
use nanoid::nanoid;
|
||||
use serde::Deserialize;
|
||||
use stardust_xr::{
|
||||
schemas::flex::{deserialize, serialize},
|
||||
values::Transform,
|
||||
};
|
||||
use stardust_xr::schemas::flex::{deserialize, serialize};
|
||||
use std::sync::Arc;
|
||||
|
||||
lazy_static! {
|
||||
@@ -54,9 +51,10 @@ impl EnvironmentItem {
|
||||
response: MethodResponseSender,
|
||||
) {
|
||||
response.wrap_sync(move || {
|
||||
let ItemType::Environment(environment_item) = &node.item.get().unwrap().specialization else {
|
||||
return Err(eyre!("Wrong item type?"))
|
||||
};
|
||||
let ItemType::Environment(environment_item) = &node.item.get().unwrap().specialization
|
||||
else {
|
||||
return Err(eyre!("Wrong item type?"));
|
||||
};
|
||||
Ok(serialize(environment_item.path.as_str())?.into())
|
||||
});
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ use crate::core::node_collections::LifeLinkedNodeMap;
|
||||
use crate::core::registry::Registry;
|
||||
use crate::nodes::alias::AliasInfo;
|
||||
use crate::nodes::fields::find_field;
|
||||
use crate::nodes::spatial::Transform;
|
||||
use color_eyre::eyre::{ensure, eyre, Result};
|
||||
use lazy_static::lazy_static;
|
||||
use nanoid::nanoid;
|
||||
@@ -20,7 +21,7 @@ use parking_lot::Mutex;
|
||||
use portable_atomic::Ordering;
|
||||
use serde::Deserialize;
|
||||
use stardust_xr::schemas::flex::{deserialize, serialize};
|
||||
use stardust_xr::values::Transform;
|
||||
|
||||
use std::hash::Hash;
|
||||
use std::sync::{Arc, Weak};
|
||||
|
||||
@@ -230,7 +231,9 @@ impl ItemUI {
|
||||
Ok(())
|
||||
}
|
||||
fn send_state(&self, state: &str, name: &str) {
|
||||
let Ok(serialized_data) = serialize(name) else {return};
|
||||
let Ok(serialized_data) = serialize(name) else {
|
||||
return;
|
||||
};
|
||||
let _ = self
|
||||
.node
|
||||
.upgrade()
|
||||
@@ -239,14 +242,20 @@ impl ItemUI {
|
||||
}
|
||||
|
||||
fn handle_create_item(&self, item: &Item) {
|
||||
let Some(node) = self.node.upgrade() else {return};
|
||||
let Some(client) = node.get_client() else {return};
|
||||
let Some(node) = self.node.upgrade() else {
|
||||
return;
|
||||
};
|
||||
let Some(client) = node.get_client() else {
|
||||
return;
|
||||
};
|
||||
|
||||
if let Ok(alias_node) = item.make_alias(&client, &(node.get_path().to_string() + "/item")) {
|
||||
self.item_aliases.add(item.uid.clone(), &alias_node);
|
||||
}
|
||||
|
||||
let Ok(serialized_data) = item.specialization.serialize_start_data(&item.uid) else {return};
|
||||
let Ok(serialized_data) = item.specialization.serialize_start_data(&item.uid) else {
|
||||
return;
|
||||
};
|
||||
let _ = node.send_remote_signal("create_item", serialized_data);
|
||||
}
|
||||
fn handle_destroy_item(&self, item: &Item) {
|
||||
@@ -254,29 +263,45 @@ impl ItemUI {
|
||||
self.send_state("destroy_item", item.uid.as_str());
|
||||
}
|
||||
fn handle_capture_item(&self, item: &Item, acceptor: &ItemAcceptor) {
|
||||
let Some(node) = self.node.upgrade() else {return};
|
||||
let Some(node) = self.node.upgrade() else {
|
||||
return;
|
||||
};
|
||||
|
||||
let Ok(message) = serialize((item.uid.as_str(), acceptor.uid.as_str())) else {return};
|
||||
let Ok(message) = serialize((item.uid.as_str(), acceptor.uid.as_str())) else {
|
||||
return;
|
||||
};
|
||||
let _ = node.send_remote_signal("capture_item", message);
|
||||
}
|
||||
fn handle_release_item(&self, item: &Item, acceptor: &ItemAcceptor) {
|
||||
let Some(node) = self.node.upgrade() else {return};
|
||||
let Some(node) = self.node.upgrade() else {
|
||||
return;
|
||||
};
|
||||
|
||||
let Ok(message) = serialize((item.uid.as_str(), acceptor.uid.as_str())) else {return};
|
||||
let Ok(message) = serialize((item.uid.as_str(), acceptor.uid.as_str())) else {
|
||||
return;
|
||||
};
|
||||
let _ = node.send_remote_signal("release_item", message);
|
||||
}
|
||||
fn handle_create_acceptor(&self, acceptor: &ItemAcceptor) {
|
||||
let Some(node) = self.node.upgrade() else {return};
|
||||
let Some(client) = node.get_client() else {return};
|
||||
let Some(node) = self.node.upgrade() else {
|
||||
return;
|
||||
};
|
||||
let Some(client) = node.get_client() else {
|
||||
return;
|
||||
};
|
||||
|
||||
let Ok((alias, field_alias)) = acceptor.make_aliases(
|
||||
&client,
|
||||
&format!("/item/{}/acceptor", self.type_info.type_name),
|
||||
) else {return};
|
||||
) else {
|
||||
return;
|
||||
};
|
||||
self.acceptor_aliases.add(acceptor.uid.clone(), &alias);
|
||||
self.acceptor_field_aliases
|
||||
.add(acceptor.uid.clone(), &field_alias);
|
||||
let Ok(message) = serialize(&acceptor.uid) else {return};
|
||||
let Ok(message) = serialize(&acceptor.uid) else {
|
||||
return;
|
||||
};
|
||||
let _ = node.send_remote_signal("create_acceptor", message);
|
||||
}
|
||||
fn handle_destroy_acceptor(&self, acceptor: &ItemAcceptor) {
|
||||
@@ -354,23 +379,33 @@ impl ItemAcceptor {
|
||||
Ok((acceptor_alias, acceptor_field_alias))
|
||||
}
|
||||
fn handle_capture(&self, item: &Arc<Item>) {
|
||||
let Some(node) = self.node.upgrade() else {return};
|
||||
let Some(client) = node.get_client() else {return};
|
||||
let Some(node) = self.node.upgrade() else {
|
||||
return;
|
||||
};
|
||||
let Some(client) = node.get_client() else {
|
||||
return;
|
||||
};
|
||||
|
||||
self.accepted_registry.add_raw(item);
|
||||
if let Ok(alias_node) = item.make_alias(&client, &node.path) {
|
||||
self.accepted_aliases.add(item.uid.clone(), &alias_node);
|
||||
}
|
||||
|
||||
let Ok(serialized_data) = item.specialization.serialize_start_data(&item.uid) else {return};
|
||||
let Ok(serialized_data) = item.specialization.serialize_start_data(&item.uid) else {
|
||||
return;
|
||||
};
|
||||
let _ = node.send_remote_signal("capture", serialized_data);
|
||||
}
|
||||
fn handle_release(&self, item: &Item) {
|
||||
let Some(node) = self.node.upgrade() else {return};
|
||||
let Some(node) = self.node.upgrade() else {
|
||||
return;
|
||||
};
|
||||
|
||||
self.accepted_registry.remove(item);
|
||||
self.accepted_aliases.remove(&item.uid);
|
||||
let Ok(message) = serialize(&item.uid) else {return};
|
||||
let Ok(message) = serialize(&item.uid) else {
|
||||
return;
|
||||
};
|
||||
let _ = node.send_remote_signal("release", message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,12 +13,13 @@ use once_cell::sync::OnceCell;
|
||||
use parking_lot::Mutex;
|
||||
use serde::Deserialize;
|
||||
use stardust_xr::schemas::flex::{deserialize, serialize};
|
||||
use stardust_xr::values::Transform;
|
||||
use std::fmt::Debug;
|
||||
use std::ptr;
|
||||
use std::sync::{Arc, Weak};
|
||||
use stereokit::{bounds_grow_to_fit_box, Bounds};
|
||||
|
||||
stardust_xr_server_codegen::codegen_spatial_protocol!();
|
||||
|
||||
static ZONEABLE_REGISTRY: Registry<Spatial> = Registry::new();
|
||||
|
||||
pub struct Spatial {
|
||||
@@ -143,7 +144,7 @@ impl Spatial {
|
||||
let (mut reference_space_scl, mut reference_space_rot, mut reference_space_pos) =
|
||||
local_transform_in_reference_space.to_scale_rotation_translation();
|
||||
|
||||
if let Some(pos) = transform.position {
|
||||
if let Some(pos) = transform.translation {
|
||||
reference_space_pos = pos.into()
|
||||
}
|
||||
if let Some(rot) = transform.rotation {
|
||||
@@ -467,7 +468,7 @@ impl Drop for Spatial {
|
||||
|
||||
pub fn parse_transform(transform: Transform, position: bool, rotation: bool, scale: bool) -> Mat4 {
|
||||
let position = position
|
||||
.then_some(transform.position)
|
||||
.then_some(transform.translation)
|
||||
.flatten()
|
||||
.unwrap_or_else(|| Vector3::from([0.0; 3]));
|
||||
let rotation = rotation
|
||||
|
||||
@@ -4,7 +4,7 @@ use crate::{
|
||||
nodes::{
|
||||
alias::{Alias, AliasInfo},
|
||||
fields::{find_field, Field},
|
||||
spatial::{find_spatial_parent, parse_transform},
|
||||
spatial::{find_spatial_parent, parse_transform, Transform},
|
||||
Message, Node,
|
||||
},
|
||||
};
|
||||
@@ -13,10 +13,7 @@ use glam::vec3a;
|
||||
use parking_lot::Mutex;
|
||||
use rustc_hash::FxHashMap;
|
||||
use serde::Deserialize;
|
||||
use stardust_xr::{
|
||||
schemas::flex::{deserialize, serialize},
|
||||
values::Transform,
|
||||
};
|
||||
use stardust_xr::schemas::flex::{deserialize, serialize};
|
||||
use std::sync::{Arc, Weak};
|
||||
|
||||
pub fn capture(spatial: &Arc<Spatial>, zone: &Arc<Zone>) {
|
||||
@@ -31,8 +28,12 @@ pub fn capture(spatial: &Arc<Spatial>, zone: &Arc<Zone>) {
|
||||
*spatial.old_parent.lock() = spatial.get_parent();
|
||||
*spatial.zone.lock() = Arc::downgrade(zone);
|
||||
zone.captured.add_raw(spatial);
|
||||
let Some(node) = zone.spatial.node.upgrade() else {return};
|
||||
let Ok(message) = serialize(&spatial.uid) else {return};
|
||||
let Some(node) = zone.spatial.node.upgrade() else {
|
||||
return;
|
||||
};
|
||||
let Ok(message) = serialize(&spatial.uid) else {
|
||||
return;
|
||||
};
|
||||
let _ = node.send_remote_signal("capture", message);
|
||||
}
|
||||
}
|
||||
@@ -40,9 +41,13 @@ pub fn release(spatial: &Spatial) {
|
||||
let _ = spatial.set_spatial_parent_in_place(spatial.old_parent.lock().take());
|
||||
let mut spatial_zone = spatial.zone.lock();
|
||||
if let Some(spatial_zone) = spatial_zone.upgrade() {
|
||||
let Some(node) = spatial_zone.spatial.node.upgrade() else {return};
|
||||
let Some(node) = spatial_zone.spatial.node.upgrade() else {
|
||||
return;
|
||||
};
|
||||
spatial_zone.captured.remove(spatial);
|
||||
let Ok(message) = serialize(&spatial.uid) else {return};
|
||||
let Ok(message) = serialize(&spatial.uid) else {
|
||||
return;
|
||||
};
|
||||
let _ = node.send_remote_signal("release", message);
|
||||
}
|
||||
*spatial_zone = Weak::new();
|
||||
@@ -83,12 +88,17 @@ impl Zone {
|
||||
}
|
||||
fn update(node: &Node, _calling_client: Arc<Client>, _message: Message) -> Result<()> {
|
||||
let zone = node.zone.get().unwrap();
|
||||
let Some(field) = zone.field.upgrade() else { return Err(color_eyre::eyre::eyre!("Zone's field has been destroyed")) };
|
||||
let Some(field) = zone.field.upgrade() else {
|
||||
return Err(color_eyre::eyre::eyre!("Zone's field has been destroyed"));
|
||||
};
|
||||
let Some((zone_client, zone_node)) = zone
|
||||
.spatial
|
||||
.node
|
||||
.upgrade()
|
||||
.and_then(|n| n.get_client().zip(Some(n))) else { return Err(color_eyre::eyre::eyre!("No client on node?")) };
|
||||
.and_then(|n| n.get_client().zip(Some(n)))
|
||||
else {
|
||||
return Err(color_eyre::eyre::eyre!("No client on node?"));
|
||||
};
|
||||
let mut old_zoneables = zone.zoneables.lock();
|
||||
for (_uid, zoneable) in old_zoneables.iter() {
|
||||
zoneable.destroy();
|
||||
|
||||
@@ -10,7 +10,7 @@ use color_eyre::eyre::Result;
|
||||
use glam::Mat4;
|
||||
use nanoid::nanoid;
|
||||
use serde::Serialize;
|
||||
use stardust_xr::schemas::{flat::Datamap, flex::flexbuffers};
|
||||
use stardust_xr::{schemas::flex::flexbuffers, values::Datamap};
|
||||
use std::sync::Arc;
|
||||
use stereokit::StereoKitMultiThread;
|
||||
|
||||
@@ -48,7 +48,7 @@ impl EyePointer {
|
||||
let mut map = fbb.start_map();
|
||||
map.push("eye", 2);
|
||||
map.end_map();
|
||||
*self.pointer.datamap.lock() = Datamap::new(fbb.take_buffer()).ok();
|
||||
*self.pointer.datamap.lock() = Datamap::from_raw(fbb.take_buffer()).ok();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::{
|
||||
core::{client::INTERNAL_CLIENT, typed_datamap::TypedDatamap},
|
||||
core::client::INTERNAL_CLIENT,
|
||||
nodes::{
|
||||
data::{mask_matches, Mask, PulseSender, KEYMAPS, PULSE_RECEIVER_REGISTRY},
|
||||
fields::Ray,
|
||||
@@ -12,6 +12,7 @@ use color_eyre::eyre::Result;
|
||||
use glam::{vec2, vec3, Mat4, Vec2, Vec3};
|
||||
use nanoid::nanoid;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use stardust_xr::values::Datamap;
|
||||
use std::{convert::TryFrom, sync::Arc};
|
||||
use stereokit::{ray_from_mouse, ButtonState, Key, StereoKitMultiThread};
|
||||
use xkbcommon::xkb::{Context, Keymap, FORMAT_TEXT_V1};
|
||||
@@ -49,8 +50,8 @@ pub struct MousePointer {
|
||||
node: Arc<Node>,
|
||||
spatial: Arc<Spatial>,
|
||||
pointer: Arc<InputMethod>,
|
||||
mouse_datamap: TypedDatamap<MouseEvent>,
|
||||
keyboard_datamap: TypedDatamap<KeyboardEvent>,
|
||||
mouse_datamap: MouseEvent,
|
||||
keyboard_datamap: KeyboardEvent,
|
||||
keyboard_sender: Arc<PulseSender>,
|
||||
}
|
||||
impl MousePointer {
|
||||
@@ -122,7 +123,7 @@ impl MousePointer {
|
||||
};
|
||||
self.mouse_datamap.scroll_continuous = vec2(0.0, mouse.scroll_change / 120.0);
|
||||
self.mouse_datamap.scroll_discrete = vec2(0.0, mouse.scroll_change / 120.0);
|
||||
*self.pointer.datamap.lock() = self.mouse_datamap.to_datamap().ok();
|
||||
*self.pointer.datamap.lock() = Datamap::from_typed(&self.mouse_datamap).ok();
|
||||
}
|
||||
self.send_keyboard_input(sk);
|
||||
}
|
||||
@@ -169,8 +170,14 @@ impl MousePointer {
|
||||
|
||||
self.keyboard_datamap.keys = keys;
|
||||
if !self.keyboard_datamap.keys.is_empty() {
|
||||
rx.send_data(&self.node.uid, self.keyboard_datamap.serialize().unwrap())
|
||||
.unwrap();
|
||||
rx.send_data(
|
||||
&self.node.uid,
|
||||
Datamap::from_typed(&self.keyboard_datamap)
|
||||
.unwrap()
|
||||
.raw()
|
||||
.clone(),
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::{
|
||||
core::{client::INTERNAL_CLIENT, typed_datamap::TypedDatamap},
|
||||
core::client::INTERNAL_CLIENT,
|
||||
nodes::{
|
||||
input::{tip::Tip, InputMethod, InputType},
|
||||
spatial::Spatial,
|
||||
@@ -9,6 +9,7 @@ use crate::{
|
||||
use color_eyre::eyre::Result;
|
||||
use glam::{Mat4, Vec2, Vec3};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use stardust_xr::values::Datamap;
|
||||
use std::sync::Arc;
|
||||
use stereokit::{
|
||||
named_colors::WHITE, ButtonState, Handed, Model, RenderLayer, StereoKitDraw,
|
||||
@@ -27,7 +28,7 @@ pub struct SkController {
|
||||
input: Arc<InputMethod>,
|
||||
model: Model,
|
||||
handed: Handed,
|
||||
datamap: TypedDatamap<ControllerDatamap>,
|
||||
datamap: ControllerDatamap,
|
||||
}
|
||||
impl SkController {
|
||||
pub fn new(sk: &impl StereoKitMultiThread, handed: Handed) -> Result<Self> {
|
||||
@@ -73,6 +74,6 @@ impl SkController {
|
||||
self.datamap.select = controller.trigger;
|
||||
self.datamap.grab = controller.grip;
|
||||
self.datamap.scroll = controller.stick;
|
||||
*self.input.datamap.lock() = self.datamap.to_datamap().ok();
|
||||
*self.input.datamap.lock() = Datamap::from_typed(&self.datamap).ok();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::{
|
||||
core::{client::INTERNAL_CLIENT, typed_datamap::TypedDatamap},
|
||||
core::client::INTERNAL_CLIENT,
|
||||
nodes::{
|
||||
input::{hand::Hand, InputMethod, InputType},
|
||||
spatial::Spatial,
|
||||
@@ -10,7 +10,10 @@ use color_eyre::eyre::Result;
|
||||
use glam::Mat4;
|
||||
use nanoid::nanoid;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use stardust_xr::schemas::flat::{Hand as FlatHand, Joint};
|
||||
use stardust_xr::{
|
||||
schemas::flat::{Hand as FlatHand, Joint},
|
||||
values::Datamap,
|
||||
};
|
||||
use std::sync::Arc;
|
||||
use stereokit::{ButtonState, HandJoint, Handed, StereoKitMultiThread};
|
||||
|
||||
@@ -33,7 +36,7 @@ pub struct SkHand {
|
||||
_node: Arc<Node>,
|
||||
input: Arc<InputMethod>,
|
||||
handed: Handed,
|
||||
datamap: TypedDatamap<HandDatamap>,
|
||||
datamap: HandDatamap,
|
||||
}
|
||||
impl SkHand {
|
||||
pub fn new(handed: Handed) -> Result<Self> {
|
||||
@@ -98,6 +101,6 @@ impl SkHand {
|
||||
}
|
||||
self.datamap.pinch_strength = sk_hand.pinch_activation;
|
||||
self.datamap.grab_strength = sk_hand.grip_activation;
|
||||
*self.input.datamap.lock() = self.datamap.to_datamap().ok();
|
||||
*self.input.datamap.lock() = Datamap::from_typed(&self.datamap).ok();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user