refactor(idl,spatial): make zone use idl
This commit is contained in:
@@ -264,3 +264,6 @@ pub fn find_field(client: &Client, path: &str) -> Result<Arc<Field>> {
|
||||
.get_aspect("Field", "info", |n| &n.field)
|
||||
.cloned()
|
||||
}
|
||||
pub fn get_field(node: &Node) -> Result<Arc<Field>> {
|
||||
node.get_aspect("Field", "info", |n| &n.field).cloned()
|
||||
}
|
||||
|
||||
@@ -15,11 +15,11 @@ use once_cell::sync::OnceCell;
|
||||
use parking_lot::Mutex;
|
||||
use portable_atomic::{AtomicBool, Ordering};
|
||||
use rustc_hash::FxHashMap;
|
||||
use serde::{de::DeserializeOwned, Serialize};
|
||||
use stardust_xr::messenger::MessageSenderHandle;
|
||||
use stardust_xr::scenegraph::ScenegraphError;
|
||||
use stardust_xr::schemas::flex::deserialize;
|
||||
use stardust_xr::schemas::flex::{deserialize, serialize};
|
||||
use std::fmt::Debug;
|
||||
use std::future::Future;
|
||||
use std::os::fd::OwnedFd;
|
||||
use std::sync::{Arc, Weak};
|
||||
use std::vec::Vec;
|
||||
@@ -290,29 +290,26 @@ impl Node {
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
pub fn execute_remote_method(
|
||||
pub async fn execute_remote_method_typed<S: Serialize, D: DeserializeOwned>(
|
||||
&self,
|
||||
method: &str,
|
||||
message: impl Into<Message>,
|
||||
) -> Result<impl Future<Output = Result<Message>>> {
|
||||
let message = message.into();
|
||||
input: S,
|
||||
fds: Vec<OwnedFd>,
|
||||
) -> Result<(D, Vec<OwnedFd>)> {
|
||||
let message_sender_handle = self
|
||||
.message_sender_handle
|
||||
.as_ref()
|
||||
.ok_or(eyre!("Messenger does not exist for this node"))?;
|
||||
|
||||
let future =
|
||||
message_sender_handle.method(self.path.as_str(), method, &message.data, message.fds)?;
|
||||
let serialized = serialize(input)?;
|
||||
let result = message_sender_handle
|
||||
.method(self.path.as_str(), method, &serialized, fds)?
|
||||
.await
|
||||
.map_err(|e| eyre!(e))?;
|
||||
|
||||
Ok(async {
|
||||
match future.await {
|
||||
Ok(m) => {
|
||||
let (data, fds) = m.into_components();
|
||||
Ok(Message { data, fds })
|
||||
}
|
||||
Err(e) => Err(eyre!(e)),
|
||||
}
|
||||
})
|
||||
let (message, fds) = result.into_components();
|
||||
let deserialized: D = deserialize(&message)?;
|
||||
Ok((deserialized, fds))
|
||||
}
|
||||
}
|
||||
impl Debug for Node {
|
||||
|
||||
@@ -13,11 +13,9 @@ use color_eyre::eyre::Result;
|
||||
use glam::Mat4;
|
||||
use rustc_hash::FxHashMap;
|
||||
use stardust_xr::schemas::flex::{deserialize, serialize};
|
||||
use tracing::instrument;
|
||||
|
||||
use std::future::Future;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::sync::Arc;
|
||||
use tracing::instrument;
|
||||
|
||||
static ROOT_REGISTRY: Registry<Root> = Registry::new();
|
||||
|
||||
@@ -96,11 +94,12 @@ impl Root {
|
||||
spatial.set_spatial_parent(None).unwrap();
|
||||
spatial.set_local_transform(transform);
|
||||
}
|
||||
pub fn save_state(&self) -> impl Future<Output = Result<ClientStateInternal>> {
|
||||
let future = self
|
||||
pub async fn save_state(&self) -> Result<ClientStateInternal> {
|
||||
Ok(self
|
||||
.node
|
||||
.execute_remote_method("save_state", Message::default());
|
||||
async move { Ok(deserialize(&future?.await?.data)?) }
|
||||
.execute_remote_method_typed("save_state", (), Vec::new())
|
||||
.await?
|
||||
.0)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
pub mod zone;
|
||||
|
||||
use self::zone::{create_zone_flex, Zone};
|
||||
use super::{Message, Node};
|
||||
use self::zone::Zone;
|
||||
use super::fields::get_field;
|
||||
use super::Node;
|
||||
use crate::core::client::Client;
|
||||
use crate::core::registry::Registry;
|
||||
use color_eyre::eyre::{ensure, eyre, Result};
|
||||
@@ -10,8 +11,6 @@ use mint::Vector3;
|
||||
use nanoid::nanoid;
|
||||
use once_cell::sync::OnceCell;
|
||||
use parking_lot::Mutex;
|
||||
use serde::Deserialize;
|
||||
use stardust_xr::schemas::flex::deserialize;
|
||||
use std::fmt::Debug;
|
||||
use std::os::fd::OwnedFd;
|
||||
use std::ptr;
|
||||
@@ -123,7 +122,7 @@ impl Spatial {
|
||||
}
|
||||
pub fn global_transform(&self) -> Mat4 {
|
||||
match self.get_parent() {
|
||||
Some(value) => value.global_transform() * *self.transform.lock(),
|
||||
Some(parent) => parent.global_transform() * *self.transform.lock(),
|
||||
None => *self.transform.lock(),
|
||||
}
|
||||
}
|
||||
@@ -275,7 +274,7 @@ impl SpatialAspect for Spatial {
|
||||
.spatial
|
||||
.get()
|
||||
.ok_or_else(|| eyre!("Node doesn't have a spatial?"))?;
|
||||
let relative_spatial = get_spatial(&relative_to, "Relative node", "Spatial")?;
|
||||
let relative_spatial = get_spatial(&relative_to, "Relative node")?;
|
||||
let center =
|
||||
Spatial::space_to_space_matrix(Some(&this_spatial), Some(&relative_spatial))
|
||||
.transform_point3([0.0; 3].into());
|
||||
@@ -311,7 +310,7 @@ impl SpatialAspect for Spatial {
|
||||
.spatial
|
||||
.get()
|
||||
.ok_or_else(|| eyre!("Node doesn't have a spatial?"))?;
|
||||
let relative_spatial = get_spatial(&relative_to, "Relative node", "Spatial")?;
|
||||
let relative_spatial = get_spatial(&relative_to, "Relative node")?;
|
||||
|
||||
let (scale, rotation, position) = Spatial::space_to_space_matrix(
|
||||
Some(this_spatial.as_ref()),
|
||||
@@ -352,7 +351,7 @@ impl SpatialAspect for Spatial {
|
||||
.spatial
|
||||
.get()
|
||||
.ok_or_else(|| eyre!("Node doesn't have a spatial?"))?;
|
||||
let relative_spatial = get_spatial(&relative_to, "Relative node", "Spatial")?;
|
||||
let relative_spatial = get_spatial(&relative_to, "Relative node")?;
|
||||
|
||||
this_spatial.set_local_transform_components(Some(&relative_spatial), transform);
|
||||
Ok(())
|
||||
@@ -368,7 +367,7 @@ impl SpatialAspect for Spatial {
|
||||
.spatial
|
||||
.get()
|
||||
.ok_or_else(|| eyre!("Node doesn't have a spatial?"))?;
|
||||
let parent = get_spatial(&parent, "Parent", "Spatial")?;
|
||||
let parent = get_spatial(&parent, "Parent")?;
|
||||
|
||||
this_spatial.set_spatial_parent(Some(parent))?;
|
||||
Ok(())
|
||||
@@ -384,7 +383,7 @@ impl SpatialAspect for Spatial {
|
||||
.spatial
|
||||
.get()
|
||||
.ok_or_else(|| eyre!("Node doesn't have a spatial?"))?;
|
||||
let parent = get_spatial(&parent, "Parent", "Spatial")?;
|
||||
let parent = get_spatial(&parent, "Parent")?;
|
||||
|
||||
this_spatial.set_spatial_parent_in_place(Some(parent))?;
|
||||
Ok(())
|
||||
@@ -461,35 +460,52 @@ pub fn find_spatial_parent(calling_client: &Arc<Client>, node_path: &str) -> Res
|
||||
pub fn find_reference_space(calling_client: &Arc<Client>, node_path: &str) -> Result<Arc<Spatial>> {
|
||||
find_spatial(calling_client, "Reference space", node_path)
|
||||
}
|
||||
pub fn get_spatial(node: &Arc<Node>, node_name: &str, aspect_name: &str) -> Result<Arc<Spatial>> {
|
||||
node.get_aspect(node_name, aspect_name, |n| &n.spatial)
|
||||
pub fn get_spatial(node: &Arc<Node>, node_name: &str) -> Result<Arc<Spatial>> {
|
||||
node.get_aspect(node_name, "spatial", |n| &n.spatial)
|
||||
.cloned()
|
||||
}
|
||||
|
||||
pub struct SpatialInterface;
|
||||
impl SpatialInterfaceAspect for SpatialInterface {
|
||||
fn create_spatial(
|
||||
_node: Arc<Node>,
|
||||
calling_client: Arc<Client>,
|
||||
_fds: Vec<OwnedFd>,
|
||||
name: String,
|
||||
parent: Arc<Node>,
|
||||
transform: Transform,
|
||||
zoneable: bool,
|
||||
) -> Result<()> {
|
||||
let parent = get_spatial(&parent, "Spatial parent")?;
|
||||
let transform = parse_transform(transform, true, true, true);
|
||||
let node =
|
||||
Node::create(&calling_client, "/spatial/spatial", &name, true).add_to_scenegraph()?;
|
||||
Spatial::add_to(&node, Some(parent), transform, zoneable)?;
|
||||
Ok(())
|
||||
}
|
||||
fn create_zone(
|
||||
_node: Arc<Node>,
|
||||
calling_client: Arc<Client>,
|
||||
_fds: Vec<OwnedFd>,
|
||||
name: String,
|
||||
parent: Arc<Node>,
|
||||
transform: Transform,
|
||||
field: Arc<Node>,
|
||||
) -> Result<()> {
|
||||
let parent = get_spatial(&parent, "Spatial parent")?;
|
||||
let transform = parse_transform(transform, true, true, false);
|
||||
let field = get_field(&field)?;
|
||||
|
||||
let node =
|
||||
Node::create(&calling_client, "/spatial/zone", &name, true).add_to_scenegraph()?;
|
||||
let space = Spatial::add_to(&node, Some(parent), transform, false)?;
|
||||
Zone::add_to(&node, space, &field);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create_interface(client: &Arc<Client>) -> Result<()> {
|
||||
let node = Node::create(client, "", "spatial", false);
|
||||
node.add_local_signal("create_spatial", create_spatial_flex);
|
||||
node.add_local_signal("create_zone", create_zone_flex);
|
||||
<SpatialInterface as SpatialInterfaceAspect>::add_node_members(&node);
|
||||
node.add_to_scenegraph().map(|_| ())
|
||||
}
|
||||
|
||||
pub fn create_spatial_flex(
|
||||
_node: Arc<Node>,
|
||||
calling_client: Arc<Client>,
|
||||
message: Message,
|
||||
) -> Result<()> {
|
||||
#[derive(Deserialize)]
|
||||
struct CreateSpatialInfo<'a> {
|
||||
name: &'a str,
|
||||
parent_path: &'a str,
|
||||
transform: Transform,
|
||||
zoneable: bool,
|
||||
}
|
||||
let info: CreateSpatialInfo = deserialize(message.as_ref())?;
|
||||
let node = Node::create(&calling_client, "/spatial/spatial", info.name, true);
|
||||
let parent = find_spatial_parent(&calling_client, info.parent_path)?;
|
||||
let transform = parse_transform(info.transform, true, true, true);
|
||||
let node = node.add_to_scenegraph()?;
|
||||
Spatial::add_to(&node, Some(parent), transform, info.zoneable)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -1,20 +1,19 @@
|
||||
use super::{find_spatial, Spatial, ZONEABLE_REGISTRY};
|
||||
use super::{get_spatial, Spatial, ZoneAspect, ZONEABLE_REGISTRY};
|
||||
use crate::{
|
||||
core::{client::Client, registry::Registry},
|
||||
nodes::{
|
||||
alias::{Alias, AliasInfo},
|
||||
fields::{find_field, Field},
|
||||
spatial::{find_spatial_parent, parse_transform, Transform},
|
||||
Message, Node,
|
||||
fields::Field,
|
||||
Node,
|
||||
},
|
||||
};
|
||||
use color_eyre::eyre::Result;
|
||||
use glam::vec3a;
|
||||
use parking_lot::Mutex;
|
||||
use rustc_hash::FxHashMap;
|
||||
use serde::Deserialize;
|
||||
use stardust_xr::schemas::flex::{deserialize, serialize};
|
||||
use std::sync::{Arc, Weak};
|
||||
use std::{
|
||||
os::fd::OwnedFd,
|
||||
sync::{Arc, Weak},
|
||||
};
|
||||
|
||||
pub fn capture(spatial: &Arc<Spatial>, zone: &Arc<Zone>) {
|
||||
let old_distance = spatial.zone_distance();
|
||||
@@ -31,10 +30,7 @@ pub fn capture(spatial: &Arc<Spatial>, zone: &Arc<Zone>) {
|
||||
let Some(node) = zone.spatial.node.upgrade() else {
|
||||
return;
|
||||
};
|
||||
let Ok(message) = serialize(&spatial.uid) else {
|
||||
return;
|
||||
};
|
||||
let _ = node.send_remote_signal("capture", message);
|
||||
let _ = super::zone_client::capture(&node, &spatial.uid);
|
||||
}
|
||||
}
|
||||
pub fn release(spatial: &Spatial) {
|
||||
@@ -45,10 +41,7 @@ pub fn release(spatial: &Spatial) {
|
||||
return;
|
||||
};
|
||||
spatial_zone.captured.remove(spatial);
|
||||
let Ok(message) = serialize(&spatial.uid) else {
|
||||
return;
|
||||
};
|
||||
let _ = node.send_remote_signal("release", message);
|
||||
let _ = super::zone_client::release(&node, &spatial.uid);
|
||||
}
|
||||
*spatial_zone = Weak::new();
|
||||
}
|
||||
@@ -67,26 +60,18 @@ impl Zone {
|
||||
zoneables: Mutex::new(FxHashMap::default()),
|
||||
captured: Registry::new(),
|
||||
});
|
||||
node.add_local_signal("capture", Zone::capture_flex);
|
||||
node.add_local_signal("release", Zone::release_flex);
|
||||
node.add_local_signal("update", Zone::update);
|
||||
<Zone as ZoneAspect>::add_node_members(node);
|
||||
let _ = node.zone.set(zone.clone());
|
||||
zone
|
||||
}
|
||||
fn capture_flex(node: Arc<Node>, calling_client: Arc<Client>, message: Message) -> Result<()> {
|
||||
let zone = node.zone.get().unwrap();
|
||||
let capture_path: &str = deserialize(message.as_ref())?;
|
||||
let spatial = find_spatial(&calling_client, "Spatial", capture_path)?;
|
||||
capture(&spatial, zone);
|
||||
Ok(())
|
||||
}
|
||||
fn release_flex(_node: Arc<Node>, calling_client: Arc<Client>, message: Message) -> Result<()> {
|
||||
let capture_path: &str = deserialize(message.as_ref())?;
|
||||
let spatial = find_spatial(&calling_client, "Spatial", capture_path)?;
|
||||
release(&spatial);
|
||||
Ok(())
|
||||
}
|
||||
fn update(node: Arc<Node>, _calling_client: Arc<Client>, _message: Message) -> Result<()> {
|
||||
}
|
||||
impl ZoneAspect for Zone {
|
||||
#[doc = ""]
|
||||
fn update(
|
||||
node: Arc<Node>,
|
||||
_calling_client: Arc<Client>,
|
||||
_fds: Vec<OwnedFd>,
|
||||
) -> color_eyre::eyre::Result<()> {
|
||||
let zone = node.zone.get().unwrap();
|
||||
let Some(field) = zone.field.upgrade() else {
|
||||
return Err(color_eyre::eyre::eyre!("Zone's field has been destroyed"));
|
||||
@@ -140,17 +125,45 @@ impl Zone {
|
||||
})
|
||||
.collect::<FxHashMap<String, Arc<Node>>>();
|
||||
|
||||
for entered_uid in zoneables.keys().filter(|k| !old_zoneables.contains_key(*k)) {
|
||||
node.send_remote_signal("enter", serialize(entered_uid)?)?;
|
||||
for (uid, zoneable) in zoneables
|
||||
.iter()
|
||||
.filter(|(k, _)| !old_zoneables.contains_key(*k))
|
||||
{
|
||||
super::zone_client::enter(&node, uid, zoneable)?;
|
||||
}
|
||||
for left_uid in old_zoneables.keys().filter(|k| !zoneables.contains_key(*k)) {
|
||||
node.send_remote_signal("leave", serialize(left_uid)?)?;
|
||||
super::zone_client::leave(&node, &left_uid)?;
|
||||
}
|
||||
|
||||
*old_zoneables = zoneables;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[doc = ""]
|
||||
fn capture(
|
||||
node: Arc<Node>,
|
||||
_calling_client: Arc<Client>,
|
||||
_fds: Vec<OwnedFd>,
|
||||
spatial: Arc<Node>,
|
||||
) -> color_eyre::eyre::Result<()> {
|
||||
let zone = node.zone.get().unwrap();
|
||||
let spatial = get_spatial(&spatial, "Spatial")?;
|
||||
capture(&spatial, zone);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[doc = ""]
|
||||
fn release(
|
||||
_node: Arc<Node>,
|
||||
_calling_client: Arc<Client>,
|
||||
_fds: Vec<OwnedFd>,
|
||||
spatial: Arc<Node>,
|
||||
) -> color_eyre::eyre::Result<()> {
|
||||
let spatial = get_spatial(&spatial, "Spatial")?;
|
||||
release(&spatial);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
impl Drop for Zone {
|
||||
fn drop(&mut self) {
|
||||
@@ -159,27 +172,3 @@ impl Drop for Zone {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create_zone_flex(
|
||||
_node: Arc<Node>,
|
||||
calling_client: Arc<Client>,
|
||||
message: Message,
|
||||
) -> Result<()> {
|
||||
#[derive(Deserialize)]
|
||||
struct CreateZoneInfo<'a> {
|
||||
name: &'a str,
|
||||
parent_path: &'a str,
|
||||
transform: Transform,
|
||||
field_path: &'a str,
|
||||
}
|
||||
let info: CreateZoneInfo = deserialize(message.as_ref())?;
|
||||
let parent = find_spatial_parent(&calling_client, info.parent_path)?;
|
||||
let transform = parse_transform(info.transform, true, true, false);
|
||||
let field = find_field(&calling_client, info.field_path)?;
|
||||
|
||||
let node =
|
||||
Node::create(&calling_client, "/spatial/zone", info.name, true).add_to_scenegraph()?;
|
||||
let space = Spatial::add_to(&node, Some(parent), transform, false)?;
|
||||
Zone::add_to(&node, space, &field);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user