diff --git a/Cargo.lock b/Cargo.lock index 327ba36..6345518 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1519,7 +1519,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" dependencies = [ "cfg-if", - "windows-targets 0.48.5", + "windows-targets 0.52.6", ] [[package]] @@ -1880,7 +1880,7 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" dependencies = [ - "proc-macro-crate 1.3.1", + "proc-macro-crate 3.2.0", "proc-macro2", "quote", "syn 2.0.87", @@ -2653,7 +2653,7 @@ checksum = "2f2b15926089e5526bb2dd738a2eb0e59034356e06eb71e1cd912358c0e62c4d" [[package]] name = "stardust-xr" version = "0.45.0" -source = "git+https://github.com/StardustXR/core.git?branch=dev#b68343a67f93e95ac5bec138c8ee0e082189a489" +source = "git+https://github.com/StardustXR/core.git?branch=dev#41f9e416cc54e7a8b4b815a43384e57478ac502c" dependencies = [ "cluFlock", "color-eyre", @@ -2674,7 +2674,7 @@ dependencies = [ [[package]] name = "stardust-xr-schemas" version = "1.5.3" -source = "git+https://github.com/StardustXR/core.git?branch=dev#b68343a67f93e95ac5bec138c8ee0e082189a489" +source = "git+https://github.com/StardustXR/core.git?branch=dev#41f9e416cc54e7a8b4b815a43384e57478ac502c" dependencies = [ "flatbuffers", "flexbuffers", @@ -3395,7 +3395,7 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] diff --git a/src/main.rs b/src/main.rs index 8d8d6b6..747dceb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -17,6 +17,7 @@ use directories::ProjectDirs; use objects::ServerObjects; use once_cell::sync::OnceCell; use session::{launch_start, save_session}; +use stardust_xr::schemas::dbus::object_registry::ObjectRegistry; use stardust_xr::server; use std::path::PathBuf; use std::sync::Arc; @@ -139,13 +140,25 @@ async fn main() { .await .expect("Couldn't add the object manager"); + let object_registry = ObjectRegistry::new(&dbus_connection).await.expect( + "Couldn't make the object registry to find all objects with given interfaces in d-bus", + ); + let sk_ready_notifier = Arc::new(Notify::new()); let stereokit_loop = tokio::task::spawn_blocking({ let sk_ready_notifier = sk_ready_notifier.clone(); let project_dirs = project_dirs.clone(); let cli_args = cli_args.clone(); let dbus_connection = dbus_connection.clone(); - move || stereokit_loop(sk_ready_notifier, project_dirs, cli_args, dbus_connection) + move || { + stereokit_loop( + sk_ready_notifier, + project_dirs, + cli_args, + dbus_connection, + object_registry, + ) + } }); sk_ready_notifier.notified().await; let mut startup_children = project_dirs @@ -173,6 +186,7 @@ fn stereokit_loop( project_dirs: Option, args: CliArgs, dbus_connection: Connection, + object_registry: ObjectRegistry, ) { let sk = SkSettings::default() .app_name("Stardust XR") @@ -258,7 +272,7 @@ fn stereokit_loop( wayland.frame_event(); destroy_queue::clear(); - objects.update(&sk, token); + objects.update(&sk, token, &dbus_connection, &object_registry); input::process_input(); nodes::root::Root::send_frame_events(Time::get_step_unscaled()); adaptive_sleep( diff --git a/src/objects/input/mouse_pointer.rs b/src/objects/input/mouse_pointer.rs index 69a524e..524ba72 100644 --- a/src/objects/input/mouse_pointer.rs +++ b/src/objects/input/mouse_pointer.rs @@ -1,10 +1,11 @@ +use super::{get_sorted_handlers, CaptureManager, DistanceCalculator}; use crate::{ core::client::INTERNAL_CLIENT, nodes::{ data::{ mask_matches, pulse_receiver_client, PulseSender, KEYMAPS, PULSE_RECEIVER_REGISTRY, }, - fields::{FieldTrait, Ray}, + fields::{Field, FieldTrait, Ray, EXPORTED_FIELDS}, input::{InputDataType, InputHandler, InputMethod, Pointer, INPUT_HANDLER_REGISTRY}, spatial::Spatial, Node, OwnedNode, @@ -15,12 +16,16 @@ use glam::{vec3, Mat4, Vec3}; use mint::Vector2; use serde::{Deserialize, Serialize}; use slotmap::{DefaultKey, Key as SlotKey}; -use stardust_xr::values::Datamap; +use stardust_xr::{ + schemas::dbus::{interfaces::FieldRefProxy, object_registry::ObjectRegistry}, + values::Datamap, +}; use std::sync::Arc; use stereokit_rust::system::{Input, Key}; +use tokio::task::JoinSet; +use tokio::time::{timeout, Duration}; use xkbcommon_rs::{xkb_keymap::CompileFlags, Context, Keymap, KeymapFormat}; - -use super::{get_sorted_handlers, CaptureManager, DistanceCalculator}; +use zbus::{names::OwnedInterfaceName, Connection}; #[derive(Debug, Deserialize, Serialize)] struct MouseEvent { @@ -46,12 +51,14 @@ impl Default for MouseEvent { } } -#[derive(Debug, Clone, Deserialize, Serialize, Default)] -pub struct KeyboardEvent { - pub keyboard: (), - pub xkbv1: (), - pub keymap_id: u64, - pub keys: Vec, +#[zbus::proxy( + interface = "org.stardustxr.XKBv1", + default_service = "org.stardustxr.XKBv1" +)] +trait KeyboardHandler { + async fn keymap(&self, keymap_id: u64) -> zbus::Result<()>; + async fn key_state(&self, key: u32, pressed: bool) -> zbus::Result<()>; + async fn reset(&self) -> zbus::Result<()>; } #[allow(unused)] @@ -62,8 +69,6 @@ pub struct MousePointer { pointer: Arc, capture_manager: CaptureManager, mouse_datamap: MouseEvent, - keyboard_datamap: KeyboardEvent, - keyboard_sender: Arc, } impl MousePointer { pub fn new() -> Result { @@ -83,29 +88,16 @@ impl MousePointer { .unwrap(), ); - let keyboard_sender = PulseSender::add_to( - &node.0, - Datamap::from_typed(KeyboardEvent::default()).unwrap(), - ) - .unwrap(); - Ok(MousePointer { node, spatial, pointer, capture_manager: CaptureManager::default(), mouse_datamap: Default::default(), - keyboard_datamap: KeyboardEvent { - keyboard: (), - xkbv1: (), - keymap_id: keymap.data().as_ffi(), - keys: vec![], - }, keymap, - keyboard_sender, }) } - pub fn update(&mut self) { + pub fn update(&mut self, dbus_connection: &Connection, object_registry: &ObjectRegistry) { let mouse = Input::get_mouse(); let ray = mouse.get_ray(); @@ -131,7 +123,7 @@ impl MousePointer { *self.pointer.datamap.lock() = Datamap::from_typed(&self.mouse_datamap).unwrap(); } self.target_pointer_input(); - self.send_keyboard_input(); + self.send_keyboard_input(dbus_connection, object_registry); } fn target_pointer_input(&mut self) { let distance_calculator: DistanceCalculator = |space, data, field| { @@ -158,56 +150,98 @@ impl MousePointer { self.pointer.set_handler_order(sorted_handlers.iter()); } - fn send_keyboard_input(&mut self) { - let rx = PULSE_RECEIVER_REGISTRY - .get_valid_contents() - .into_iter() - .filter(|rx| mask_matches(&rx.mask, &self.keyboard_sender.mask)) - .map(|rx| { - let result = rx.field.ray_march(Ray { - origin: vec3(0.0, 0.0, 0.0), - direction: vec3(0.0, 0.0, -1.0), - space: self.spatial.clone(), - }); - (rx, result) - }) - .filter(|(_rx, result)| { - result.deepest_point_distance > 0.0 && result.min_distance < 0.05 - }) - .reduce(|(rx_a, result_a), (rx_b, result_b)| { - if result_a.deepest_point_distance < result_b.deepest_point_distance { - (rx_a, result_a) - } else { - (rx_b, result_b) + pub fn send_keyboard_input( + &mut self, + dbus_connection: &Connection, + object_registry: &ObjectRegistry, + ) { + let keyboard_handlers = object_registry.get_objects("org.stardustxr.XKBv1"); + + // Spawn async task to handle keyboard input + tokio::spawn({ + let keyboard_handlers = keyboard_handlers.clone(); + let spatial = self.spatial.clone(); + let keymap_id = self.keymap.data().as_ffi(); + let dbus_connection = dbus_connection.clone(); + + async move { + let mut closest_handler = None; + let mut closest_distance = f32::MAX; + + let mut join_set = JoinSet::new(); + for handler in &keyboard_handlers { + let handler = handler.clone(); + let dbus_connection = dbus_connection.clone(); + join_set.spawn(async move { + timeout(Duration::from_millis(1), async { + let field_ref = handler + .to_typed_proxy::(&dbus_connection) + .await + .ok()?; + let uid = field_ref.uid().await.ok()?; + Some((handler, uid)) + }) + .await + .ok() + .flatten() + }); } - }) - .map(|(rx, _)| rx); + while let Some(Ok(Some((handler, field_ref_id)))) = join_set.join_next().await { + let exported_fields = EXPORTED_FIELDS.lock(); + dbg!(&*exported_fields); + let Some(field_ref_node) = exported_fields.get(&field_ref_id) else { + println!("didn't find a thing :("); + continue; + }; + // println!("still sendin stuff :)"); + let Ok(field_ref) = field_ref_node.get_aspect::() else { + continue; + }; + drop(exported_fields); - if let Some(rx) = rx { - let keys = (8_u32..254) - .map(|i| unsafe { std::mem::transmute(i) }) - .filter_map(|k| Some((map_key(k)?, Input::key(k)))) - .filter_map(|(i, k)| { - if k.is_just_active() { - Some(i as i32) - } else if k.is_just_inactive() { - Some(-(i as i32)) - } else { - None + let result = field_ref.ray_march(Ray { + origin: vec3(0.0, 0.0, 0.0), + direction: vec3(0.0, 0.0, -1.0), + space: spatial.clone(), + }); + + if result.deepest_point_distance > 0.0 + && result.min_distance < 0.05 + && result.deepest_point_distance < closest_distance + { + closest_distance = result.deepest_point_distance; + closest_handler = Some(handler); } - }) - .collect(); + } - self.keyboard_datamap.keys = keys; - if !self.keyboard_datamap.keys.is_empty() { - pulse_receiver_client::data( - &rx.node.upgrade().unwrap(), - &self.node.0, - &Datamap::from_typed(&self.keyboard_datamap).unwrap(), - ) - .unwrap(); + let Some(handler) = closest_handler else { + return; + }; + let Ok(keyboard_handler) = handler + .to_typed_proxy::(&dbus_connection) + .await + else { + return; + }; + + // Register keymap first + let _ = keyboard_handler.keymap(keymap_id).await; + + // Send key states + for i in 8_u32..254 { + let key = unsafe { std::mem::transmute::(i) }; + let Some(mapped_key) = map_key(key) else { + continue; + }; + let input_state = Input::key(key); + if input_state.is_just_active() { + let _ = keyboard_handler.key_state(mapped_key, true).await; + } else if input_state.is_just_inactive() { + let _ = keyboard_handler.key_state(mapped_key, false).await; + } + } } - } + }); } } diff --git a/src/objects/mod.rs b/src/objects/mod.rs index 7ba9011..21bc9e4 100644 --- a/src/objects/mod.rs +++ b/src/objects/mod.rs @@ -14,6 +14,7 @@ use input::{ sk_hand::SkHand, }; use play_space::PlaySpaceBounds; +use stardust_xr::schemas::dbus::object_registry::ObjectRegistry; use std::{marker::PhantomData, sync::Arc}; use stereokit_rust::{ material::Material, @@ -116,7 +117,13 @@ impl ServerObjects { } } - pub fn update(&mut self, sk: &Sk, token: &MainThreadToken) { + pub fn update( + &mut self, + sk: &Sk, + token: &MainThreadToken, + dbus_connection: &Connection, + object_registry: &ObjectRegistry, + ) { let hmd_pose = Input::get_head(); self.hmd .0 @@ -177,7 +184,9 @@ impl ServerObjects { eye_pointer.update(); } } - Inputs::MousePointer(mouse_pointer) => mouse_pointer.update(), + Inputs::MousePointer(mouse_pointer) => { + mouse_pointer.update(dbus_connection, object_registry) + } // Inputs::Controllers((left, right)) => { // left.update(token); // right.update(token);