feat: optimization

This commit is contained in:
Nova
2023-10-08 18:44:52 -04:00
parent 3d4ab27a14
commit f045bfb93d
15 changed files with 170 additions and 113 deletions

View File

@@ -7,33 +7,32 @@ use std::{
sync::{Arc, Weak},
};
#[derive(Default)]
pub struct LifeLinkedNodeList {
nodes: Mutex<Vec<Weak<Node>>>,
}
impl LifeLinkedNodeList {
pub fn add(&self, node: Weak<Node>) {
self.nodes.lock().push(node);
}
// #[derive(Default)]
// pub struct LifeLinkedNodeList {
// nodes: Mutex<Vec<Weak<Node>>>,
// }
// impl LifeLinkedNodeList {
// pub fn add(&self, node: Weak<Node>) {
// self.nodes.lock().push(node);
// }
// pub fn clear(&self) {
// self.nodes
// .lock()
// .iter()
// .filter_map(|node| node.upgrade())
// .for_each(|node| {
// node.destroy();
// });
// self.nodes.lock().clear();
// }
// }
// impl Drop for LifeLinkedNodeList {
// fn drop(&mut self) {
// self.clear();
// }
// }
pub fn clear(&self) {
self.nodes
.lock()
.iter()
.filter_map(|node| node.upgrade())
.for_each(|node| {
node.destroy();
});
self.nodes.lock().clear();
}
}
impl Drop for LifeLinkedNodeList {
fn drop(&mut self) {
self.clear();
}
}
#[derive(Default)]
#[derive(Default, Debug)]
pub struct LifeLinkedNodeMap<K: Hash + Eq> {
nodes: Mutex<FxHashMap<K, Weak<Node>>>,
}

View File

@@ -3,13 +3,14 @@ use crate::{core::client::Client, nodes::Message};
use color_eyre::eyre::Result;
use once_cell::sync::OnceCell;
use parking_lot::Mutex;
use portable_atomic::Ordering;
use rustc_hash::FxHashMap;
use stardust_xr::scenegraph;
use stardust_xr::scenegraph::ScenegraphError;
use std::os::fd::OwnedFd;
use std::sync::{Arc, Weak};
use tokio::sync::oneshot;
use tracing::{debug, debug_span, instrument};
use tracing::{debug, debug_span};
#[derive(Default)]
pub struct Scenegraph {
@@ -33,11 +34,14 @@ impl Scenegraph {
self.nodes.lock().insert(path, node);
}
#[instrument(level = "debug", skip(self))]
pub fn get_node(&self, path: &str) -> Option<Arc<Node>> {
let mut node = self.nodes.lock().get(path)?.clone();
while let Some(alias) = node.alias.get() {
node = alias.original.upgrade()?;
if alias.enabled.load(Ordering::Relaxed) {
node = alias.original.upgrade()?;
} else {
return None;
}
}
Some(node)
}

View File

@@ -1,10 +1,8 @@
use color_eyre::eyre::Result;
use std::future::Future;
use tokio::task::JoinHandle;
use tracing::instrument;
#[allow(unused_variables)]
#[instrument(level = "debug", skip_all)]
pub fn new<
F: FnOnce() -> S,
S: AsRef<str>,

View File

@@ -67,14 +67,18 @@ struct EventLoopInfo {
socket_path: PathBuf,
}
fn setup_tracing() {
fn main() {
ctrlc::set_handler(|| {
if atty::isnt(atty::Stream::Stdout) {
STOP_NOTIFIER.notify_waiters()
}
})
.unwrap();
let registry = tracing_subscriber::registry();
#[cfg(feature = "profile_app")]
let (chrome_layer, _guard) = tracing_chrome::ChromeLayerBuilder::new()
.include_args(true)
.build();
#[cfg(feature = "profile_app")]
let registry = registry.with(chrome_layer);
let registry = registry.with(tracing_tracy::TracyLayer::new().with_filter(LevelFilter::DEBUG));
#[cfg(feature = "profile_tokio")]
let (console_layer, _) = console_subscriber::ConsoleLayer::builder().build();
@@ -87,17 +91,6 @@ fn setup_tracing() {
.with_line_number(true)
.with_filter(EnvFilter::from_default_env());
registry.with(log_layer).init();
}
fn main() {
ctrlc::set_handler(|| {
if atty::isnt(atty::Stream::Stdout) {
STOP_NOTIFIER.notify_waiters()
}
})
.unwrap();
setup_tracing();
let project_dirs = ProjectDirs::from("", "", "stardust");
if project_dirs.is_none() {

View File

@@ -1,6 +1,7 @@
use super::Node;
use crate::core::client::Client;
use color_eyre::eyre::{ensure, Result};
use portable_atomic::AtomicBool;
use std::sync::{Arc, Weak};
#[derive(Debug, Default, Clone)]
@@ -12,6 +13,7 @@ pub struct AliasInfo {
#[allow(dead_code)]
pub struct Alias {
pub enabled: Arc<AtomicBool>,
pub(super) node: Weak<Node>,
pub original: Weak<Node>,
@@ -35,6 +37,7 @@ impl Alias {
let node = Node::create(client, parent, name, true).add_to_scenegraph()?;
let alias = Alias {
enabled: Arc::new(AtomicBool::new(true)),
node: Arc::downgrade(&node),
original: Arc::downgrade(original),
info,

View File

@@ -7,7 +7,6 @@ use color_eyre::eyre::Result;
use glam::{vec3, Mat4};
use std::sync::Arc;
use stereokit::StereoKitMultiThread;
use tracing::instrument;
lazy_static::lazy_static! {
static ref HMD: Arc<Node> = create();
@@ -20,7 +19,6 @@ fn create() -> Arc<Node> {
node
}
#[instrument(level = "debug", name = "Update HMD Pose", skip(sk))]
pub fn frame(sk: &impl StereoKitMultiThread) {
let spatial = HMD
.spatial

View File

@@ -12,8 +12,8 @@ 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::{node_collections::LifeLinkedNodeList, registry::Registry};
use color_eyre::eyre::{ensure, Result};
use glam::Mat4;
use once_cell::sync::OnceCell;
@@ -99,6 +99,7 @@ impl InputMethod {
};
for handler in INPUT_HANDLER_REGISTRY.get_valid_contents() {
method.handle_new_handler(&handler);
method.make_alias(&handler);
}
let method = INPUT_METHOD_REGISTRY.add(method);
let _ = node.input_method.set(method.clone());
@@ -137,6 +138,26 @@ impl InputMethod {
Ok(())
}
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 Ok(method_alias) = Alias::create(
&client,
handler_node.get_path(),
&self.uid,
&method_node,
AliasInfo {
server_signals: vec!["capture"],
..Default::default()
},
) else {return};
method_alias.enabled.store(false, Ordering::Relaxed);
handler
.method_aliases
.add(self as *const InputMethod as usize, &method_alias);
}
fn compare_distance(&self, to: &Field) -> f32 {
self.specialization
.lock()
@@ -201,25 +222,12 @@ pub struct DistanceLink {
handler: Arc<InputHandler>,
}
impl DistanceLink {
fn from(method: Arc<InputMethod>, handler: Arc<InputHandler>) -> Option<Self> {
let handler_node = handler.node.upgrade()?;
let method_alias = Alias::create(
&handler_node.get_client()?,
handler_node.get_path(),
&method.uid,
&method.node.upgrade()?,
AliasInfo {
server_signals: vec!["capture"],
..Default::default()
},
)
.ok()?;
handler.method_aliases.add(Arc::downgrade(&method_alias));
Some(DistanceLink {
fn from(method: Arc<InputMethod>, handler: Arc<InputHandler>) -> Self {
DistanceLink {
distance: method.compare_distance(&handler.field),
method,
handler,
})
}
}
fn send_input(&self, order: u32, datamap: Datamap) {
@@ -249,7 +257,7 @@ pub struct InputHandler {
node: Weak<Node>,
spatial: Arc<Spatial>,
field: Arc<Field>,
method_aliases: LifeLinkedNodeList,
method_aliases: LifeLinkedNodeMap<usize>,
}
impl InputHandler {
pub fn add_to(node: &Arc<Node>, field: &Arc<Field>) -> Result<()> {
@@ -264,9 +272,10 @@ impl InputHandler {
node: Arc::downgrade(node),
spatial: node.spatial.get().unwrap().clone(),
field: field.clone(),
method_aliases: LifeLinkedNodeList::default(),
method_aliases: LifeLinkedNodeMap::default(),
};
for method in INPUT_METHOD_REGISTRY.get_valid_contents() {
method.make_alias(&handler);
method.handle_new_handler(&handler);
}
let handler = INPUT_HANDLER_REGISTRY.add(handler);
@@ -343,10 +352,12 @@ pub fn process_input() {
.filter(|method| method.datamap.lock().is_some())
});
let handlers = INPUT_HANDLER_REGISTRY.get_valid_contents();
for handler in &handlers {
handler.method_aliases.clear();
}
const LIMIT: usize = 50;
for method in methods {
for alias in method.node.upgrade().unwrap().aliases.get_valid_contents() {
alias.enabled.store(false, Ordering::Relaxed);
}
debug_span!("Process input method").in_scope(|| {
// Get all valid input handlers and convert them to DistanceLink objects
let distance_links: Vec<DistanceLink> = debug_span!("Generate distance links")
@@ -357,14 +368,16 @@ pub fn process_input() {
.iter()
.filter_map(|h| h.upgrade())
.filter(|handler| handler.enabled.load(Ordering::Relaxed))
.filter_map(|handler| DistanceLink::from(method.clone(), handler))
.map(|handler| DistanceLink::from(method.clone(), handler))
.collect()
} else {
let mut distance_links: Vec<_> = handlers
.iter()
.filter(|handler| handler.enabled.load(Ordering::Relaxed))
.filter_map(|handler| {
DistanceLink::from(method.clone(), handler.clone())
.map(|handler| {
debug_span!("Create distance link").in_scope(|| {
DistanceLink::from(method.clone(), handler.clone())
})
})
.collect();
@@ -375,6 +388,9 @@ pub fn process_input() {
});
});
distance_links.reverse();
distance_links.truncate(LIMIT);
distance_links.reverse();
distance_links
}
});
@@ -382,6 +398,18 @@ pub fn process_input() {
let captures = method.captures.take_valid_contents();
// Iterate over the distance links and send input to them
for (i, distance_link) in distance_links.into_iter().enumerate() {
if i > LIMIT {
break;
}
if let Some(method_alias) = distance_link
.handler
.method_aliases
.get(&(Arc::as_ptr(&distance_link.method) as usize))
.and_then(|a| a.alias.get().cloned())
{
method_alias.enabled.store(true, Ordering::Relaxed);
}
distance_link.send_input(i as u32, method.datamap.lock().clone().unwrap());
// If the current distance link is in the list of captured input handlers,

View File

@@ -23,7 +23,6 @@ use std::future::Future;
use std::os::fd::OwnedFd;
use std::sync::{Arc, Weak};
use std::vec::Vec;
use tracing::instrument;
use crate::core::client::Client;
use crate::core::registry::Registry;
@@ -272,7 +271,6 @@ impl Node {
method(self, calling_client, message, response);
}
}
#[instrument(level = "debug", skip_all)]
pub fn send_remote_signal(&self, method: &str, message: impl Into<Message>) -> Result<()> {
let message = message.into();
self.aliases
@@ -297,7 +295,6 @@ impl Node {
}
Ok(())
}
// #[instrument(level = "debug", skip_all)]
pub fn execute_remote_method(
&self,
method: &str,

View File

@@ -17,7 +17,6 @@ use std::fmt::Debug;
use std::ptr;
use std::sync::{Arc, OnceLock, Weak};
use stereokit::{bounds_grow_to_fit_box, Bounds};
use tracing::instrument;
static ZONEABLE_REGISTRY: Registry<Spatial> = Registry::new();
@@ -81,7 +80,6 @@ impl Spatial {
self.node.upgrade()
}
#[instrument(level = "debug", skip_all)]
pub fn space_to_space_matrix(from: Option<&Spatial>, to: Option<&Spatial>) -> Mat4 {
let space_to_world_matrix = from.map_or(Mat4::IDENTITY, |from| from.global_transform());
let world_to_space_matrix = to.map_or(Mat4::IDENTITY, |to| to.global_transform().inverse());
@@ -89,7 +87,6 @@ impl Spatial {
}
// the output bounds are probably way bigger than they need to be
#[instrument(level = "debug")]
pub fn get_bounding_box(&self) -> Bounds {
let Some(node) = self.node() else {return Bounds::default()};
let mut bounds = self
@@ -107,7 +104,6 @@ impl Spatial {
bounds
}
#[instrument(level = "debug", skip_all)]
pub fn local_transform(&self) -> Mat4 {
*self.transform.lock()
}
@@ -117,11 +113,9 @@ impl Spatial {
None => *self.transform.lock(),
}
}
#[instrument]
pub fn set_local_transform(&self, transform: Mat4) {
*self.transform.lock() = transform;
}
#[instrument(level = "debug", skip(self, reference_space))]
pub fn set_local_transform_components(
&self,
reference_space: Option<&Spatial>,
@@ -165,7 +159,6 @@ impl Spatial {
);
}
#[instrument(level = "debug", skip_all)]
pub fn is_ancestor_of(&self, spatial: Arc<Spatial>) -> bool {
let mut current_ancestor = spatial;
loop {
@@ -197,7 +190,6 @@ impl Spatial {
*self.parent.lock() = new_parent;
}
#[instrument(level = "debug", skip_all)]
pub fn set_spatial_parent(&self, parent: Option<Arc<Spatial>>) -> Result<()> {
let is_ancestor = parent
.as_ref()
@@ -211,7 +203,6 @@ impl Spatial {
Ok(())
}
#[instrument(level = "debug", skip_all)]
pub fn set_spatial_parent_in_place(&self, parent: Option<Arc<Spatial>>) -> Result<()> {
let is_ancestor = parent
.as_ref()
@@ -437,7 +428,6 @@ impl Spatial {
});
}
#[instrument]
pub(self) fn zone_distance(&self) -> f32 {
self.zone
.lock()

View File

@@ -13,7 +13,6 @@ use serde::Serialize;
use stardust_xr::schemas::{flat::Datamap, flex::flexbuffers};
use std::sync::Arc;
use stereokit::StereoKitMultiThread;
use tracing::instrument;
#[derive(Debug, Clone, Serialize)]
pub struct KeyboardEvent {
@@ -36,7 +35,6 @@ impl EyePointer {
Ok(EyePointer { spatial, pointer })
}
#[instrument(level = "debug", name = "Update Flatscreen Pointer Ray", skip_all)]
pub fn update(&self, sk: &impl StereoKitMultiThread) {
let ray = sk.input_eyes();
self.spatial

View File

@@ -14,7 +14,6 @@ use nanoid::nanoid;
use serde::{Deserialize, Serialize};
use std::{convert::TryFrom, sync::Arc};
use stereokit::{ray_from_mouse, ButtonState, Key, StereoKitMultiThread};
use tracing::instrument;
use xkbcommon::xkb::{Context, Keymap, FORMAT_TEXT_V1};
#[derive(Default, Deserialize, Serialize)]
@@ -77,7 +76,6 @@ impl MousePointer {
keyboard_sender,
})
}
#[instrument(level = "debug", name = "Update Flatscreen Pointer Ray", skip_all)]
pub fn update(&mut self, sk: &impl StereoKitMultiThread) {
let mouse = sk.input_mouse();

View File

@@ -14,7 +14,6 @@ use stereokit::{
named_colors::WHITE, ButtonState, Handed, Model, RenderLayer, StereoKitDraw,
StereoKitMultiThread,
};
use tracing::instrument;
#[derive(Default, Deserialize, Serialize)]
struct ControllerDatamap {
@@ -55,7 +54,6 @@ impl SkController {
datamap: Default::default(),
})
}
#[instrument(level = "debug", name = "Update StereoKit Tip Input Method", skip_all)]
pub fn update(&mut self, sk: &impl StereoKitDraw) {
let controller = sk.input_controller(self.handed);
*self.input.enabled.lock() = controller.tracked.contains(ButtonState::ACTIVE);

View File

@@ -13,7 +13,6 @@ use serde::{Deserialize, Serialize};
use stardust_xr::schemas::flat::{Hand as FlatHand, Joint};
use std::sync::Arc;
use stereokit::{ButtonState, HandJoint, Handed, StereoKitMultiThread};
use tracing::instrument;
fn convert_joint(joint: HandJoint) -> Joint {
Joint {
@@ -54,7 +53,6 @@ impl SkHand {
datamap: Default::default(),
})
}
#[instrument(level = "debug", name = "Update Hand Input Method", skip_all)]
pub fn update(&mut self, controller_enabled: bool, sk: &impl StereoKitMultiThread) {
let sk_hand = sk.input_hand(self.handed);
if let InputType::Hand(hand) = &mut *self.input.specialization.lock() {