stardust_xr_fusion/
node.rs1use crate::client::ClientHandle;
4use serde::{Serialize, de::DeserializeOwned};
5use stardust_xr::{
6 messenger::MessengerError,
7 scenegraph::ScenegraphError,
8 schemas::flex::{
9 FlexSerializeError, deserialize, flexbuffers::DeserializationError, serialize,
10 },
11};
12use std::{fmt::Debug, os::fd::OwnedFd, sync::Arc, vec::Vec};
13use thiserror::Error;
14
15pub use crate::protocol::node::*;
16
17pub type NodeResult<O> = Result<O, NodeError>;
18
19#[derive(Error, Debug)]
20pub enum NodeError {
21 #[error("client has been dropped")]
22 ClientDropped,
23 #[error("Messenger error: {e}")]
24 MessengerError { e: MessengerError },
25 #[error("Node does not exist anymore")]
26 DoesNotExist,
27 #[error("Node's signal/method isn't available because it is an alias node")]
28 NotAliased,
29 #[error("invalid path")]
30 InvalidPath,
31 #[error("Serialization failed with an error: {e}")]
32 Serialization { e: FlexSerializeError },
33 #[error("Deserialization failed with an error: {e}")]
34 Deserialization { e: DeserializationError },
35 #[error("Server returned an error: {e}")]
37 ReturnedError { e: String },
38 #[error("Attempted to register to a singleton twice")]
39 OverrideSingleton,
40 #[error("Map is not a valid flexbuffer map at the root")]
42 MapInvalid,
43}
44impl From<MessengerError> for NodeError {
45 fn from(e: MessengerError) -> Self {
46 NodeError::MessengerError { e }
47 }
48}
49impl From<FlexSerializeError> for NodeError {
50 fn from(e: FlexSerializeError) -> Self {
51 NodeError::Serialization { e }
52 }
53}
54impl From<DeserializationError> for NodeError {
55 fn from(e: DeserializationError) -> Self {
56 NodeError::Deserialization { e }
57 }
58}
59impl From<String> for NodeError {
60 fn from(e: String) -> Self {
61 NodeError::ReturnedError { e }
62 }
63}
64impl From<NodeError> for ScenegraphError {
65 fn from(e: NodeError) -> Self {
66 ScenegraphError::MemberError {
67 error: e.to_string(),
68 }
69 }
70}
71
72pub trait NodeType: Sized + Send + Sync + 'static {
75 fn node(&self) -> &NodeCore;
77 fn id(&self) -> u64 {
79 self.node().id
80 }
81 fn client(&self) -> &Arc<ClientHandle> {
83 &self.node().client
84 }
85 fn set_enabled(&self, enabled: bool) -> Result<(), NodeError> {
87 if self.node().owned {
88 OwnedAspect::set_enabled(self.node(), enabled)
89 } else {
90 Err(NodeError::DoesNotExist)
91 }
92 }
93}
94
95pub struct NodeCore {
96 pub client: Arc<ClientHandle>,
97 pub id: u64,
98 pub(crate) owned: bool,
99}
100impl NodeCore {
101 pub(crate) fn new(client: Arc<ClientHandle>, id: u64, owned: bool) -> Self {
102 Self { client, id, owned }
103 }
104
105 pub(crate) fn send_signal<S: Serialize>(
107 &self,
108 aspect: u64,
109 signal: u64,
110 data: &S,
111 fds: Vec<OwnedFd>,
112 ) -> Result<(), NodeError> {
113 let serialized = serialize(data).map_err(|e| NodeError::Serialization { e })?;
114 self.client
115 .message_sender_handle
116 .signal(self.id, aspect, signal, &serialized, fds)
117 .map_err(|e| match e {
118 MessengerError::ReceiverDropped => NodeError::ClientDropped,
119 other => NodeError::MessengerError { e: other },
120 })
121 }
122
123 pub(crate) async fn call_method<S: Serialize, D: DeserializeOwned>(
125 &self,
126 aspect: u64,
127 method: u64,
128 data: &S,
129 fds: Vec<OwnedFd>,
130 ) -> Result<D, NodeError> {
131 let serialized = serialize(data).map_err(|e| NodeError::Serialization { e })?;
132
133 let response = self
134 .client
135 .message_sender_handle
136 .method(self.id, aspect, method, &serialized, fds)
137 .await
138 .map_err(|e| match e {
139 MessengerError::ReceiverDropped => NodeError::ClientDropped,
140 other => NodeError::MessengerError { e: other },
141 })?
142 .map_err(|e| NodeError::ReturnedError { e })?;
143
144 deserialize(&response.into_message()).map_err(|e| NodeError::Deserialization { e })
145 }
146}
147impl NodeType for NodeCore {
148 fn node(&self) -> &NodeCore {
149 self
150 }
151}
152impl OwnedAspect for NodeCore {}
153impl std::fmt::Debug for NodeCore {
154 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
155 f.debug_struct("NodeCore")
156 .field("id", &self.id)
157 .field("owned", &self.owned)
158 .finish()
159 }
160}
161impl Drop for NodeCore {
162 fn drop(&mut self) {
163 if self.owned {
164 let _ = self.destroy();
165 }
166 }
167}
168
169