From 5797d2f3e363858d5a838e98b22c41d67d40188c Mon Sep 17 00:00:00 2001 From: Schmarni Date: Sat, 22 Mar 2025 04:40:53 +0100 Subject: [PATCH 1/5] feat: wip debugging improvements and protocol change Signed-off-by: Schmarni --- Cargo.lock | 37 +++++++++------- Cargo.toml | 3 ++ codegen/src/lib.rs | 106 ++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 130 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 131e907..2b5e57a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1048,9 +1048,9 @@ checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" [[package]] name = "futures-lite" -version = "2.3.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52527eb5074e35e9339c6b4e8d12600c7128b68fb25dcb9fa9dec18f7c25f3a5" +checksum = "f5edaec856126859abb19ed65f39e90fea3a9574b9707f13539acf4abf7eb532" dependencies = [ "fastrand", "futures-core", @@ -1089,11 +1089,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" dependencies = [ "futures-core", - "futures-io", "futures-macro", - "futures-sink", "futures-task", - "memchr", "pin-project-lite", "pin-utils", "slab", @@ -2623,7 +2620,6 @@ checksum = "2f2b15926089e5526bb2dd738a2eb0e59034356e06eb71e1cd912358c0e62c4d" [[package]] name = "stardust-xr" version = "0.45.0" -source = "git+https://github.com/StardustXR/core.git?branch=dev#0e746ca4d0a04f668fc1958e38b9d799eb5e3370" dependencies = [ "cluFlock", "color-eyre", @@ -2644,7 +2640,6 @@ dependencies = [ [[package]] name = "stardust-xr-schemas" version = "1.5.3" -source = "git+https://github.com/StardustXR/core.git?branch=dev#0e746ca4d0a04f668fc1958e38b9d799eb5e3370" dependencies = [ "flatbuffers", "flexbuffers", @@ -3667,6 +3662,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "winnow" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e97b544156e9bebe1a0ffbc03484fc1ffe3100cbce3ffb17eac35f7cdd7ab36" +dependencies = [ + "memchr", +] + [[package]] name = "xdg-home" version = "1.3.0" @@ -3738,9 +3742,9 @@ checksum = "539a77ee7c0de333dcc6da69b177380a0b81e0dacfa4f7344c465a36871ee601" [[package]] name = "zbus" -version = "5.0.1" +version = "5.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "333be40ef37976542e10832ba961e3e44ea215a6b1e2673066b303ee3e0ede10" +checksum = "59c333f648ea1b647bc95dc1d34807c8e25ed7a6feff3394034dc4776054b236" dependencies = [ "async-broadcast", "async-executor", @@ -3755,7 +3759,7 @@ dependencies = [ "enumflags2", "event-listener", "futures-core", - "futures-util", + "futures-lite", "hex", "nix 0.29.0", "ordered-stream", @@ -3766,6 +3770,7 @@ dependencies = [ "tracing", "uds_windows", "windows-sys 0.59.0", + "winnow 0.7.4", "xdg-home", "zbus_macros", "zbus_names", @@ -3774,14 +3779,16 @@ dependencies = [ [[package]] name = "zbus_macros" -version = "5.0.1" +version = "5.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "381be624000c82e716c2a45d9213fabacf82177591fa8a6ff655d2825450601a" +checksum = "f325ad10eb0d0a3eb060203494c3b7ec3162a01a59db75d2deee100339709fc0" dependencies = [ "proc-macro-crate 3.2.0", "proc-macro2", "quote", "syn 2.0.87", + "zbus_names", + "zvariant", "zvariant_utils", ] @@ -3846,14 +3853,14 @@ dependencies = [ [[package]] name = "zvariant_utils" -version = "3.0.1" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f8d85190ba70bc7b9540430df078bb529620b1464ed4a606010de584e27094d" +checksum = "e16edfee43e5d7b553b77872d99bc36afdda75c223ca7ad5e3fbecd82ca5fc34" dependencies = [ "proc-macro2", "quote", "serde", "static_assertions", "syn 2.0.87", - "winnow 0.6.18", + "winnow 0.7.4", ] diff --git a/Cargo.toml b/Cargo.toml index e494c63..a57509a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,9 @@ homepage = "https://stardustxr.org" [workspace] members = ["codegen"] +[patch."https://github.com/StardustXR/core.git"] +stardust-xr.path = "../core/core" + [workspace.dependencies.stardust-xr] git = "https://github.com/StardustXR/core.git" branch = "dev" diff --git a/codegen/src/lib.rs b/codegen/src/lib.rs index 1d1c77b..da02fac 100644 --- a/codegen/src/lib.rs +++ b/codegen/src/lib.rs @@ -49,6 +49,110 @@ pub fn codegen_item_panel_protocol(_input: proc_macro::TokenStream) -> proc_macr codegen_protocol(ITEM_PANEL_PROTOCOL) } +#[proc_macro] +pub fn codegen_id_to_name_functions(_input: proc_macro::TokenStream) -> proc_macro::TokenStream { + let mut aspect_map: Vec<(u64, String)> = Vec::new(); + let mut method_map: Vec<(u64, String)> = Vec::new(); + let mut signal_map: Vec<(u64, String)> = Vec::new(); + let protocols = [ + ROOT_PROTOCOL, + NODE_PROTOCOL, + SPATIAL_PROTOCOL, + FIELD_PROTOCOL, + AUDIO_PROTOCOL, + DRAWABLE_PROTOCOL, + INPUT_PROTOCOL, + ITEM_PROTOCOL, + ITEM_CAMERA_PROTOCOL, + ITEM_PANEL_PROTOCOL, + ]; + let mut interface_found = false; + for protocol in protocols + .into_iter() + .filter_map(|p| Protocol::parse(p).ok()) + { + if let Some(i) = protocol.interface { + if interface_found { + panic!("more than one interface?! wha? pls help? someone?"); + } + interface_found = true; + aspect_map.push((0, "interface".to_owned())); + for m in i.members { + match m._type { + MemberType::Signal => &mut signal_map, + MemberType::Method => &mut method_map, + } + .push((m.opcode, m.name)); + } + } + for aspect in protocol.aspects.into_iter() { + aspect_map.push((aspect.id, aspect.name)); + for m in aspect.members.into_iter() { + match m._type { + MemberType::Signal => &mut signal_map, + MemberType::Method => &mut method_map, + } + .push((m.opcode, m.name)); + } + } + } + + let aspect_id_to_name = aspect_map + .iter() + .map(|(id, name)| { + quote! { + #id => Some(#name), + } + }) + .reduce(fold_tokens); + let aspect_id_to_name_fn = quote! { + pub const fn aspect_id_to_name(id: u64) -> Option<&'static str> { + match id { + #aspect_id_to_name + _ => None, + } + } + }; + let method_id_to_name = method_map + .iter() + .map(|(id, name)| { + quote! { + #id => Some(#name), + } + }) + .reduce(fold_tokens); + let method_id_to_name_fn = quote! { + pub const fn method_id_to_name(id: u64) -> Option<&'static str> { + match id { + #method_id_to_name + _ => None, + } + } + }; + let signal_id_to_name = signal_map + .iter() + .map(|(id, name)| { + quote! { + #id => Some(#name), + } + }) + .reduce(fold_tokens); + let signal_id_to_name_fn = quote! { + pub const fn signal_id_to_name(id: u64) -> Option<&'static str> { + match id { + #signal_id_to_name + _ => None + } + } + }; + quote! { + #aspect_id_to_name_fn + #method_id_to_name_fn + #signal_id_to_name_fn + } + .into() +} + fn codegen_protocol(protocol: &'static str) -> proc_macro::TokenStream { let protocol = Protocol::parse(protocol).unwrap(); let interface = protocol @@ -143,7 +247,7 @@ fn generate_custom_union(custom_union: &CustomUnion) -> TokenStream { quote! { #[doc = #description] #[derive(Debug, Clone, serde::Deserialize, serde::Serialize)] - #[serde(tag = "type")] + // #[serde(tag = "type")] pub enum #name {#option_decls} } } -- 2.49.1 From 7c343005f76a39d2d69735b9ae4ab2b89a874e99 Mon Sep 17 00:00:00 2001 From: Schmarni Date: Sun, 23 Mar 2025 00:26:41 +0100 Subject: [PATCH 2/5] feat: add better logging to codegen Signed-off-by: Schmarni --- codegen/src/lib.rs | 50 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 39 insertions(+), 11 deletions(-) diff --git a/codegen/src/lib.rs b/codegen/src/lib.rs index da02fac..7f2732b 100644 --- a/codegen/src/lib.rs +++ b/codegen/src/lib.rs @@ -294,7 +294,7 @@ fn generate_aspect(aspect: &Aspect) -> TokenStream { Span::call_site(), ); let client_side_members = client_members - .map(|m| generate_member(aspect.id, m)) + .map(|m| generate_member(aspect.id, &aspect.name.to_case(Case::Snake), m)) .reduce(fold_tokens) .map(|t| { // TODO: properly import all dependencies @@ -332,7 +332,7 @@ fn generate_aspect(aspect: &Aspect) -> TokenStream { let alias_info = generate_alias_info(aspect); let server_side_members = server_members - .map(|m| generate_member(aspect.id, m)) + .map(|m| generate_member(aspect.id, &aspect.name.to_case(Case::Pascal), m)) .reduce(fold_tokens) .unwrap_or_default(); let aspect_trait_name = Ident::new( @@ -471,7 +471,7 @@ fn generate_alias_info(aspect: &Aspect) -> TokenStream { } } -fn generate_member(aspect_id: u64, member: &Member) -> TokenStream { +fn generate_member(aspect_id: u64, aspect_name: &str, member: &Member) -> TokenStream { let opcode = member.opcode; let name = Ident::new(&member.name.to_case(Case::Snake), Span::call_site()); let description = &member.description; @@ -502,14 +502,21 @@ fn generate_member(aspect_id: u64, member: &Member) -> TokenStream { .as_ref() .map(|r| generate_argument_type(r, false, true)) .unwrap_or_else(|| quote!(())); + let name_str = name.to_string(); match (side, _type) { (Side::Client, MemberType::Signal) => { quote! { #[doc = #description] pub fn #name(#argument_decls) -> crate::core::error::Result<()> { - let serialized = stardust_xr::schemas::flex::serialize((#argument_uses))?; - _node.send_remote_signal(#aspect_id, #opcode, serialized) + + let result = stardust_xr::schemas::flex::serialize((#argument_uses)).map_err(|e|e.into()).and_then(|serialized|_node.send_remote_signal(#aspect_id, #opcode, serialized)); + if let Err(err) = result.as_ref() { + ::tracing::error!("failed to send remote signal: {}::{}, error: {}",#aspect_name,#name_str,err); + } else { + ::tracing::trace!("sent remote signal: {}::{}",#aspect_name,#name_str); + } + result } } } @@ -517,7 +524,13 @@ fn generate_member(aspect_id: u64, member: &Member) -> TokenStream { quote! { #[doc = #description] pub async fn #name(#argument_decls) -> crate::core::error::Result<(#return_type, Vec)> { - _node.execute_remote_method_typed(#aspect_id, #opcode, &(#argument_uses), vec![]).await + let result = _node.execute_remote_method_typed(#aspect_id, #opcode, &(#argument_uses), vec![]).await; + if let Err(err) = result.as_ref() { + ::tracing::error!("failed to call remote method: {}::{}, error: {}",#aspect_name,#name_str,err); + } else { + ::tracing::trace!("called remote method: {}::{}",#aspect_name,#name_str); + } + result } } } @@ -574,18 +587,33 @@ fn generate_run_member(aspect_name: &Ident, _type: MemberType, member: &Member) .map(|a| generate_argument_deserialize(&a.name, &a._type, a.optional)) .reduce(|a, b| quote!(#a, #b)) .unwrap_or_default(); + let member_name = member_name_ident.to_string(); + let aspect_name_str = aspect_name.to_string(); match _type { MemberType::Signal => quote! { - #opcode => (move || { + #opcode => { let result = (move || { #deserialize ::#member_name_ident(_node, _calling_client.clone(), #argument_uses) - })().map_err(|e: crate::core::error::ServerError| stardust_xr::scenegraph::ScenegraphError::MemberError { error: e.to_string() }), + })().map_err(|e: crate::core::error::ServerError| stardust_xr::scenegraph::ScenegraphError::MemberError { error: e.to_string() }); + if let Err(err) = result.as_ref() { + ::tracing::error!("failed to receive local signal: {}::{}, error: {}",#aspect_name_str,#member_name,err); + } else { + ::tracing::trace!("received local signal: {}::{}",#aspect_name_str,#member_name); + } + result + }, }, MemberType::Method => quote! { #opcode => _method_response.wrap_async(async move { - #deserialize - let result = ::#member_name_ident(_node, _calling_client.clone(), #argument_uses).await?; - Ok((#serialize, Vec::::new())) + #deserialize + let result = ::#member_name_ident(_node, _calling_client.clone(), #argument_uses).await; + if let Err(err) = result.as_ref() { + ::tracing::error!("failed to call local method: {}::{}, error: {}",#aspect_name_str,#member_name,err); + } else { + ::tracing::trace!("called local method: {}::{}",#aspect_name_str,#member_name); + }; + let result = result?; + Ok((#serialize, Vec::::new())) }), }, } -- 2.49.1 From 8286cbdaafab89d8174ce9ad7eebaa3e2e133afd Mon Sep 17 00:00:00 2001 From: Schmarni Date: Sun, 23 Mar 2025 01:15:56 +0100 Subject: [PATCH 3/5] refactor: change errors to warnings and fix unions/enums in protocol Signed-off-by: Schmarni --- codegen/src/lib.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/codegen/src/lib.rs b/codegen/src/lib.rs index 7f2732b..9f1d7d9 100644 --- a/codegen/src/lib.rs +++ b/codegen/src/lib.rs @@ -247,7 +247,7 @@ fn generate_custom_union(custom_union: &CustomUnion) -> TokenStream { quote! { #[doc = #description] #[derive(Debug, Clone, serde::Deserialize, serde::Serialize)] - // #[serde(tag = "type")] + #[serde(tag = "t", content = "c")] pub enum #name {#option_decls} } } @@ -512,7 +512,7 @@ fn generate_member(aspect_id: u64, aspect_name: &str, member: &Member) -> TokenS let result = stardust_xr::schemas::flex::serialize((#argument_uses)).map_err(|e|e.into()).and_then(|serialized|_node.send_remote_signal(#aspect_id, #opcode, serialized)); if let Err(err) = result.as_ref() { - ::tracing::error!("failed to send remote signal: {}::{}, error: {}",#aspect_name,#name_str,err); + ::tracing::warn!("failed to send remote signal: {}::{}, error: {}",#aspect_name,#name_str,err); } else { ::tracing::trace!("sent remote signal: {}::{}",#aspect_name,#name_str); } @@ -526,7 +526,7 @@ fn generate_member(aspect_id: u64, aspect_name: &str, member: &Member) -> TokenS pub async fn #name(#argument_decls) -> crate::core::error::Result<(#return_type, Vec)> { let result = _node.execute_remote_method_typed(#aspect_id, #opcode, &(#argument_uses), vec![]).await; if let Err(err) = result.as_ref() { - ::tracing::error!("failed to call remote method: {}::{}, error: {}",#aspect_name,#name_str,err); + ::tracing::warn!("failed to call remote method: {}::{}, error: {}",#aspect_name,#name_str,err); } else { ::tracing::trace!("called remote method: {}::{}",#aspect_name,#name_str); } @@ -596,7 +596,7 @@ fn generate_run_member(aspect_name: &Ident, _type: MemberType, member: &Member) ::#member_name_ident(_node, _calling_client.clone(), #argument_uses) })().map_err(|e: crate::core::error::ServerError| stardust_xr::scenegraph::ScenegraphError::MemberError { error: e.to_string() }); if let Err(err) = result.as_ref() { - ::tracing::error!("failed to receive local signal: {}::{}, error: {}",#aspect_name_str,#member_name,err); + ::tracing::warn!("failed to receive local signal: {}::{}, error: {}",#aspect_name_str,#member_name,err); } else { ::tracing::trace!("received local signal: {}::{}",#aspect_name_str,#member_name); } @@ -608,7 +608,7 @@ fn generate_run_member(aspect_name: &Ident, _type: MemberType, member: &Member) #deserialize let result = ::#member_name_ident(_node, _calling_client.clone(), #argument_uses).await; if let Err(err) = result.as_ref() { - ::tracing::error!("failed to call local method: {}::{}, error: {}",#aspect_name_str,#member_name,err); + ::tracing::warn!("failed to call local method: {}::{}, error: {}",#aspect_name_str,#member_name,err); } else { ::tracing::trace!("called local method: {}::{}",#aspect_name_str,#member_name); }; -- 2.49.1 From f92fb898714521e45b241082bb085e15a13851e3 Mon Sep 17 00:00:00 2001 From: Schmarni Date: Sun, 23 Mar 2025 01:21:16 +0100 Subject: [PATCH 4/5] chore: remove unneeded cargo patch Signed-off-by: Schmarni --- Cargo.lock | 2 ++ Cargo.toml | 3 --- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2b5e57a..bb83e43 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2620,6 +2620,7 @@ checksum = "2f2b15926089e5526bb2dd738a2eb0e59034356e06eb71e1cd912358c0e62c4d" [[package]] name = "stardust-xr" version = "0.45.0" +source = "git+https://github.com/StardustXR/core.git?branch=dev#752e34817e045997c7bdca53cda6bb8a0055e902" dependencies = [ "cluFlock", "color-eyre", @@ -2640,6 +2641,7 @@ dependencies = [ [[package]] name = "stardust-xr-schemas" version = "1.5.3" +source = "git+https://github.com/StardustXR/core.git?branch=dev#752e34817e045997c7bdca53cda6bb8a0055e902" dependencies = [ "flatbuffers", "flexbuffers", diff --git a/Cargo.toml b/Cargo.toml index a57509a..e494c63 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,9 +12,6 @@ homepage = "https://stardustxr.org" [workspace] members = ["codegen"] -[patch."https://github.com/StardustXR/core.git"] -stardust-xr.path = "../core/core" - [workspace.dependencies.stardust-xr] git = "https://github.com/StardustXR/core.git" branch = "dev" -- 2.49.1 From 76a671764e3d8a342334da4d611899fc51f7ea16 Mon Sep 17 00:00:00 2001 From: Schmarni Date: Sun, 23 Mar 2025 02:25:15 +0100 Subject: [PATCH 5/5] refactor: remove unused macro Signed-off-by: Schmarni --- codegen/src/lib.rs | 104 --------------------------------------------- 1 file changed, 104 deletions(-) diff --git a/codegen/src/lib.rs b/codegen/src/lib.rs index 9f1d7d9..a050ad9 100644 --- a/codegen/src/lib.rs +++ b/codegen/src/lib.rs @@ -49,110 +49,6 @@ pub fn codegen_item_panel_protocol(_input: proc_macro::TokenStream) -> proc_macr codegen_protocol(ITEM_PANEL_PROTOCOL) } -#[proc_macro] -pub fn codegen_id_to_name_functions(_input: proc_macro::TokenStream) -> proc_macro::TokenStream { - let mut aspect_map: Vec<(u64, String)> = Vec::new(); - let mut method_map: Vec<(u64, String)> = Vec::new(); - let mut signal_map: Vec<(u64, String)> = Vec::new(); - let protocols = [ - ROOT_PROTOCOL, - NODE_PROTOCOL, - SPATIAL_PROTOCOL, - FIELD_PROTOCOL, - AUDIO_PROTOCOL, - DRAWABLE_PROTOCOL, - INPUT_PROTOCOL, - ITEM_PROTOCOL, - ITEM_CAMERA_PROTOCOL, - ITEM_PANEL_PROTOCOL, - ]; - let mut interface_found = false; - for protocol in protocols - .into_iter() - .filter_map(|p| Protocol::parse(p).ok()) - { - if let Some(i) = protocol.interface { - if interface_found { - panic!("more than one interface?! wha? pls help? someone?"); - } - interface_found = true; - aspect_map.push((0, "interface".to_owned())); - for m in i.members { - match m._type { - MemberType::Signal => &mut signal_map, - MemberType::Method => &mut method_map, - } - .push((m.opcode, m.name)); - } - } - for aspect in protocol.aspects.into_iter() { - aspect_map.push((aspect.id, aspect.name)); - for m in aspect.members.into_iter() { - match m._type { - MemberType::Signal => &mut signal_map, - MemberType::Method => &mut method_map, - } - .push((m.opcode, m.name)); - } - } - } - - let aspect_id_to_name = aspect_map - .iter() - .map(|(id, name)| { - quote! { - #id => Some(#name), - } - }) - .reduce(fold_tokens); - let aspect_id_to_name_fn = quote! { - pub const fn aspect_id_to_name(id: u64) -> Option<&'static str> { - match id { - #aspect_id_to_name - _ => None, - } - } - }; - let method_id_to_name = method_map - .iter() - .map(|(id, name)| { - quote! { - #id => Some(#name), - } - }) - .reduce(fold_tokens); - let method_id_to_name_fn = quote! { - pub const fn method_id_to_name(id: u64) -> Option<&'static str> { - match id { - #method_id_to_name - _ => None, - } - } - }; - let signal_id_to_name = signal_map - .iter() - .map(|(id, name)| { - quote! { - #id => Some(#name), - } - }) - .reduce(fold_tokens); - let signal_id_to_name_fn = quote! { - pub const fn signal_id_to_name(id: u64) -> Option<&'static str> { - match id { - #signal_id_to_name - _ => None - } - } - }; - quote! { - #aspect_id_to_name_fn - #method_id_to_name_fn - #signal_id_to_name_fn - } - .into() -} - fn codegen_protocol(protocol: &'static str) -> proc_macro::TokenStream { let protocol = Protocol::parse(protocol).unwrap(); let interface = protocol -- 2.49.1