diff --git a/Cargo.lock b/Cargo.lock index 0d92375..91ffaf2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2063,7 +2063,7 @@ checksum = "2f2b15926089e5526bb2dd738a2eb0e59034356e06eb71e1cd912358c0e62c4d" [[package]] name = "stardust-xr" version = "0.14.1" -source = "git+https://github.com/StardustXR/core.git?branch=feat/idl#c7e27806c671d0ad262801583ec30acbf710a143" +source = "git+https://github.com/StardustXR/core.git?branch=feat/idl#530b1fe5aa33f782fbf28026410ba00dd23da16d" dependencies = [ "cluFlock", "color-rs", @@ -2083,7 +2083,7 @@ dependencies = [ [[package]] name = "stardust-xr-schemas" version = "1.5.3" -source = "git+https://github.com/StardustXR/core.git?branch=feat/idl#c7e27806c671d0ad262801583ec30acbf710a143" +source = "git+https://github.com/StardustXR/core.git?branch=feat/idl#530b1fe5aa33f782fbf28026410ba00dd23da16d" dependencies = [ "flatbuffers", "flexbuffers", diff --git a/codegen/src/lib.rs b/codegen/src/lib.rs index 8e80aa4..d89dc2d 100644 --- a/codegen/src/lib.rs +++ b/codegen/src/lib.rs @@ -29,10 +29,6 @@ pub fn codegen_data_protocol(_input: proc_macro::TokenStream) -> proc_macro::Tok codegen_protocol(DATA_PROTOCOL) } #[proc_macro] -pub fn codegen_zone_protocol(_input: proc_macro::TokenStream) -> proc_macro::TokenStream { - codegen_protocol(ZONE_PROTOCOL) -} -#[proc_macro] pub fn codegen_audio_protocol(_input: proc_macro::TokenStream) -> proc_macro::TokenStream { codegen_protocol(AUDIO_PROTOCOL) } @@ -40,18 +36,6 @@ pub fn codegen_audio_protocol(_input: proc_macro::TokenStream) -> proc_macro::To pub fn codegen_drawable_protocol(_input: proc_macro::TokenStream) -> proc_macro::TokenStream { codegen_protocol(DRAWABLE_PROTOCOL) } -#[proc_macro] -pub fn codegen_drawable_lines_protocol(_input: proc_macro::TokenStream) -> proc_macro::TokenStream { - codegen_protocol(DRAWABLE_LINES_PROTOCOL) -} -#[proc_macro] -pub fn codegen_drawable_model_protocol(_input: proc_macro::TokenStream) -> proc_macro::TokenStream { - codegen_protocol(DRAWABLE_MODEL_PROTOCOL) -} -#[proc_macro] -pub fn codegen_drawable_text_protocol(_input: proc_macro::TokenStream) -> proc_macro::TokenStream { - codegen_protocol(DRAWABLE_TEXT_PROTOCOL) -} // #[proc_macro] // pub fn codegen_input_protocol(_input: proc_macro::TokenStream) -> proc_macro::TokenStream { // codegen_protocol(INPUT_PROTOCOL) @@ -59,6 +43,22 @@ pub fn codegen_drawable_text_protocol(_input: proc_macro::TokenStream) -> proc_m fn codegen_protocol(protocol: &'static str) -> proc_macro::TokenStream { let protocol = Protocol::parse(protocol).unwrap(); + let interface = protocol + .interface + .map(|p| { + let virtual_aspect_name = p.path[1..] + .split('/') + .map(ToString::to_string) + .reduce(|a, b| format!("{a}_{b}")) + .unwrap_or_default() + + "_interface"; + generate_aspect(&Aspect { + name: virtual_aspect_name, + description: protocol.description.clone(), + members: p.members, + }) + }) + .unwrap_or_default(); let custom_enums = protocol .custom_enums .iter() @@ -89,14 +89,7 @@ fn codegen_protocol(protocol: &'static str) -> proc_macro::TokenStream { // .map(generate_node) // .reduce(fold_tokens) // .unwrap_or_default(); - // let interfaces = protocol - // .interfaces - // .iter() - // .map(generate_interface) - // .reduce(fold_tokens) - // .unwrap_or_default(); - // quote!(#custom_enums #custom_unions #custom_structs #aspects #nodes #interfaces).into() - quote!(#custom_enums #custom_unions #custom_structs #aspects).into() + quote!(#custom_enums #custom_unions #custom_structs #aspects #interface).into() } fn generate_custom_enum(custom_enum: &CustomEnum) -> TokenStream { @@ -167,15 +160,6 @@ fn generate_custom_struct(custom_struct: &CustomStruct) -> TokenStream { } } -fn generate_interface(interface: &Interface) -> TokenStream { - interface - .members - .iter() - .map(generate_member) - .reduce(fold_tokens) - .unwrap_or_default() -} - fn generate_node(node: &Node) -> TokenStream { let node_name = Ident::new(&node.name, Span::call_site()); let description = &node.description; @@ -219,8 +203,8 @@ fn generate_aspect(aspect: &Aspect) -> TokenStream { let description = &aspect.description; let (client_members, server_members) = aspect.members.iter().split(|m| m.side == Side::Server); - let aspect_handler_name = Ident::new( - &format!("{}Handler", &aspect.name.to_case(Case::Pascal)), + let client_mod_name = Ident::new( + &format!("{}_client", &aspect.name.to_case(Case::Snake)), Span::call_site(), ); let client_side_members = client_members @@ -228,8 +212,7 @@ fn generate_aspect(aspect: &Aspect) -> TokenStream { .reduce(fold_tokens) .map(|t| { quote! { - #[doc = #description] - pub trait #aspect_handler_name: Send + Sync + 'static { + pub mod #client_mod_name { #t } } @@ -252,7 +235,7 @@ fn generate_aspect(aspect: &Aspect) -> TokenStream { .reduce(fold_tokens) .map(|members| { quote! { - fn add_node_members(node: &Node) { + fn add_node_members(node: &crate::nodes::Node) { #members } } @@ -268,6 +251,10 @@ fn generate_aspect(aspect: &Aspect) -> TokenStream { quote!(#client_side_members #server_side_members) } +fn generate_interface_member(interface_path: &str, member: &Member) -> TokenStream { + Default::default() +} + fn generate_member(member: &Member) -> TokenStream { let name_str = &member.name; let name = Ident::new(&member.name.to_case(Case::Snake), Span::call_site()); @@ -276,10 +263,11 @@ fn generate_member(member: &Member) -> TokenStream { let side = member.side; let _type = member._type; - let first_args = if member.side == Side::Server { - quote!(_node: std::sync::Arc, _calling_client: std::sync::Arc, _fds: Vec) - } else { - quote!(&mut self) + let first_args = match member.side { + Side::Server => { + quote!(_node: std::sync::Arc, _calling_client: std::sync::Arc, _fds: Vec) + } + Side::Client => quote!(_node: &crate::nodes::Node), }; let argument_decls = member .arguments @@ -301,38 +289,19 @@ fn generate_member(member: &Member) -> TokenStream { match (side, _type) { (Side::Client, MemberType::Method) => { - let body = if let Some(interface_path) = &member.interface_path { - quote! { - let data = stardust_xr::schemas::flex::serialize(&(#argument_uses))?; - let result = client.message_sender_handle.method(#interface_path, #name_str, &data, Vec::new())?.await?; - Ok(stardust_xr::schemas::flex::deserialize(&result.into_message())?) - } - } else { - quote! { - self.node().execute_remote_method(#name_str, &(#argument_uses)).await - } - }; quote! { #[doc = #description] - async fn #name(#argument_decls) -> crate::node::NodeResult<#return_type> { - #body + pub async fn #name(#argument_decls) -> color_eyre::eyre::Result<#return_type> { + _node.execute_remote_method(#name_str, &(#argument_uses)).await } } } (Side::Client, MemberType::Signal) => { - let body = if let Some(interface_path) = &member.interface_path { - quote! { - client.message_sender_handle.signal(#interface_path, #name_str, &stardust_xr::schemas::flex::serialize(&(#argument_uses))?, Vec::new()) - } - } else { - quote! { - self.node().send_remote_signal(#name_str, &(#argument_uses)) - } - }; quote! { #[doc = #description] - fn #name(#argument_decls) -> crate::node::NodeResult<#return_type> { - #body + pub fn #name(#argument_decls) -> color_eyre::eyre::Result<()> { + let serialized = stardust_xr::schemas::flex::serialize((#argument_uses))?; + _node.send_remote_signal(#name_str, serialized) } } } @@ -345,7 +314,7 @@ fn generate_member(member: &Member) -> TokenStream { (Side::Server, MemberType::Signal) => { quote! { #[doc = #description] - fn #name(#argument_decls) -> color_eyre::eyre::Result<#return_type>; + fn #name(#argument_decls) -> color_eyre::eyre::Result<()>; } } } @@ -424,11 +393,11 @@ fn generate_argument_deserialize( ArgumentType::Color => quote!(color::rgba_linear!(#name[0], #name[1], #name[2], #name[3])), ArgumentType::Vec(v) => { let mapping = generate_argument_deserialize("a", v, false); - quote!(#name.iter().map(|a| Ok(#mapping)).collect::, crate::node::NodeError>>()?) + quote!(#name.iter().map(|a| Ok(#mapping)).collect::>>()?) } ArgumentType::Map(v) => { let mapping = generate_argument_deserialize("a", v, false); - quote!(#name.iter().map(|(k, a)| Ok((k, #mapping))).collect::, crate::node::NodeError>>()?) + quote!(#name.iter().map(|(k, a)| Ok((k, #mapping))).collect::>>()?) } _ => quote!(#name), } @@ -444,24 +413,24 @@ fn generate_argument_serialize( _type, return_info: _, } => match optional { - true => quote!(#name.map(|n| n.node().get_path()).transpose()?), - false => quote!(#name.node().get_path()?), + true => quote!(#name.map(|n| n.get_path())), + false => quote!(#name.get_path()), }, ArgumentType::Color => quote!([#name.c.r, #name.c.g, #name.c.b, #name.a]), ArgumentType::Vec(v) => { let mapping = generate_argument_serialize("a", v, false); - quote!(#name.iter().map(|a| Ok(#mapping)).collect::, crate::node::NodeError>>()?) + quote!(#name.iter().map(|a| Ok(#mapping)).collect::>>()?) } ArgumentType::Map(v) => { let mapping = generate_argument_serialize("a", v, false); - quote!(#name.iter().map(|(k, a)| Ok((k, #mapping))).collect::, crate::node::NodeError>>()?) + quote!(#name.iter().map(|(k, a)| Ok((k, #mapping))).collect::>>()?) } _ => quote!(#name), } } -fn generate_argument_decl(argument: &Argument, returned: bool) -> TokenStream { +fn generate_argument_decl(argument: &Argument, owned_values: bool) -> TokenStream { let name = Ident::new(&argument.name.to_case(Case::Snake), Span::call_site()); - let mut _type = generate_argument_type(&argument._type, returned); + let mut _type = generate_argument_type(&argument._type, owned_values); if argument.optional { _type = quote!(Option<#_type>); } @@ -560,7 +529,11 @@ fn generate_argument_type(argument_type: &ArgumentType, owned: bool) -> TokenStr _type, return_info: _, } => { - quote!(Arc) + if !owned { + quote!(&std::sync::Arc) + } else { + quote!(std::sync::Arc) + } } } } diff --git a/src/nodes/fields/mod.rs b/src/nodes/fields/mod.rs index 5857f21..45d5960 100644 --- a/src/nodes/fields/mod.rs +++ b/src/nodes/fields/mod.rs @@ -264,3 +264,6 @@ pub fn find_field(client: &Client, path: &str) -> Result> { .get_aspect("Field", "info", |n| &n.field) .cloned() } +pub fn get_field(node: &Node) -> Result> { + node.get_aspect("Field", "info", |n| &n.field).cloned() +} diff --git a/src/nodes/mod.rs b/src/nodes/mod.rs index f733375..4d31ffb 100644 --- a/src/nodes/mod.rs +++ b/src/nodes/mod.rs @@ -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( &self, method: &str, - message: impl Into, - ) -> Result>> { - let message = message.into(); + input: S, + fds: Vec, + ) -> Result<(D, Vec)> { 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 { diff --git a/src/nodes/root.rs b/src/nodes/root.rs index 118fb0c..26bcbef 100644 --- a/src/nodes/root.rs +++ b/src/nodes/root.rs @@ -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 = 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> { - let future = self + pub async fn save_state(&self) -> Result { + 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) } } diff --git a/src/nodes/spatial/mod.rs b/src/nodes/spatial/mod.rs index d348d57..8d12bf5 100644 --- a/src/nodes/spatial/mod.rs +++ b/src/nodes/spatial/mod.rs @@ -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, node_path: &str) -> Res pub fn find_reference_space(calling_client: &Arc, node_path: &str) -> Result> { find_spatial(calling_client, "Reference space", node_path) } -pub fn get_spatial(node: &Arc, node_name: &str, aspect_name: &str) -> Result> { - node.get_aspect(node_name, aspect_name, |n| &n.spatial) +pub fn get_spatial(node: &Arc, node_name: &str) -> Result> { + node.get_aspect(node_name, "spatial", |n| &n.spatial) .cloned() } +pub struct SpatialInterface; +impl SpatialInterfaceAspect for SpatialInterface { + fn create_spatial( + _node: Arc, + calling_client: Arc, + _fds: Vec, + name: String, + parent: Arc, + 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, + calling_client: Arc, + _fds: Vec, + name: String, + parent: Arc, + transform: Transform, + field: Arc, + ) -> 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) -> 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); + ::add_node_members(&node); node.add_to_scenegraph().map(|_| ()) } - -pub fn create_spatial_flex( - _node: Arc, - calling_client: Arc, - 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(()) -} diff --git a/src/nodes/spatial/zone.rs b/src/nodes/spatial/zone.rs index 8dfafd2..d5dde8c 100644 --- a/src/nodes/spatial/zone.rs +++ b/src/nodes/spatial/zone.rs @@ -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, zone: &Arc) { let old_distance = spatial.zone_distance(); @@ -31,10 +30,7 @@ pub fn capture(spatial: &Arc, zone: &Arc) { 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); + ::add_node_members(node); let _ = node.zone.set(zone.clone()); zone } - fn capture_flex(node: Arc, calling_client: Arc, 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, calling_client: Arc, 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, _calling_client: Arc, _message: Message) -> Result<()> { +} +impl ZoneAspect for Zone { + #[doc = ""] + fn update( + node: Arc, + _calling_client: Arc, + _fds: Vec, + ) -> 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::>>(); - 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, + _calling_client: Arc, + _fds: Vec, + spatial: Arc, + ) -> 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, + _calling_client: Arc, + _fds: Vec, + spatial: Arc, + ) -> 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, - calling_client: Arc, - 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(()) -}