stardust_xr_fusion/
query_impl.rs

1use crate::{
2	ClientHandle,
3	fields::FieldRef,
4	objects::{FieldRefProxyExt, SpatialRefProxyExt as _},
5	spatial::SpatialRef,
6};
7use parking_lot::Mutex;
8use stardust_xr::schemas::dbus::{
9	interfaces::{FieldRefProxy, SpatialRefProxy},
10	query::{QueryContext, Queryable},
11};
12use std::{
13	collections::HashMap,
14	sync::{Arc, LazyLock},
15};
16use zbus::names::InterfaceName;
17
18impl QueryContext for ClientHandle {}
19
20pub trait ClientQueryContext: QueryContext {
21	fn get_client_handle(self: &Arc<Self>) -> &Arc<ClientHandle>;
22}
23impl ClientQueryContext for ClientHandle {
24	fn get_client_handle(self: &Arc<Self>) -> &Arc<ClientHandle> {
25		self
26	}
27}
28
29impl<Ctx: ClientQueryContext> Queryable<Ctx> for SpatialRef {
30	async fn try_new(
31		connection: &zbus::Connection,
32		ctx: &Arc<Ctx>,
33		object: &stardust_xr::schemas::dbus::ObjectInfo,
34		contains_interface: &(impl Fn(&InterfaceName) -> bool + Send + Sync),
35	) -> Option<Self> {
36		static CACHE: LazyLock<Mutex<HashMap<u64, SpatialRef>>> = LazyLock::new(Mutex::default);
37		let proxy = SpatialRefProxy::try_new(connection, ctx, object, contains_interface).await?;
38		let id = proxy.uid().await.ok()?;
39		let v = CACHE.lock().get(&id).cloned();
40		Some(match v {
41			Some(v) => v,
42			None => {
43				let spatial_ref = proxy.import(ctx.get_client_handle()).await?;
44				CACHE.lock().insert(id, spatial_ref.clone());
45				spatial_ref
46			}
47		})
48	}
49}
50
51impl<Ctx: ClientQueryContext> Queryable<Ctx> for FieldRef {
52	async fn try_new(
53		connection: &zbus::Connection,
54		ctx: &Arc<Ctx>,
55		object: &stardust_xr::schemas::dbus::ObjectInfo,
56		contains_interface: &(impl Fn(&InterfaceName) -> bool + Send + Sync),
57	) -> Option<Self> {
58		static CACHE: LazyLock<Mutex<HashMap<u64, FieldRef>>> = LazyLock::new(Mutex::default);
59		let proxy = FieldRefProxy::try_new(connection, ctx, object, contains_interface).await?;
60		let id = proxy.uid().await.ok()?;
61		let v = CACHE.lock().get(&id).cloned();
62		Some(match v {
63			Some(v) => v,
64			None => {
65				let spatial_ref = proxy.import(ctx.get_client_handle()).await?;
66				CACHE.lock().insert(id, spatial_ref.clone());
67				spatial_ref
68			}
69		})
70	}
71}