From c0141da88b716ede46b7bdce0fbc0fad1adae36b Mon Sep 17 00:00:00 2001 From: Nova Date: Sun, 29 Dec 2024 09:44:50 -0800 Subject: [PATCH] refactor: optimize get aspect hotpath --- codegen/src/lib.rs | 18 +++++++++++++++--- src/nodes/alias.rs | 12 ++++++------ src/nodes/audio.rs | 5 ++++- src/nodes/drawable/mod.rs | 15 ++++++++++++++- src/nodes/fields.rs | 8 +++++++- src/nodes/input/mod.rs | 10 ++++++++++ src/nodes/items/camera.rs | 10 ++++++++++ src/nodes/items/mod.rs | 11 ++++++++++- src/nodes/items/panel.rs | 12 ++++++++++-- src/nodes/mod.rs | 28 +++++++++++++++++----------- src/nodes/root.rs | 5 ++++- src/nodes/spatial/mod.rs | 11 ++++++++++- 12 files changed, 117 insertions(+), 28 deletions(-) diff --git a/codegen/src/lib.rs b/codegen/src/lib.rs index 757780c..1357644 100644 --- a/codegen/src/lib.rs +++ b/codegen/src/lib.rs @@ -69,6 +69,9 @@ fn codegen_protocol(protocol: &'static str) -> proc_macro::TokenStream { #node_id #aspect pub struct Interface; + impl crate::nodes::AspectIdentifier for Interface { + impl_aspect_for_interface_aspect_id!{} + } impl crate::nodes::Aspect for Interface { impl_aspect_for_interface_aspect!{} } @@ -255,6 +258,13 @@ fn generate_aspect(aspect: &Aspect) -> TokenStream { #server_side_members } }; + let aspect_id_macro_name = Ident::new( + &format!( + "impl_aspect_for_{}_aspect_id", + aspect.name.to_case(Case::Snake) + ), + Span::call_site(), + ); let aspect_macro_name = Ident::new( &format!( "impl_aspect_for_{}_aspect", @@ -264,11 +274,13 @@ fn generate_aspect(aspect: &Aspect) -> TokenStream { ); let aspect_id = aspect.id; let aspect_macro = quote! { + macro_rules! #aspect_id_macro_name { + () => { + const ID: u64 = #aspect_id; + } + } macro_rules! #aspect_macro_name { () => { - fn id(&self) -> u64 { - #aspect_id - } fn as_any(self: Arc) -> Arc { self } diff --git a/src/nodes/alias.rs b/src/nodes/alias.rs index fdbfd3a..5375749 100644 --- a/src/nodes/alias.rs +++ b/src/nodes/alias.rs @@ -1,4 +1,4 @@ -use super::{Aspect, Node}; +use super::{Aspect, AspectIdentifier, Node}; use crate::core::{client::Client, registry::Registry}; use color_eyre::eyre::Result; use std::{ @@ -68,10 +68,10 @@ impl Alias { Ok(()) } } +impl AspectIdentifier for Alias { + const ID: u64 = 0; +} impl Aspect for Alias { - fn id(&self) -> u64 { - 0 - } fn as_any(self: Arc) -> Arc { self } @@ -129,7 +129,7 @@ impl AliasList { .into_iter() .find(move |node| links_to(node.clone(), original.clone())) } - pub fn get_from_aspect(&self, aspect: &A) -> Option> { + pub fn get_from_aspect(&self, aspect: &A) -> Option> { self.0.get_valid_contents().into_iter().find(|node| { let Some(node) = get_original(node.clone(), false) else { return false; @@ -143,7 +143,7 @@ impl AliasList { pub fn get_aliases(&self) -> Vec> { self.0.get_valid_contents() } - pub fn remove_aspect(&self, aspect: &A) { + pub fn remove_aspect(&self, aspect: &A) { self.0.retain(|node| { let Some(original) = get_original(node.clone(), false) else { return false; diff --git a/src/nodes/audio.rs b/src/nodes/audio.rs index 205df13..928b295 100644 --- a/src/nodes/audio.rs +++ b/src/nodes/audio.rs @@ -1,4 +1,4 @@ -use super::{Aspect, Node}; +use super::{Aspect, AspectIdentifier, Node}; use crate::core::client::Client; use crate::core::destroy_queue; use crate::core::registry::Registry; @@ -68,6 +68,9 @@ impl Sound { } } } +impl AspectIdentifier for Sound { + impl_aspect_for_sound_aspect_id! {} +} impl Aspect for Sound { impl_aspect_for_sound_aspect! {} } diff --git a/src/nodes/drawable/mod.rs b/src/nodes/drawable/mod.rs index a5e3856..00b73a1 100644 --- a/src/nodes/drawable/mod.rs +++ b/src/nodes/drawable/mod.rs @@ -8,7 +8,7 @@ pub mod text; use self::{lines::Lines, model::Model, text::Text}; use super::{ spatial::{Spatial, Transform}, - Aspect, Node, + Aspect, AspectIdentifier, Node, }; use crate::core::{client::Client, resource::get_resource_file}; use crate::nodes::spatial::SPATIAL_ASPECT_ALIAS_INFO; @@ -41,15 +41,28 @@ static QUEUED_SKYLIGHT: Mutex> = Mutex::new(None); static QUEUED_SKYTEX: Mutex> = Mutex::new(None); stardust_xr_server_codegen::codegen_drawable_protocol!(); + +impl AspectIdentifier for Lines { + impl_aspect_for_lines_aspect_id! {} +} impl Aspect for Lines { impl_aspect_for_lines_aspect! {} } +impl AspectIdentifier for Model { + impl_aspect_for_model_aspect_id! {} +} impl Aspect for Model { impl_aspect_for_model_aspect! {} } +impl AspectIdentifier for ModelPart { + impl_aspect_for_model_part_aspect_id! {} +} impl Aspect for ModelPart { impl_aspect_for_model_part_aspect! {} } +impl AspectIdentifier for Text { + impl_aspect_for_text_aspect_id! {} +} impl Aspect for Text { impl_aspect_for_text_aspect! {} } diff --git a/src/nodes/fields.rs b/src/nodes/fields.rs index 990d5d2..1f595b7 100644 --- a/src/nodes/fields.rs +++ b/src/nodes/fields.rs @@ -3,7 +3,7 @@ use super::spatial::{ Spatial, SPATIAL_REF_GET_LOCAL_BOUNDING_BOX_SERVER_OPCODE, SPATIAL_REF_GET_RELATIVE_BOUNDING_BOX_SERVER_OPCODE, SPATIAL_REF_GET_TRANSFORM_SERVER_OPCODE, }; -use super::{Aspect, Node}; +use super::{Aspect, AspectIdentifier, Node}; use crate::core::client::Client; use crate::nodes::spatial::Transform; use crate::nodes::spatial::SPATIAL_ASPECT_ALIAS_INFO; @@ -148,6 +148,9 @@ impl Field { Ok(field) } } +impl AspectIdentifier for Field { + impl_aspect_for_field_aspect_id! {} +} impl Aspect for Field { impl_aspect_for_field_aspect! {} } @@ -193,6 +196,9 @@ impl FieldTrait for Field { } pub struct FieldRef; +impl AspectIdentifier for FieldRef { + impl_aspect_for_field_ref_aspect_id! {} +} impl Aspect for FieldRef { impl_aspect_for_field_ref_aspect! {} } diff --git a/src/nodes/input/mod.rs b/src/nodes/input/mod.rs index eaa08bb..86e80cb 100644 --- a/src/nodes/input/mod.rs +++ b/src/nodes/input/mod.rs @@ -12,6 +12,7 @@ pub use method::*; use super::fields::Field; use super::spatial::Spatial; use super::Aspect; +use super::AspectIdentifier; use crate::nodes::spatial::SPATIAL_ASPECT_ALIAS_INFO; use crate::nodes::spatial::SPATIAL_REF_ASPECT_ALIAS_INFO; use crate::{core::client::Client, nodes::Node}; @@ -25,12 +26,21 @@ pub static INPUT_HANDLER_REGISTRY: Registry = Registry::new(); stardust_xr_server_codegen::codegen_input_protocol!(); +impl AspectIdentifier for InputHandler { + impl_aspect_for_input_handler_aspect_id! {} +} impl Aspect for InputHandler { impl_aspect_for_input_handler_aspect! {} } +impl AspectIdentifier for InputMethod { + impl_aspect_for_input_method_aspect_id! {} +} impl Aspect for InputMethod { impl_aspect_for_input_method_aspect! {} } +impl AspectIdentifier for InputMethodRef { + impl_aspect_for_input_method_ref_aspect_id! {} +} impl Aspect for InputMethodRef { impl_aspect_for_input_method_ref_aspect! {} } diff --git a/src/nodes/items/camera.rs b/src/nodes/items/camera.rs index 08b161d..b54ecc6 100644 --- a/src/nodes/items/camera.rs +++ b/src/nodes/items/camera.rs @@ -2,6 +2,7 @@ use super::{create_item_acceptor_flex, register_item_ui_flex, Item, ItemType}; use crate::nodes::items::ITEM_ACCEPTOR_ASPECT_ALIAS_INFO; use crate::nodes::items::ITEM_ASPECT_ALIAS_INFO; use crate::nodes::Aspect; +use crate::nodes::AspectIdentifier; use crate::{ core::{client::Client, registry::Registry, scenegraph::MethodResponseSender}, nodes::{ @@ -168,18 +169,27 @@ impl CameraItem { } } } +impl AspectIdentifier for CameraItem { + impl_aspect_for_camera_item_aspect_id! {} +} impl Aspect for CameraItem { impl_aspect_for_camera_item_aspect! {} } impl CameraItemAspect for CameraItem {} pub struct CameraItemUi; +impl AspectIdentifier for CameraItemUi { + impl_aspect_for_camera_item_ui_aspect_id! {} +} impl Aspect for CameraItemUi { impl_aspect_for_camera_item_ui_aspect! {} } impl CameraItemUiAspect for CameraItemUi {} pub struct CameraItemAcceptor; +impl AspectIdentifier for CameraItemAcceptor { + impl_aspect_for_camera_item_acceptor_aspect_id! {} +} impl Aspect for CameraItemAcceptor { impl_aspect_for_camera_item_acceptor_aspect! {} } diff --git a/src/nodes/items/mod.rs b/src/nodes/items/mod.rs index 83acd41..6b0535a 100644 --- a/src/nodes/items/mod.rs +++ b/src/nodes/items/mod.rs @@ -6,7 +6,7 @@ use self::panel::PanelItemTrait; use super::alias::AliasList; use super::fields::{Field, FIELD_ALIAS_INFO}; use super::spatial::Spatial; -use super::{Alias, Aspect, Node}; +use super::{Alias, Aspect, AspectIdentifier, Node}; use crate::core::client::Client; use crate::core::registry::Registry; use crate::nodes::alias::AliasInfo; @@ -109,6 +109,9 @@ impl Item { ) } } +impl AspectIdentifier for Item { + impl_aspect_for_item_aspect_id! {} +} impl Aspect for Item { impl_aspect_for_item_aspect! {} } @@ -285,6 +288,9 @@ impl ItemUI { .remove_aspect(acceptor.field.as_ref()); } } +impl AspectIdentifier for ItemUI { + impl_aspect_for_item_ui_aspect_id! {} +} impl Aspect for ItemUI { impl_aspect_for_item_ui_aspect! {} } @@ -343,6 +349,9 @@ impl ItemAcceptor { let _ = item_acceptor_client::release_item(&node, alias.id); } } +impl AspectIdentifier for ItemAcceptor { + impl_aspect_for_item_acceptor_aspect_id! {} +} impl Aspect for ItemAcceptor { impl_aspect_for_item_acceptor_aspect! {} } diff --git a/src/nodes/items/panel.rs b/src/nodes/items/panel.rs index f238b7a..28ce336 100644 --- a/src/nodes/items/panel.rs +++ b/src/nodes/items/panel.rs @@ -2,7 +2,7 @@ use super::camera::CameraItemAcceptor; use super::{create_item_acceptor_flex, register_item_ui_flex}; use crate::nodes::items::ITEM_ACCEPTOR_ASPECT_ALIAS_INFO; use crate::nodes::items::ITEM_ASPECT_ALIAS_INFO; -use crate::nodes::Aspect; +use crate::nodes::{Aspect, AspectIdentifier}; use crate::{ core::{ client::{get_env, state, Client, INTERNAL_CLIENT}, @@ -207,7 +207,9 @@ impl PanelItem { panel_item_client::destroy_child(&node, id); } } - +impl AspectIdentifier for PanelItem { + impl_aspect_for_panel_item_aspect_id! {} +} impl Aspect for PanelItem { impl_aspect_for_panel_item_aspect! {} } @@ -418,12 +420,18 @@ impl PanelItemAspect for PanelItem { } pub struct PanelItemUi; +impl AspectIdentifier for PanelItemUi { + impl_aspect_for_panel_item_ui_aspect_id! {} +} impl Aspect for PanelItemUi { impl_aspect_for_panel_item_ui_aspect! {} } impl PanelItemUiAspect for PanelItemUi {} pub struct PanelItemAcceptor; +impl AspectIdentifier for PanelItemAcceptor { + impl_aspect_for_panel_item_acceptor_aspect_id! {} +} impl Aspect for PanelItemAcceptor { impl_aspect_for_panel_item_acceptor_aspect! {} } diff --git a/src/nodes/mod.rs b/src/nodes/mod.rs index 482f580..991effe 100644 --- a/src/nodes/mod.rs +++ b/src/nodes/mod.rs @@ -48,6 +48,9 @@ impl AsRef<[u8]> for Message { stardust_xr_server_codegen::codegen_node_protocol!(); pub struct Owned; +impl AspectIdentifier for Owned { + impl_aspect_for_owned_aspect_id! {} +} impl Aspect for Owned { impl_aspect_for_owned_aspect! {} } @@ -157,13 +160,13 @@ impl Node { // Ok(serialize(pid)?.into()) // } - pub fn add_aspect(&self, aspect: A) -> Arc { + pub fn add_aspect(&self, aspect: A) -> Arc { self.aspects.add(aspect) } - pub fn add_aspect_raw(&self, aspect: Arc) { + pub fn add_aspect_raw(&self, aspect: Arc) { self.aspects.add_raw(aspect) } - pub fn get_aspect(&self) -> Result> { + pub fn get_aspect(&self) -> Result> { self.aspects.get() } @@ -298,8 +301,10 @@ impl Drop for Node { } } +pub trait AspectIdentifier: Aspect { + const ID: u64; +} pub trait Aspect: Any + Send + Sync + 'static { - fn id(&self) -> u64; fn as_any(self: Arc) -> Arc; fn run_signal( &self, @@ -321,20 +326,21 @@ pub trait Aspect: Any + Send + Sync + 'static { #[derive(Default)] struct Aspects(Mutex>>); impl Aspects { - fn add(&self, t: A) -> Arc { + fn add(&self, t: A) -> Arc { let aspect = Arc::new(t); self.add_raw(aspect.clone()); aspect } - fn add_raw(&self, aspect: Arc) { - let id = aspect.id(); - self.0.lock().insert(id, aspect); + fn add_raw(&self, aspect: Arc) { + self.0.lock().insert(A::ID, aspect); } - fn get(&self) -> Result> { + fn get(&self) -> Result> { self.0 .lock() - .values() - .find_map(|a| Arc::downcast(a.clone().as_any()).ok()) + .get(&A::ID) + .cloned() + .map(|a| a.as_any()) + .and_then(|a| Arc::downcast(a).ok()) .ok_or(eyre!("Couldn't get aspect")) } } diff --git a/src/nodes/root.rs b/src/nodes/root.rs index c221fed..8151114 100644 --- a/src/nodes/root.rs +++ b/src/nodes/root.rs @@ -1,5 +1,5 @@ use super::spatial::Spatial; -use super::{Aspect, Node}; +use super::{Aspect, AspectIdentifier, Node}; use crate::core::client::Client; use crate::core::client_state::ClientStateParsed; use crate::core::registry::Registry; @@ -54,6 +54,9 @@ impl Root { Ok(root_client::save_state(&self.node).await?.0) } } +impl AspectIdentifier for Root { + impl_aspect_for_root_aspect_id! {} +} impl Aspect for Root { impl_aspect_for_root_aspect! {} } diff --git a/src/nodes/spatial/mod.rs b/src/nodes/spatial/mod.rs index b579e8a..b50dac7 100644 --- a/src/nodes/spatial/mod.rs +++ b/src/nodes/spatial/mod.rs @@ -3,7 +3,7 @@ pub mod zone; use self::zone::Zone; use super::alias::Alias; use super::fields::{Field, FieldTrait}; -use super::Aspect; +use super::{Aspect, AspectIdentifier}; use crate::core::client::Client; use crate::core::registry::Registry; use crate::nodes::{Node, OWNED_ASPECT_ALIAS_INFO}; @@ -37,6 +37,9 @@ impl Transform { Mat4::from_scale_rotation_translation(scale.into(), rotation.into(), position.into()) } } +impl AspectIdentifier for Zone { + impl_aspect_for_zone_aspect_id! {} +} impl Aspect for Zone { impl_aspect_for_zone_aspect! {} } @@ -241,6 +244,9 @@ impl Spatial { .unwrap_or(f32::MAX) } } +impl AspectIdentifier for Spatial { + impl_aspect_for_spatial_aspect_id! {} +} impl Aspect for Spatial { impl_aspect_for_spatial_aspect! {} } @@ -331,6 +337,9 @@ impl Drop for Spatial { } pub struct SpatialRef; +impl AspectIdentifier for SpatialRef { + impl_aspect_for_spatial_ref_aspect_id! {} +} impl Aspect for SpatialRef { impl_aspect_for_spatial_ref_aspect! {} }