refactor: optimize get aspect hotpath

This commit is contained in:
Nova
2024-12-29 09:44:50 -08:00
parent 8f18d83694
commit c0141da88b
12 changed files with 117 additions and 28 deletions

View File

@@ -69,6 +69,9 @@ fn codegen_protocol(protocol: &'static str) -> proc_macro::TokenStream {
#node_id #node_id
#aspect #aspect
pub struct Interface; pub struct Interface;
impl crate::nodes::AspectIdentifier for Interface {
impl_aspect_for_interface_aspect_id!{}
}
impl crate::nodes::Aspect for Interface { impl crate::nodes::Aspect for Interface {
impl_aspect_for_interface_aspect!{} impl_aspect_for_interface_aspect!{}
} }
@@ -255,6 +258,13 @@ fn generate_aspect(aspect: &Aspect) -> TokenStream {
#server_side_members #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( let aspect_macro_name = Ident::new(
&format!( &format!(
"impl_aspect_for_{}_aspect", "impl_aspect_for_{}_aspect",
@@ -264,11 +274,13 @@ fn generate_aspect(aspect: &Aspect) -> TokenStream {
); );
let aspect_id = aspect.id; let aspect_id = aspect.id;
let aspect_macro = quote! { let aspect_macro = quote! {
macro_rules! #aspect_id_macro_name {
() => {
const ID: u64 = #aspect_id;
}
}
macro_rules! #aspect_macro_name { macro_rules! #aspect_macro_name {
() => { () => {
fn id(&self) -> u64 {
#aspect_id
}
fn as_any(self: Arc<Self>) -> Arc<dyn std::any::Any + Send + Sync + 'static> { fn as_any(self: Arc<Self>) -> Arc<dyn std::any::Any + Send + Sync + 'static> {
self self
} }

View File

@@ -1,4 +1,4 @@
use super::{Aspect, Node}; use super::{Aspect, AspectIdentifier, Node};
use crate::core::{client::Client, registry::Registry}; use crate::core::{client::Client, registry::Registry};
use color_eyre::eyre::Result; use color_eyre::eyre::Result;
use std::{ use std::{
@@ -68,10 +68,10 @@ impl Alias {
Ok(()) Ok(())
} }
} }
impl AspectIdentifier for Alias {
const ID: u64 = 0;
}
impl Aspect for Alias { impl Aspect for Alias {
fn id(&self) -> u64 {
0
}
fn as_any(self: Arc<Self>) -> Arc<dyn std::any::Any + Send + Sync + 'static> { fn as_any(self: Arc<Self>) -> Arc<dyn std::any::Any + Send + Sync + 'static> {
self self
} }
@@ -129,7 +129,7 @@ impl AliasList {
.into_iter() .into_iter()
.find(move |node| links_to(node.clone(), original.clone())) .find(move |node| links_to(node.clone(), original.clone()))
} }
pub fn get_from_aspect<A: Aspect>(&self, aspect: &A) -> Option<Arc<Node>> { pub fn get_from_aspect<A: AspectIdentifier>(&self, aspect: &A) -> Option<Arc<Node>> {
self.0.get_valid_contents().into_iter().find(|node| { self.0.get_valid_contents().into_iter().find(|node| {
let Some(node) = get_original(node.clone(), false) else { let Some(node) = get_original(node.clone(), false) else {
return false; return false;
@@ -143,7 +143,7 @@ impl AliasList {
pub fn get_aliases(&self) -> Vec<Arc<Node>> { pub fn get_aliases(&self) -> Vec<Arc<Node>> {
self.0.get_valid_contents() self.0.get_valid_contents()
} }
pub fn remove_aspect<A: Aspect>(&self, aspect: &A) { pub fn remove_aspect<A: AspectIdentifier>(&self, aspect: &A) {
self.0.retain(|node| { self.0.retain(|node| {
let Some(original) = get_original(node.clone(), false) else { let Some(original) = get_original(node.clone(), false) else {
return false; return false;

View File

@@ -1,4 +1,4 @@
use super::{Aspect, Node}; use super::{Aspect, AspectIdentifier, Node};
use crate::core::client::Client; use crate::core::client::Client;
use crate::core::destroy_queue; use crate::core::destroy_queue;
use crate::core::registry::Registry; 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 {
impl_aspect_for_sound_aspect! {} impl_aspect_for_sound_aspect! {}
} }

View File

@@ -8,7 +8,7 @@ pub mod text;
use self::{lines::Lines, model::Model, text::Text}; use self::{lines::Lines, model::Model, text::Text};
use super::{ use super::{
spatial::{Spatial, Transform}, spatial::{Spatial, Transform},
Aspect, Node, Aspect, AspectIdentifier, Node,
}; };
use crate::core::{client::Client, resource::get_resource_file}; use crate::core::{client::Client, resource::get_resource_file};
use crate::nodes::spatial::SPATIAL_ASPECT_ALIAS_INFO; use crate::nodes::spatial::SPATIAL_ASPECT_ALIAS_INFO;
@@ -41,15 +41,28 @@ static QUEUED_SKYLIGHT: Mutex<Option<PathBuf>> = Mutex::new(None);
static QUEUED_SKYTEX: Mutex<Option<PathBuf>> = Mutex::new(None); static QUEUED_SKYTEX: Mutex<Option<PathBuf>> = Mutex::new(None);
stardust_xr_server_codegen::codegen_drawable_protocol!(); 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 {
impl_aspect_for_lines_aspect! {} impl_aspect_for_lines_aspect! {}
} }
impl AspectIdentifier for Model {
impl_aspect_for_model_aspect_id! {}
}
impl Aspect for Model { impl Aspect for Model {
impl_aspect_for_model_aspect! {} impl_aspect_for_model_aspect! {}
} }
impl AspectIdentifier for ModelPart {
impl_aspect_for_model_part_aspect_id! {}
}
impl Aspect for ModelPart { impl Aspect for ModelPart {
impl_aspect_for_model_part_aspect! {} impl_aspect_for_model_part_aspect! {}
} }
impl AspectIdentifier for Text {
impl_aspect_for_text_aspect_id! {}
}
impl Aspect for Text { impl Aspect for Text {
impl_aspect_for_text_aspect! {} impl_aspect_for_text_aspect! {}
} }

View File

@@ -3,7 +3,7 @@ use super::spatial::{
Spatial, SPATIAL_REF_GET_LOCAL_BOUNDING_BOX_SERVER_OPCODE, Spatial, SPATIAL_REF_GET_LOCAL_BOUNDING_BOX_SERVER_OPCODE,
SPATIAL_REF_GET_RELATIVE_BOUNDING_BOX_SERVER_OPCODE, SPATIAL_REF_GET_TRANSFORM_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::core::client::Client;
use crate::nodes::spatial::Transform; use crate::nodes::spatial::Transform;
use crate::nodes::spatial::SPATIAL_ASPECT_ALIAS_INFO; use crate::nodes::spatial::SPATIAL_ASPECT_ALIAS_INFO;
@@ -148,6 +148,9 @@ impl Field {
Ok(field) Ok(field)
} }
} }
impl AspectIdentifier for Field {
impl_aspect_for_field_aspect_id! {}
}
impl Aspect for Field { impl Aspect for Field {
impl_aspect_for_field_aspect! {} impl_aspect_for_field_aspect! {}
} }
@@ -193,6 +196,9 @@ impl FieldTrait for Field {
} }
pub struct FieldRef; pub struct FieldRef;
impl AspectIdentifier for FieldRef {
impl_aspect_for_field_ref_aspect_id! {}
}
impl Aspect for FieldRef { impl Aspect for FieldRef {
impl_aspect_for_field_ref_aspect! {} impl_aspect_for_field_ref_aspect! {}
} }

View File

@@ -12,6 +12,7 @@ pub use method::*;
use super::fields::Field; use super::fields::Field;
use super::spatial::Spatial; use super::spatial::Spatial;
use super::Aspect; use super::Aspect;
use super::AspectIdentifier;
use crate::nodes::spatial::SPATIAL_ASPECT_ALIAS_INFO; use crate::nodes::spatial::SPATIAL_ASPECT_ALIAS_INFO;
use crate::nodes::spatial::SPATIAL_REF_ASPECT_ALIAS_INFO; use crate::nodes::spatial::SPATIAL_REF_ASPECT_ALIAS_INFO;
use crate::{core::client::Client, nodes::Node}; use crate::{core::client::Client, nodes::Node};
@@ -25,12 +26,21 @@ pub static INPUT_HANDLER_REGISTRY: Registry<InputHandler> = Registry::new();
stardust_xr_server_codegen::codegen_input_protocol!(); 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 InputHandler {
impl_aspect_for_input_handler_aspect! {} impl_aspect_for_input_handler_aspect! {}
} }
impl AspectIdentifier for InputMethod {
impl_aspect_for_input_method_aspect_id! {}
}
impl Aspect for InputMethod { impl Aspect for InputMethod {
impl_aspect_for_input_method_aspect! {} 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 InputMethodRef {
impl_aspect_for_input_method_ref_aspect! {} impl_aspect_for_input_method_ref_aspect! {}
} }

View File

@@ -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_ACCEPTOR_ASPECT_ALIAS_INFO;
use crate::nodes::items::ITEM_ASPECT_ALIAS_INFO; use crate::nodes::items::ITEM_ASPECT_ALIAS_INFO;
use crate::nodes::Aspect; use crate::nodes::Aspect;
use crate::nodes::AspectIdentifier;
use crate::{ use crate::{
core::{client::Client, registry::Registry, scenegraph::MethodResponseSender}, core::{client::Client, registry::Registry, scenegraph::MethodResponseSender},
nodes::{ 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 CameraItem {
impl_aspect_for_camera_item_aspect! {} impl_aspect_for_camera_item_aspect! {}
} }
impl CameraItemAspect for CameraItem {} impl CameraItemAspect for CameraItem {}
pub struct CameraItemUi; pub struct CameraItemUi;
impl AspectIdentifier for CameraItemUi {
impl_aspect_for_camera_item_ui_aspect_id! {}
}
impl Aspect for CameraItemUi { impl Aspect for CameraItemUi {
impl_aspect_for_camera_item_ui_aspect! {} impl_aspect_for_camera_item_ui_aspect! {}
} }
impl CameraItemUiAspect for CameraItemUi {} impl CameraItemUiAspect for CameraItemUi {}
pub struct CameraItemAcceptor; pub struct CameraItemAcceptor;
impl AspectIdentifier for CameraItemAcceptor {
impl_aspect_for_camera_item_acceptor_aspect_id! {}
}
impl Aspect for CameraItemAcceptor { impl Aspect for CameraItemAcceptor {
impl_aspect_for_camera_item_acceptor_aspect! {} impl_aspect_for_camera_item_acceptor_aspect! {}
} }

View File

@@ -6,7 +6,7 @@ use self::panel::PanelItemTrait;
use super::alias::AliasList; use super::alias::AliasList;
use super::fields::{Field, FIELD_ALIAS_INFO}; use super::fields::{Field, FIELD_ALIAS_INFO};
use super::spatial::Spatial; use super::spatial::Spatial;
use super::{Alias, Aspect, Node}; use super::{Alias, Aspect, AspectIdentifier, Node};
use crate::core::client::Client; use crate::core::client::Client;
use crate::core::registry::Registry; use crate::core::registry::Registry;
use crate::nodes::alias::AliasInfo; 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 {
impl_aspect_for_item_aspect! {} impl_aspect_for_item_aspect! {}
} }
@@ -285,6 +288,9 @@ impl ItemUI {
.remove_aspect(acceptor.field.as_ref()); .remove_aspect(acceptor.field.as_ref());
} }
} }
impl AspectIdentifier for ItemUI {
impl_aspect_for_item_ui_aspect_id! {}
}
impl Aspect for ItemUI { impl Aspect for ItemUI {
impl_aspect_for_item_ui_aspect! {} impl_aspect_for_item_ui_aspect! {}
} }
@@ -343,6 +349,9 @@ impl ItemAcceptor {
let _ = item_acceptor_client::release_item(&node, alias.id); 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 ItemAcceptor {
impl_aspect_for_item_acceptor_aspect! {} impl_aspect_for_item_acceptor_aspect! {}
} }

View File

@@ -2,7 +2,7 @@ use super::camera::CameraItemAcceptor;
use super::{create_item_acceptor_flex, register_item_ui_flex}; use super::{create_item_acceptor_flex, register_item_ui_flex};
use crate::nodes::items::ITEM_ACCEPTOR_ASPECT_ALIAS_INFO; use crate::nodes::items::ITEM_ACCEPTOR_ASPECT_ALIAS_INFO;
use crate::nodes::items::ITEM_ASPECT_ALIAS_INFO; use crate::nodes::items::ITEM_ASPECT_ALIAS_INFO;
use crate::nodes::Aspect; use crate::nodes::{Aspect, AspectIdentifier};
use crate::{ use crate::{
core::{ core::{
client::{get_env, state, Client, INTERNAL_CLIENT}, client::{get_env, state, Client, INTERNAL_CLIENT},
@@ -207,7 +207,9 @@ impl<B: Backend> PanelItem<B> {
panel_item_client::destroy_child(&node, id); panel_item_client::destroy_child(&node, id);
} }
} }
impl<B: Backend> AspectIdentifier for PanelItem<B> {
impl_aspect_for_panel_item_aspect_id! {}
}
impl<B: Backend> Aspect for PanelItem<B> { impl<B: Backend> Aspect for PanelItem<B> {
impl_aspect_for_panel_item_aspect! {} impl_aspect_for_panel_item_aspect! {}
} }
@@ -418,12 +420,18 @@ impl<B: Backend> PanelItemAspect for PanelItem<B> {
} }
pub struct PanelItemUi; pub struct PanelItemUi;
impl AspectIdentifier for PanelItemUi {
impl_aspect_for_panel_item_ui_aspect_id! {}
}
impl Aspect for PanelItemUi { impl Aspect for PanelItemUi {
impl_aspect_for_panel_item_ui_aspect! {} impl_aspect_for_panel_item_ui_aspect! {}
} }
impl PanelItemUiAspect for PanelItemUi {} impl PanelItemUiAspect for PanelItemUi {}
pub struct PanelItemAcceptor; pub struct PanelItemAcceptor;
impl AspectIdentifier for PanelItemAcceptor {
impl_aspect_for_panel_item_acceptor_aspect_id! {}
}
impl Aspect for PanelItemAcceptor { impl Aspect for PanelItemAcceptor {
impl_aspect_for_panel_item_acceptor_aspect! {} impl_aspect_for_panel_item_acceptor_aspect! {}
} }

View File

@@ -48,6 +48,9 @@ impl AsRef<[u8]> for Message {
stardust_xr_server_codegen::codegen_node_protocol!(); stardust_xr_server_codegen::codegen_node_protocol!();
pub struct Owned; pub struct Owned;
impl AspectIdentifier for Owned {
impl_aspect_for_owned_aspect_id! {}
}
impl Aspect for Owned { impl Aspect for Owned {
impl_aspect_for_owned_aspect! {} impl_aspect_for_owned_aspect! {}
} }
@@ -157,13 +160,13 @@ impl Node {
// Ok(serialize(pid)?.into()) // Ok(serialize(pid)?.into())
// } // }
pub fn add_aspect<A: Aspect>(&self, aspect: A) -> Arc<A> { pub fn add_aspect<A: AspectIdentifier>(&self, aspect: A) -> Arc<A> {
self.aspects.add(aspect) self.aspects.add(aspect)
} }
pub fn add_aspect_raw<A: Aspect>(&self, aspect: Arc<A>) { pub fn add_aspect_raw<A: AspectIdentifier>(&self, aspect: Arc<A>) {
self.aspects.add_raw(aspect) self.aspects.add_raw(aspect)
} }
pub fn get_aspect<A: Aspect>(&self) -> Result<Arc<A>> { pub fn get_aspect<A: AspectIdentifier>(&self) -> Result<Arc<A>> {
self.aspects.get() 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 { pub trait Aspect: Any + Send + Sync + 'static {
fn id(&self) -> u64;
fn as_any(self: Arc<Self>) -> Arc<dyn Any + Send + Sync + 'static>; fn as_any(self: Arc<Self>) -> Arc<dyn Any + Send + Sync + 'static>;
fn run_signal( fn run_signal(
&self, &self,
@@ -321,20 +326,21 @@ pub trait Aspect: Any + Send + Sync + 'static {
#[derive(Default)] #[derive(Default)]
struct Aspects(Mutex<FxHashMap<u64, Arc<dyn Aspect>>>); struct Aspects(Mutex<FxHashMap<u64, Arc<dyn Aspect>>>);
impl Aspects { impl Aspects {
fn add<A: Aspect>(&self, t: A) -> Arc<A> { fn add<A: AspectIdentifier>(&self, t: A) -> Arc<A> {
let aspect = Arc::new(t); let aspect = Arc::new(t);
self.add_raw(aspect.clone()); self.add_raw(aspect.clone());
aspect aspect
} }
fn add_raw<A: Aspect>(&self, aspect: Arc<A>) { fn add_raw<A: AspectIdentifier>(&self, aspect: Arc<A>) {
let id = aspect.id(); self.0.lock().insert(A::ID, aspect);
self.0.lock().insert(id, aspect);
} }
fn get<A: Aspect>(&self) -> Result<Arc<A>> { fn get<A: Aspect + AspectIdentifier>(&self) -> Result<Arc<A>> {
self.0 self.0
.lock() .lock()
.values() .get(&A::ID)
.find_map(|a| Arc::downcast(a.clone().as_any()).ok()) .cloned()
.map(|a| a.as_any())
.and_then(|a| Arc::downcast(a).ok())
.ok_or(eyre!("Couldn't get aspect")) .ok_or(eyre!("Couldn't get aspect"))
} }
} }

View File

@@ -1,5 +1,5 @@
use super::spatial::Spatial; use super::spatial::Spatial;
use super::{Aspect, Node}; use super::{Aspect, AspectIdentifier, Node};
use crate::core::client::Client; use crate::core::client::Client;
use crate::core::client_state::ClientStateParsed; use crate::core::client_state::ClientStateParsed;
use crate::core::registry::Registry; use crate::core::registry::Registry;
@@ -54,6 +54,9 @@ impl Root {
Ok(root_client::save_state(&self.node).await?.0) 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 {
impl_aspect_for_root_aspect! {} impl_aspect_for_root_aspect! {}
} }

View File

@@ -3,7 +3,7 @@ pub mod zone;
use self::zone::Zone; use self::zone::Zone;
use super::alias::Alias; use super::alias::Alias;
use super::fields::{Field, FieldTrait}; use super::fields::{Field, FieldTrait};
use super::Aspect; use super::{Aspect, AspectIdentifier};
use crate::core::client::Client; use crate::core::client::Client;
use crate::core::registry::Registry; use crate::core::registry::Registry;
use crate::nodes::{Node, OWNED_ASPECT_ALIAS_INFO}; 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()) 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 {
impl_aspect_for_zone_aspect! {} impl_aspect_for_zone_aspect! {}
} }
@@ -241,6 +244,9 @@ impl Spatial {
.unwrap_or(f32::MAX) .unwrap_or(f32::MAX)
} }
} }
impl AspectIdentifier for Spatial {
impl_aspect_for_spatial_aspect_id! {}
}
impl Aspect for Spatial { impl Aspect for Spatial {
impl_aspect_for_spatial_aspect! {} impl_aspect_for_spatial_aspect! {}
} }
@@ -331,6 +337,9 @@ impl Drop for Spatial {
} }
pub struct SpatialRef; pub struct SpatialRef;
impl AspectIdentifier for SpatialRef {
impl_aspect_for_spatial_ref_aspect_id! {}
}
impl Aspect for SpatialRef { impl Aspect for SpatialRef {
impl_aspect_for_spatial_ref_aspect! {} impl_aspect_for_spatial_ref_aspect! {}
} }