stardust_xr_fusion/
query_impl.rs1use 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}