stardust_xr_fusion/
objects.rs

1#![allow(async_fn_in_trait)]
2
3use crate::{
4	client::ClientHandle,
5	fields::{Field, FieldAspect, FieldRef},
6	node::NodeResult,
7	spatial::{Spatial, SpatialAspect, SpatialRef},
8};
9use interfaces::FieldRefProxy;
10pub use stardust_xr::schemas::dbus::*;
11use stardust_xr::{
12	schemas::{
13		dbus::interfaces::{PlaySpaceProxy, SpatialRefProxy},
14		zbus::Connection,
15	},
16	values::Vector2,
17};
18use std::sync::Arc;
19
20pub trait SpatialRefProxyExt {
21	async fn import(&self, stardust_client: &Arc<ClientHandle>) -> Option<SpatialRef>;
22}
23impl SpatialRefProxyExt for SpatialRefProxy<'_> {
24	async fn import(&self, stardust_client: &Arc<ClientHandle>) -> Option<SpatialRef> {
25		let uid = self.uid().await.ok()?;
26		SpatialRef::import(stardust_client, uid).await.ok()
27	}
28}
29pub struct SpatialObject(u64, Spatial);
30impl SpatialObject {
31	pub async fn new(spatial: Spatial) -> NodeResult<Self> {
32		Ok(Self(spatial.export_spatial().await?, spatial))
33	}
34}
35#[zbus::interface(name = "org.stardustxr.SpatialRef")]
36impl SpatialObject {
37	#[zbus(property)]
38	async fn uid(&self) -> u64 {
39		self.0
40	}
41}
42
43pub trait FieldRefProxyExt {
44	async fn import(&self, stardust_client: &Arc<ClientHandle>) -> Option<FieldRef>;
45}
46impl FieldRefProxyExt for FieldRefProxy<'_> {
47	async fn import(&self, stardust_client: &Arc<ClientHandle>) -> Option<FieldRef> {
48		let uid = self.uid().await.ok()?;
49		FieldRef::import(stardust_client, uid).await.ok()
50	}
51}
52pub struct FieldObject(u64, Field);
53impl FieldObject {
54	pub async fn new(field: Field) -> NodeResult<Self> {
55		Ok(Self(field.export_field().await?, field))
56	}
57}
58#[zbus::interface(name = "org.stardustxr.FieldRef")]
59impl FieldObject {
60	#[zbus(property)]
61	async fn uid(&self) -> u64 {
62		self.0
63	}
64}
65
66pub async fn hmd(client: &Arc<ClientHandle>) -> Option<SpatialRef> {
67	let connection = Connection::session().await.ok()?;
68	let spatial_ref =
69		SpatialRefProxy::new(&connection, "org.stardustxr.HMD", "/org/stardustxr/HMD")
70			.await
71			.ok()?;
72	spatial_ref.import(client).await
73}
74
75#[tokio::test]
76async fn fusion_objects_hmd() {
77	use crate::spatial::SpatialRefAspect;
78
79	let client = crate::Client::connect().await.unwrap();
80	let client_handle = client.handle();
81	client.async_event_loop();
82
83	let hmd = hmd(&client_handle).await.unwrap();
84	assert!(hmd.get_transform(client_handle.get_root()).await.is_ok())
85}
86
87pub struct PlaySpace {
88	pub spatial: SpatialRef,
89	pub bounds_polygon: Vec<Vector2<f32>>,
90}
91pub async fn play_space(client: &Arc<ClientHandle>) -> Option<PlaySpace> {
92	let connection = Connection::session().await.ok()?;
93	let spatial_proxy = SpatialRefProxy::new(
94		&connection,
95		"org.stardustxr.PlaySpace",
96		"/org/stardustxr/PlaySpace",
97	)
98	.await
99	.ok()?;
100	let spatial = spatial_proxy.import(client).await?;
101	let play_space_proxy = PlaySpaceProxy::new(&connection).await.ok()?;
102	let bounds_polygon = play_space_proxy.bounds().await.ok()?;
103	Some(PlaySpace {
104		spatial,
105		bounds_polygon: bounds_polygon
106			.into_iter()
107			.map(|(x, y)| [x as f32, y as f32].into())
108			.collect(),
109	})
110}