refactor: alias_id
This commit is contained in:
4
Cargo.lock
generated
4
Cargo.lock
generated
@@ -2698,7 +2698,7 @@ checksum = "2f2b15926089e5526bb2dd738a2eb0e59034356e06eb71e1cd912358c0e62c4d"
|
||||
[[package]]
|
||||
name = "stardust-xr"
|
||||
version = "0.45.0"
|
||||
source = "git+https://github.com/StardustXR/core.git?branch=dev#8313d5ce425dfec9f460526d527536b52d58b963"
|
||||
source = "git+https://github.com/StardustXR/core.git?branch=dev#22fcdda7937308a067a9f61ecbcffb0907739ecb"
|
||||
dependencies = [
|
||||
"cluFlock",
|
||||
"dirs",
|
||||
@@ -2718,7 +2718,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "stardust-xr-schemas"
|
||||
version = "1.5.3"
|
||||
source = "git+https://github.com/StardustXR/core.git?branch=dev#8313d5ce425dfec9f460526d527536b52d58b963"
|
||||
source = "git+https://github.com/StardustXR/core.git?branch=dev#22fcdda7937308a067a9f61ecbcffb0907739ecb"
|
||||
dependencies = [
|
||||
"flatbuffers",
|
||||
"flexbuffers",
|
||||
|
||||
@@ -64,11 +64,25 @@ fn codegen_protocol(protocol: &'static str) -> proc_macro::TokenStream {
|
||||
};
|
||||
let aspect = generate_aspect(&Aspect {
|
||||
name: "interface".to_string(),
|
||||
id: 0,
|
||||
description: protocol.description.clone(),
|
||||
inherits: vec![],
|
||||
members: p.members,
|
||||
});
|
||||
quote!(#node_id #aspect)
|
||||
quote! {
|
||||
#node_id
|
||||
#aspect
|
||||
pub struct Interface;
|
||||
impl crate::nodes::Aspect for Interface {
|
||||
impl_aspect_for_interface_aspect!{}
|
||||
}
|
||||
pub fn create_interface(client: &std::sync::Arc<crate::core::client::Client>) -> color_eyre::eyre::Result<()>{
|
||||
let node = crate::nodes::Node::from_id(client,INTERFACE_NODE_ID,false);
|
||||
node.add_aspect(Interface);
|
||||
node.add_to_scenegraph()?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
})
|
||||
.unwrap_or_default();
|
||||
let custom_enums = protocol
|
||||
@@ -177,7 +191,7 @@ fn generate_aspect(aspect: &Aspect) -> TokenStream {
|
||||
Span::call_site(),
|
||||
);
|
||||
let client_side_members = client_members
|
||||
.map(generate_member)
|
||||
.map(|m| generate_member(aspect.id, m))
|
||||
.reduce(fold_tokens)
|
||||
.map(|t| {
|
||||
// TODO: properly import all dependencies
|
||||
@@ -190,11 +204,6 @@ fn generate_aspect(aspect: &Aspect) -> TokenStream {
|
||||
})
|
||||
.unwrap_or_default();
|
||||
|
||||
let aspect_trait_name = Ident::new(
|
||||
&format!("{}Aspect", &aspect.name.to_case(Case::Pascal)),
|
||||
Span::call_site(),
|
||||
);
|
||||
|
||||
let opcodes = aspect
|
||||
.members
|
||||
.iter()
|
||||
@@ -219,31 +228,87 @@ fn generate_aspect(aspect: &Aspect) -> TokenStream {
|
||||
let alias_info = generate_alias_info(aspect);
|
||||
|
||||
let server_side_members = server_members
|
||||
.map(generate_member)
|
||||
.map(|m| generate_member(aspect.id, m))
|
||||
.reduce(fold_tokens)
|
||||
.unwrap_or_default();
|
||||
let add_node_members = aspect
|
||||
let aspect_trait_name = Ident::new(
|
||||
&format!("{}Aspect", &aspect.name.to_case(Case::Pascal)),
|
||||
Span::call_site(),
|
||||
);
|
||||
let run_signals = aspect
|
||||
.members
|
||||
.iter()
|
||||
.filter(|m| m.side == Side::Server)
|
||||
.map(generate_handler)
|
||||
.filter(|m| m._type == MemberType::Signal)
|
||||
.map(|m| generate_run_member(&aspect_trait_name, MemberType::Signal, m))
|
||||
.reduce(fold_tokens)
|
||||
.unwrap_or_default();
|
||||
let run_methods = aspect
|
||||
.members
|
||||
.iter()
|
||||
.filter(|m| m.side == Side::Server)
|
||||
.filter(|m| m._type == MemberType::Method)
|
||||
.map(|m| generate_run_member(&aspect_trait_name, MemberType::Method, m))
|
||||
.reduce(fold_tokens)
|
||||
.map(|members| {
|
||||
quote! {
|
||||
fn add_node_members(node: &crate::nodes::Node) {
|
||||
#members
|
||||
}
|
||||
}
|
||||
})
|
||||
.unwrap_or_default();
|
||||
let server_side_members = quote! {
|
||||
#[doc = #description]
|
||||
pub trait #aspect_trait_name {
|
||||
#add_node_members
|
||||
#server_side_members
|
||||
}
|
||||
};
|
||||
quote!(#opcodes #alias_info #client_side_members #server_side_members)
|
||||
let aspect_name = aspect.name.to_case(Case::Camel);
|
||||
let aspect_macro_name = Ident::new(
|
||||
&format!(
|
||||
"impl_aspect_for_{}_aspect",
|
||||
aspect.name.to_case(Case::Snake)
|
||||
),
|
||||
Span::call_site(),
|
||||
);
|
||||
let aspect_id = aspect.id;
|
||||
let aspect_macro = quote! {
|
||||
macro_rules! #aspect_macro_name {
|
||||
() => {
|
||||
fn name(&self) -> String {
|
||||
#aspect_name.to_string()
|
||||
}
|
||||
fn id(&self) -> u64 {
|
||||
#aspect_id
|
||||
}
|
||||
fn as_any(self: Arc<Self>) -> Arc<dyn std::any::Any + Send + Sync + 'static> {
|
||||
self
|
||||
}
|
||||
fn run_signal(
|
||||
&self,
|
||||
_calling_client: std::sync::Arc<crate::core::client::Client>,
|
||||
_node: std::sync::Arc<crate::nodes::Node>,
|
||||
_signal: u64,
|
||||
_message: crate::nodes::Message
|
||||
) -> Result<(), stardust_xr::scenegraph::ScenegraphError> {
|
||||
match _signal {
|
||||
#run_signals
|
||||
_ => Err(stardust_xr::scenegraph::ScenegraphError::SignalNotFound)
|
||||
}
|
||||
}
|
||||
fn run_method(
|
||||
&self,
|
||||
_calling_client: std::sync::Arc<crate::core::client::Client>,
|
||||
_node: std::sync::Arc<crate::nodes::Node>,
|
||||
_method: u64,
|
||||
_message: crate::nodes::Message,
|
||||
_method_response: crate::nodes::MethodResponseSender,
|
||||
) {
|
||||
match _method {
|
||||
#run_methods
|
||||
_ => {
|
||||
let _ = _method_response.send(Err(stardust_xr::scenegraph::ScenegraphError::MethodNotFound));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
quote!(#opcodes #alias_info #client_side_members #server_side_members #aspect_macro)
|
||||
}
|
||||
|
||||
fn generate_alias_opcodes(aspect: &Aspect, side: Side, _type: MemberType) -> TokenStream {
|
||||
@@ -293,8 +358,8 @@ fn generate_alias_info(aspect: &Aspect) -> TokenStream {
|
||||
}
|
||||
}
|
||||
|
||||
fn generate_member(member: &Member) -> TokenStream {
|
||||
let id = member.opcode;
|
||||
fn generate_member(aspect_id: u64, member: &Member) -> TokenStream {
|
||||
let opcode = member.opcode;
|
||||
let name = Ident::new(&member.name.to_case(Case::Snake), Span::call_site());
|
||||
let description = &member.description;
|
||||
|
||||
@@ -326,27 +391,21 @@ fn generate_member(member: &Member) -> TokenStream {
|
||||
.unwrap_or_else(|| quote!(()));
|
||||
|
||||
match (side, _type) {
|
||||
(Side::Client, MemberType::Method) => {
|
||||
quote! {
|
||||
#[doc = #description]
|
||||
pub async fn #name(#argument_decls) -> color_eyre::eyre::Result<(#return_type, Vec<std::os::fd::OwnedFd>)> {
|
||||
_node.execute_remote_method_typed(#id, &(#argument_uses), vec![]).await
|
||||
}
|
||||
}
|
||||
}
|
||||
(Side::Client, MemberType::Signal) => {
|
||||
quote! {
|
||||
#[doc = #description]
|
||||
pub fn #name(#argument_decls) -> color_eyre::eyre::Result<()> {
|
||||
let serialized = stardust_xr::schemas::flex::serialize((#argument_uses))?;
|
||||
_node.send_remote_signal(#id, serialized)
|
||||
_node.send_remote_signal(#aspect_id, #opcode, serialized)
|
||||
}
|
||||
}
|
||||
}
|
||||
(Side::Server, MemberType::Method) => {
|
||||
(Side::Client, MemberType::Method) => {
|
||||
quote! {
|
||||
#[doc = #description]
|
||||
fn #name(#argument_decls) -> impl std::future::Future<Output = color_eyre::eyre::Result<#return_type>> + Send + 'static;
|
||||
pub async fn #name(#argument_decls) -> color_eyre::eyre::Result<(#return_type, Vec<std::os::fd::OwnedFd>)> {
|
||||
_node.execute_remote_method_typed(#aspect_id, #opcode, &(#argument_uses), vec![]).await
|
||||
}
|
||||
}
|
||||
}
|
||||
(Side::Server, MemberType::Signal) => {
|
||||
@@ -355,9 +414,15 @@ fn generate_member(member: &Member) -> TokenStream {
|
||||
fn #name(#argument_decls) -> color_eyre::eyre::Result<()>;
|
||||
}
|
||||
}
|
||||
(Side::Server, MemberType::Method) => {
|
||||
quote! {
|
||||
#[doc = #description]
|
||||
fn #name(#argument_decls) -> impl std::future::Future<Output = color_eyre::eyre::Result<#return_type>> + Send + Sync + 'static;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fn generate_handler(member: &Member) -> TokenStream {
|
||||
fn generate_run_member(aspect_name: &Ident, _type: MemberType, member: &Member) -> TokenStream {
|
||||
let opcode = member.opcode;
|
||||
let member_name_ident = Ident::new(&member.name, Span::call_site());
|
||||
|
||||
@@ -393,21 +458,19 @@ fn generate_handler(member: &Member) -> TokenStream {
|
||||
.map(|a| generate_argument_deserialize(&a.name, &a._type, a.optional))
|
||||
.reduce(|a, b| quote!(#a, #b))
|
||||
.unwrap_or_default();
|
||||
match member._type {
|
||||
match _type {
|
||||
MemberType::Signal => quote! {
|
||||
node.add_local_signal(#opcode, |_node, _calling_client, _message| {
|
||||
#opcode => (move || {
|
||||
#deserialize
|
||||
Self::#member_name_ident(_node, _calling_client.clone(), #argument_uses)
|
||||
});
|
||||
<Self as #aspect_name>::#member_name_ident(_node, _calling_client.clone(), #argument_uses)
|
||||
})().map_err(|e: color_eyre::Report| stardust_xr::scenegraph::ScenegraphError::SignalError { error: e.to_string() }),
|
||||
},
|
||||
MemberType::Method => quote! {
|
||||
node.add_local_method(#opcode, |_node, _calling_client, _message, _method_response| {
|
||||
_method_response.wrap_async(async move {
|
||||
#deserialize
|
||||
let result = Self::#member_name_ident(_node, _calling_client.clone(), #argument_uses).await?;
|
||||
Ok((#serialize, Vec::new()))
|
||||
});
|
||||
});
|
||||
#opcode => _method_response.wrap_async(async move {
|
||||
#deserialize
|
||||
let result = <Self as #aspect_name>::#member_name_ident(_node, _calling_client.clone(), #argument_uses).await?;
|
||||
Ok((#serialize, Vec::<std::os::fd::OwnedFd>::new()))
|
||||
}),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
#[macro_export]
|
||||
macro_rules! create_interface {
|
||||
($iface:ident) => {
|
||||
pub fn create_interface(client: &Arc<Client>) -> Result<()> {
|
||||
let node = Node::from_id(client, INTERFACE_NODE_ID, false);
|
||||
<$iface as self::InterfaceAspect>::add_node_members(&node);
|
||||
node.add_to_scenegraph()?;
|
||||
Ok(())
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -2,7 +2,6 @@ pub mod client;
|
||||
pub mod client_state;
|
||||
pub mod delta;
|
||||
pub mod destroy_queue;
|
||||
pub mod idl_utils;
|
||||
pub mod registry;
|
||||
pub mod resource;
|
||||
pub mod scenegraph;
|
||||
|
||||
@@ -86,19 +86,21 @@ fn map_method_return<T: Serialize>(
|
||||
impl scenegraph::Scenegraph for Scenegraph {
|
||||
fn send_signal(
|
||||
&self,
|
||||
node: u64,
|
||||
node_id: u64,
|
||||
aspect_id: u64,
|
||||
method: u64,
|
||||
data: &[u8],
|
||||
fds: Vec<OwnedFd>,
|
||||
) -> Result<(), ScenegraphError> {
|
||||
let Some(client) = self.get_client() else {
|
||||
return Err(ScenegraphError::SignalNotFound);
|
||||
return Err(ScenegraphError::NodeNotFound);
|
||||
};
|
||||
debug_span!("Handle signal", node, method).in_scope(|| {
|
||||
self.get_node(node)
|
||||
debug_span!("Handle signal", aspect_id, node_id, method).in_scope(|| {
|
||||
self.get_node(node_id)
|
||||
.ok_or(ScenegraphError::NodeNotFound)?
|
||||
.send_local_signal(
|
||||
client,
|
||||
aspect_id,
|
||||
method,
|
||||
Message {
|
||||
data: data.to_vec(),
|
||||
@@ -109,23 +111,25 @@ impl scenegraph::Scenegraph for Scenegraph {
|
||||
}
|
||||
fn execute_method(
|
||||
&self,
|
||||
node: u64,
|
||||
node_id: u64,
|
||||
aspect_id: u64,
|
||||
method: u64,
|
||||
data: &[u8],
|
||||
fds: Vec<OwnedFd>,
|
||||
response: oneshot::Sender<Result<(Vec<u8>, Vec<OwnedFd>), ScenegraphError>>,
|
||||
) {
|
||||
let Some(client) = self.get_client() else {
|
||||
let _ = response.send(Err(ScenegraphError::MethodNotFound));
|
||||
let _ = response.send(Err(ScenegraphError::NodeNotFound));
|
||||
return;
|
||||
};
|
||||
debug!(node, method, "Handle method");
|
||||
let Some(node) = self.get_node(node) else {
|
||||
debug!(aspect_id, node_id, method, "Handle method");
|
||||
let Some(node) = self.get_node(node_id) else {
|
||||
let _ = response.send(Err(ScenegraphError::NodeNotFound));
|
||||
return;
|
||||
};
|
||||
node.execute_local_method(
|
||||
client,
|
||||
aspect_id,
|
||||
method,
|
||||
Message {
|
||||
data: data.to_vec(),
|
||||
|
||||
@@ -262,8 +262,6 @@ fn stereokit_loop(
|
||||
}
|
||||
|
||||
info!("Cleanly shut down StereoKit");
|
||||
#[cfg(feature = "wayland")]
|
||||
drop(wayland);
|
||||
}
|
||||
|
||||
fn adaptive_sleep(
|
||||
|
||||
@@ -69,7 +69,33 @@ impl Alias {
|
||||
}
|
||||
}
|
||||
impl Aspect for Alias {
|
||||
const NAME: &'static str = "Alias";
|
||||
fn name(&self) -> String {
|
||||
"Alias".to_string()
|
||||
}
|
||||
fn id(&self) -> u64 {
|
||||
0
|
||||
}
|
||||
fn as_any(self: Arc<Self>) -> Arc<dyn std::any::Any + Send + Sync + 'static> {
|
||||
self
|
||||
}
|
||||
fn run_signal(
|
||||
&self,
|
||||
_calling_client: Arc<Client>,
|
||||
_node: Arc<Node>,
|
||||
_signal: u64,
|
||||
_message: super::Message,
|
||||
) -> Result<(), stardust_xr::scenegraph::ScenegraphError> {
|
||||
Ok(())
|
||||
}
|
||||
fn run_method(
|
||||
&self,
|
||||
_calling_client: Arc<Client>,
|
||||
_node: Arc<Node>,
|
||||
_method: u64,
|
||||
_message: super::Message,
|
||||
_response: crate::core::scenegraph::MethodResponseSender,
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_original(node: Arc<Node>, stop_on_disabled: bool) -> Option<Arc<Node>> {
|
||||
|
||||
@@ -3,9 +3,7 @@ use crate::core::client::Client;
|
||||
use crate::core::destroy_queue;
|
||||
use crate::core::registry::Registry;
|
||||
use crate::core::resource::get_resource_file;
|
||||
use crate::create_interface;
|
||||
use crate::nodes::spatial::SPATIAL_ASPECT_ALIAS_INFO;
|
||||
use crate::nodes::spatial::{Spatial, Transform};
|
||||
use crate::nodes::spatial::{Spatial, Transform, SPATIAL_ASPECT_ALIAS_INFO};
|
||||
use color_eyre::eyre::{eyre, Result};
|
||||
use glam::{vec3, Vec4Swizzles};
|
||||
use once_cell::sync::OnceCell;
|
||||
@@ -49,7 +47,6 @@ impl Sound {
|
||||
};
|
||||
let sound_arc = SOUND_REGISTRY.add(sound);
|
||||
node.add_aspect_raw(sound_arc.clone());
|
||||
<Sound as SoundAspect>::add_node_members(node);
|
||||
Ok(sound_arc)
|
||||
}
|
||||
|
||||
@@ -72,7 +69,7 @@ impl Sound {
|
||||
}
|
||||
}
|
||||
impl Aspect for Sound {
|
||||
const NAME: &'static str = "Sound";
|
||||
impl_aspect_for_sound_aspect! {}
|
||||
}
|
||||
impl SoundAspect for Sound {
|
||||
fn play(node: Arc<Node>, _calling_client: Arc<Client>) -> Result<()> {
|
||||
@@ -101,9 +98,7 @@ pub fn update() {
|
||||
}
|
||||
}
|
||||
|
||||
create_interface!(AudioInterface);
|
||||
struct AudioInterface;
|
||||
impl InterfaceAspect for AudioInterface {
|
||||
impl InterfaceAspect for Interface {
|
||||
#[doc = "Create a sound node. WAV and MP3 are supported."]
|
||||
fn create_sound(
|
||||
_node: Arc<Node>,
|
||||
|
||||
@@ -4,7 +4,6 @@ use super::spatial::{parse_transform, Spatial};
|
||||
use super::{Alias, Aspect, Node};
|
||||
use crate::core::client::Client;
|
||||
use crate::core::registry::Registry;
|
||||
use crate::create_interface;
|
||||
use crate::nodes::fields::FIELD_ALIAS_INFO;
|
||||
use crate::nodes::spatial::Transform;
|
||||
use crate::nodes::spatial::SPATIAL_ASPECT_ALIAS_INFO;
|
||||
@@ -71,7 +70,6 @@ impl PulseSender {
|
||||
field_aliases: AliasList::default(),
|
||||
};
|
||||
|
||||
// <PulseSender as PulseSenderAspect>::add_node_members(node);
|
||||
let sender = PULSE_SENDER_REGISTRY.add(sender);
|
||||
node.add_aspect_raw(sender.clone());
|
||||
for receiver in PULSE_RECEIVER_REGISTRY.get_valid_contents() {
|
||||
@@ -134,7 +132,7 @@ impl PulseSender {
|
||||
}
|
||||
}
|
||||
impl Aspect for PulseSender {
|
||||
const NAME: &'static str = "PulseSender";
|
||||
impl_aspect_for_pulse_sender_aspect! {}
|
||||
}
|
||||
impl PulseSenderAspect for PulseSender {}
|
||||
impl Drop for PulseSender {
|
||||
@@ -161,7 +159,6 @@ impl PulseReceiver {
|
||||
};
|
||||
let receiver = PULSE_RECEIVER_REGISTRY.add(receiver);
|
||||
|
||||
<PulseReceiver as PulseReceiverAspect>::add_node_members(node);
|
||||
node.add_aspect_raw(receiver.clone());
|
||||
for sender in PULSE_SENDER_REGISTRY.get_valid_contents() {
|
||||
sender.handle_new_receiver(&receiver);
|
||||
@@ -170,7 +167,7 @@ impl PulseReceiver {
|
||||
}
|
||||
}
|
||||
impl Aspect for PulseReceiver {
|
||||
const NAME: &'static str = "PulseReceiver";
|
||||
impl_aspect_for_pulse_receiver_aspect! {}
|
||||
}
|
||||
impl PulseReceiverAspect for PulseReceiver {
|
||||
fn send_data(
|
||||
@@ -199,9 +196,7 @@ impl Drop for PulseReceiver {
|
||||
}
|
||||
}
|
||||
|
||||
create_interface!(DataInterface);
|
||||
struct DataInterface;
|
||||
impl InterfaceAspect for DataInterface {
|
||||
impl InterfaceAspect for Interface {
|
||||
fn create_pulse_sender(
|
||||
_node: Arc<Node>,
|
||||
calling_client: Arc<Client>,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use super::{Line, LinesAspect};
|
||||
use crate::{
|
||||
core::{client::Client, registry::Registry},
|
||||
nodes::{spatial::Spatial, Aspect, Node},
|
||||
nodes::{spatial::Spatial, Node},
|
||||
};
|
||||
use color_eyre::eyre::Result;
|
||||
use glam::Vec3;
|
||||
@@ -40,7 +40,6 @@ impl Lines {
|
||||
space: node.get_aspect::<Spatial>()?.clone(),
|
||||
data: Mutex::new(lines),
|
||||
});
|
||||
<Lines as LinesAspect>::add_node_members(node);
|
||||
node.add_aspect_raw(lines.clone());
|
||||
|
||||
Ok(lines)
|
||||
@@ -83,9 +82,6 @@ impl Lines {
|
||||
}
|
||||
}
|
||||
}
|
||||
impl Aspect for Lines {
|
||||
const NAME: &'static str = "Lines";
|
||||
}
|
||||
impl LinesAspect for Lines {
|
||||
fn set_lines(node: Arc<Node>, _calling_client: Arc<Client>, lines: Vec<Line>) -> Result<()> {
|
||||
let lines_aspect = node.get_aspect::<Lines>()?;
|
||||
|
||||
@@ -8,14 +8,12 @@ pub mod text;
|
||||
use self::{lines::Lines, model::Model, text::Text};
|
||||
use super::{
|
||||
spatial::{Spatial, Transform},
|
||||
Node,
|
||||
Aspect, Node,
|
||||
};
|
||||
use crate::core::{client::Client, resource::get_resource_file};
|
||||
use crate::nodes::spatial::SPATIAL_ASPECT_ALIAS_INFO;
|
||||
use crate::{
|
||||
core::{client::Client, resource::get_resource_file},
|
||||
create_interface,
|
||||
};
|
||||
use color_eyre::eyre::{self, Result};
|
||||
use model::ModelPart;
|
||||
use parking_lot::Mutex;
|
||||
use stardust_xr::values::ResourceID;
|
||||
use std::{ffi::OsStr, path::PathBuf, sync::Arc};
|
||||
@@ -43,10 +41,20 @@ static QUEUED_SKYLIGHT: Mutex<Option<PathBuf>> = Mutex::new(None);
|
||||
static QUEUED_SKYTEX: Mutex<Option<PathBuf>> = Mutex::new(None);
|
||||
|
||||
stardust_xr_server_codegen::codegen_drawable_protocol!();
|
||||
create_interface!(DrawableInterface);
|
||||
impl Aspect for Lines {
|
||||
impl_aspect_for_lines_aspect! {}
|
||||
}
|
||||
impl Aspect for Model {
|
||||
impl_aspect_for_model_aspect! {}
|
||||
}
|
||||
impl Aspect for ModelPart {
|
||||
impl_aspect_for_model_part_aspect! {}
|
||||
}
|
||||
impl Aspect for Text {
|
||||
impl_aspect_for_text_aspect! {}
|
||||
}
|
||||
|
||||
pub struct DrawableInterface;
|
||||
impl InterfaceAspect for DrawableInterface {
|
||||
impl InterfaceAspect for Interface {
|
||||
fn set_sky_tex(_node: Arc<Node>, calling_client: Arc<Client>, tex: ResourceID) -> Result<()> {
|
||||
let resource_path = get_resource_file(&tex, &calling_client, &[OsStr::new("hdr")])
|
||||
.ok_or(eyre::eyre!("Could not find resource"))?;
|
||||
|
||||
@@ -4,7 +4,7 @@ use crate::core::registry::Registry;
|
||||
use crate::core::resource::get_resource_file;
|
||||
use crate::nodes::alias::{Alias, AliasList};
|
||||
use crate::nodes::spatial::Spatial;
|
||||
use crate::nodes::{Aspect, Node};
|
||||
use crate::nodes::Node;
|
||||
use color_eyre::eyre::{bail, eyre, Result};
|
||||
use glam::{Mat4, Vec2, Vec3};
|
||||
use once_cell::sync::{Lazy, OnceCell};
|
||||
@@ -204,7 +204,6 @@ impl ModelPart {
|
||||
pending_material_replacement: Mutex::new(None),
|
||||
aliases: AliasList::default(),
|
||||
});
|
||||
<ModelPart as ModelPartAspect>::add_node_members(&node);
|
||||
node.add_aspect_raw(model_part.clone());
|
||||
parts.push(model_part.clone());
|
||||
Some(model_part)
|
||||
@@ -278,9 +277,6 @@ impl ModelPart {
|
||||
}
|
||||
}
|
||||
}
|
||||
impl Aspect for ModelPart {
|
||||
const NAME: &'static str = "ModelPart";
|
||||
}
|
||||
impl ModelPartAspect for ModelPart {
|
||||
#[doc = "Set this model part's material to one that cuts a hole in the world. Often used for overlays/passthrough where you want to show the background through an object."]
|
||||
fn apply_holdout_material(node: Arc<Node>, _calling_client: Arc<Client>) -> Result<()> {
|
||||
@@ -327,7 +323,6 @@ impl Model {
|
||||
sk_model: OnceCell::new(),
|
||||
parts: Mutex::new(Vec::default()),
|
||||
});
|
||||
<Model as ModelAspect>::add_node_members(node);
|
||||
MODEL_REGISTRY.add_raw(&model);
|
||||
|
||||
// technically doing this in anything but the main thread isn't a good idea but dangit we need those model nodes ASAP
|
||||
@@ -361,9 +356,6 @@ impl Model {
|
||||
// TODO: proper hread safety in stereokit_rust (probably just bind stereokit directly)
|
||||
unsafe impl Send for Model {}
|
||||
unsafe impl Sync for Model {}
|
||||
impl Aspect for Model {
|
||||
const NAME: &'static str = "Model";
|
||||
}
|
||||
impl ModelAspect for Model {
|
||||
#[doc = "Bind a model part to the node with the ID input."]
|
||||
fn bind_model_part(
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use crate::{
|
||||
core::{client::Client, destroy_queue, registry::Registry, resource::get_resource_file},
|
||||
nodes::{spatial::Spatial, Aspect, Node},
|
||||
nodes::{spatial::Spatial, Node},
|
||||
};
|
||||
use color_eyre::eyre::{eyre, Result};
|
||||
use glam::{vec3, Mat4, Vec2};
|
||||
@@ -53,7 +53,6 @@ impl Text {
|
||||
text: Mutex::new(text),
|
||||
data: Mutex::new(style),
|
||||
});
|
||||
<Text as TextAspect>::add_node_members(node);
|
||||
node.add_aspect_raw(text.clone());
|
||||
|
||||
Ok(text)
|
||||
@@ -132,9 +131,6 @@ impl Text {
|
||||
}
|
||||
}
|
||||
}
|
||||
impl Aspect for Text {
|
||||
const NAME: &'static str = "Text";
|
||||
}
|
||||
impl TextAspect for Text {
|
||||
fn set_character_height(
|
||||
node: Arc<Node>,
|
||||
|
||||
@@ -5,7 +5,6 @@ use super::spatial::{
|
||||
};
|
||||
use super::{Aspect, Node};
|
||||
use crate::core::client::Client;
|
||||
use crate::create_interface;
|
||||
use crate::nodes::spatial::Transform;
|
||||
use crate::nodes::spatial::SPATIAL_ASPECT_ALIAS_INFO;
|
||||
use crate::nodes::spatial::SPATIAL_REF_ASPECT_ALIAS_INFO;
|
||||
@@ -145,15 +144,59 @@ impl Field {
|
||||
shape: Mutex::new(shape),
|
||||
};
|
||||
let field = node.add_aspect(field);
|
||||
<Field as FieldRefAspect>::add_node_members(node);
|
||||
<Field as FieldAspect>::add_node_members(node);
|
||||
node.add_aspect(FieldRef);
|
||||
Ok(field)
|
||||
}
|
||||
}
|
||||
impl Aspect for Field {
|
||||
const NAME: &'static str = "Field";
|
||||
impl_aspect_for_field_aspect! {}
|
||||
}
|
||||
impl FieldRefAspect for Field {
|
||||
impl FieldAspect for Field {
|
||||
fn set_shape(node: Arc<Node>, _calling_client: Arc<Client>, shape: Shape) -> Result<()> {
|
||||
let field = node.get_aspect::<Field>()?;
|
||||
*field.shape.lock() = shape;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn export_field(node: Arc<Node>, _calling_client: Arc<Client>) -> Result<u64> {
|
||||
let id = rand::random();
|
||||
EXPORTED_FIELDS.lock().insert(id, node);
|
||||
Ok(id)
|
||||
}
|
||||
}
|
||||
impl FieldTrait for Field {
|
||||
fn spatial_ref(&self) -> &Spatial {
|
||||
&self.spatial
|
||||
}
|
||||
fn local_distance(&self, p: Vec3A) -> f32 {
|
||||
match self.shape.lock().clone() {
|
||||
Shape::Box(size) => {
|
||||
let q = vec3(
|
||||
p.x.abs() - (size.x * 0.5_f32),
|
||||
p.y.abs() - (size.y * 0.5_f32),
|
||||
p.z.abs() - (size.z * 0.5_f32),
|
||||
);
|
||||
let v = vec3a(q.x.max(0_f32), q.y.max(0_f32), q.z.max(0_f32));
|
||||
v.length() + q.x.max(q.y.max(q.z)).min(0_f32)
|
||||
}
|
||||
Shape::Cylinder(CylinderShape { length, radius }) => {
|
||||
let d = vec2(p.xy().length().abs() - radius, p.z.abs() - (length * 0.5));
|
||||
d.x.max(d.y).min(0.0) + d.max(vec2(0.0, 0.0)).length()
|
||||
}
|
||||
Shape::Sphere(radius) => p.length() - radius,
|
||||
Shape::Torus(TorusShape { radius_a, radius_b }) => {
|
||||
let q = vec2(p.xz().length() - radius_a, p.y);
|
||||
q.length() - radius_b
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct FieldRef;
|
||||
impl Aspect for FieldRef {
|
||||
impl_aspect_for_field_ref_aspect! {}
|
||||
}
|
||||
impl FieldRefAspect for FieldRef {
|
||||
async fn distance(
|
||||
node: Arc<Node>,
|
||||
_calling_client: Arc<Client>,
|
||||
@@ -205,50 +248,8 @@ impl FieldRefAspect for Field {
|
||||
}))
|
||||
}
|
||||
}
|
||||
impl FieldAspect for Field {
|
||||
fn set_shape(node: Arc<Node>, _calling_client: Arc<Client>, shape: Shape) -> Result<()> {
|
||||
let field = node.get_aspect::<Field>()?;
|
||||
*field.shape.lock() = shape;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn export_field(node: Arc<Node>, _calling_client: Arc<Client>) -> Result<u64> {
|
||||
let id = rand::random();
|
||||
EXPORTED_FIELDS.lock().insert(id, node);
|
||||
Ok(id)
|
||||
}
|
||||
}
|
||||
impl FieldTrait for Field {
|
||||
fn spatial_ref(&self) -> &Spatial {
|
||||
&self.spatial
|
||||
}
|
||||
fn local_distance(&self, p: Vec3A) -> f32 {
|
||||
match self.shape.lock().clone() {
|
||||
Shape::Box(size) => {
|
||||
let q = vec3(
|
||||
p.x.abs() - (size.x * 0.5_f32),
|
||||
p.y.abs() - (size.y * 0.5_f32),
|
||||
p.z.abs() - (size.z * 0.5_f32),
|
||||
);
|
||||
let v = vec3a(q.x.max(0_f32), q.y.max(0_f32), q.z.max(0_f32));
|
||||
v.length() + q.x.max(q.y.max(q.z)).min(0_f32)
|
||||
}
|
||||
Shape::Cylinder(CylinderShape { length, radius }) => {
|
||||
let d = vec2(p.xy().length().abs() - radius, p.z.abs() - (length * 0.5));
|
||||
d.x.max(d.y).min(0.0) + d.max(vec2(0.0, 0.0)).length()
|
||||
}
|
||||
Shape::Sphere(radius) => p.length() - radius,
|
||||
Shape::Torus(TorusShape { radius_a, radius_b }) => {
|
||||
let q = vec2(p.xz().length() - radius_a, p.y);
|
||||
q.length() - radius_b
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
create_interface!(FieldInterface);
|
||||
pub struct FieldInterface;
|
||||
impl InterfaceAspect for FieldInterface {
|
||||
impl InterfaceAspect for Interface {
|
||||
async fn import_field_ref(
|
||||
_node: Arc<Node>,
|
||||
calling_client: Arc<Client>,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use super::{InputHandlerAspect, INPUT_HANDLER_REGISTRY, INPUT_METHOD_REGISTRY};
|
||||
use crate::nodes::{alias::AliasList, fields::Field, spatial::Spatial, Aspect, Node};
|
||||
use crate::nodes::{alias::AliasList, fields::Field, spatial::Spatial, Node};
|
||||
use color_eyre::eyre::Result;
|
||||
use std::sync::Arc;
|
||||
|
||||
@@ -23,9 +23,6 @@ impl InputHandler {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
impl Aspect for InputHandler {
|
||||
const NAME: &'static str = "InputHandler";
|
||||
}
|
||||
impl InputHandlerAspect for InputHandler {}
|
||||
impl PartialEq for InputHandler {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
|
||||
@@ -9,7 +9,7 @@ use crate::{
|
||||
alias::{Alias, AliasList},
|
||||
fields::{Field, FIELD_ALIAS_INFO},
|
||||
spatial::Spatial,
|
||||
Aspect, Node,
|
||||
Node,
|
||||
},
|
||||
};
|
||||
use color_eyre::eyre::Result;
|
||||
@@ -45,13 +45,12 @@ impl InputMethod {
|
||||
internal_capture_requests: Registry::new(),
|
||||
captures: Registry::new(),
|
||||
};
|
||||
<InputMethod as InputMethodRefAspect>::add_node_members(node);
|
||||
<InputMethod as InputMethodAspect>::add_node_members(node);
|
||||
for handler in INPUT_HANDLER_REGISTRY.get_valid_contents() {
|
||||
method.handle_new_handler(&handler);
|
||||
}
|
||||
let method = INPUT_METHOD_REGISTRY.add(method);
|
||||
node.add_aspect_raw(method.clone());
|
||||
node.add_aspect(InputMethodRef);
|
||||
Ok(method)
|
||||
}
|
||||
|
||||
@@ -154,25 +153,6 @@ impl InputMethod {
|
||||
}
|
||||
}
|
||||
}
|
||||
impl Aspect for InputMethod {
|
||||
const NAME: &'static str = "InputMethod";
|
||||
}
|
||||
impl InputMethodRefAspect for InputMethod {
|
||||
#[doc = "Have the input handler that this method reference came from capture the method for the next frame."]
|
||||
fn request_capture(
|
||||
node: Arc<Node>,
|
||||
_calling_client: Arc<Client>,
|
||||
handler: Arc<Node>,
|
||||
) -> Result<()> {
|
||||
let input_method = node.get_aspect::<InputMethod>()?;
|
||||
let input_handler = handler.get_aspect::<InputHandler>()?;
|
||||
|
||||
input_method
|
||||
.internal_capture_requests
|
||||
.add_raw(&input_handler);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
impl InputMethodAspect for InputMethod {
|
||||
#[doc = "Set the spatial input component of this input method. You must keep the same input data type throughout the entire thing."]
|
||||
fn set_input(
|
||||
@@ -231,3 +211,21 @@ impl Drop for InputMethod {
|
||||
INPUT_METHOD_REGISTRY.remove(self);
|
||||
}
|
||||
}
|
||||
|
||||
pub struct InputMethodRef;
|
||||
impl InputMethodRefAspect for InputMethodRef {
|
||||
#[doc = "Have the input handler that this method reference came from capture the method for the next frame."]
|
||||
fn request_capture(
|
||||
node: Arc<Node>,
|
||||
_calling_client: Arc<Client>,
|
||||
handler: Arc<Node>,
|
||||
) -> Result<()> {
|
||||
let input_method = node.get_aspect::<InputMethod>()?;
|
||||
let input_handler = handler.get_aspect::<InputHandler>()?;
|
||||
|
||||
input_method
|
||||
.internal_capture_requests
|
||||
.add_raw(&input_handler);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ pub use method::*;
|
||||
|
||||
use super::fields::Field;
|
||||
use super::spatial::Spatial;
|
||||
use crate::create_interface;
|
||||
use super::Aspect;
|
||||
use crate::nodes::spatial::SPATIAL_ASPECT_ALIAS_INFO;
|
||||
use crate::nodes::spatial::SPATIAL_REF_ASPECT_ALIAS_INFO;
|
||||
use crate::{core::client::Client, nodes::Node};
|
||||
@@ -25,6 +25,16 @@ pub static INPUT_HANDLER_REGISTRY: Registry<InputHandler> = Registry::new();
|
||||
|
||||
stardust_xr_server_codegen::codegen_input_protocol!();
|
||||
|
||||
impl Aspect for InputHandler {
|
||||
impl_aspect_for_input_handler_aspect! {}
|
||||
}
|
||||
impl Aspect for InputMethod {
|
||||
impl_aspect_for_input_method_aspect! {}
|
||||
}
|
||||
impl Aspect for InputMethodRef {
|
||||
impl_aspect_for_input_method_ref_aspect! {}
|
||||
}
|
||||
|
||||
pub trait InputDataTrait {
|
||||
fn transform(&mut self, method: &InputMethod, handler: &InputHandler);
|
||||
fn distance(&self, space: &Arc<Spatial>, field: &Field) -> f32;
|
||||
@@ -47,9 +57,7 @@ impl InputDataTrait for InputDataType {
|
||||
}
|
||||
}
|
||||
|
||||
create_interface!(InputInterface);
|
||||
pub struct InputInterface;
|
||||
impl InterfaceAspect for InputInterface {
|
||||
impl InterfaceAspect for Interface {
|
||||
#[doc = "Create an input method node"]
|
||||
fn create_input_method(
|
||||
_node: Arc<Node>,
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
use super::{
|
||||
create_item_acceptor_flex, register_item_ui_flex, Item, ItemAcceptor, ItemInterface, ItemType,
|
||||
};
|
||||
use super::{create_item_acceptor_flex, register_item_ui_flex, Item, ItemType};
|
||||
use crate::nodes::items::ITEM_ACCEPTOR_ASPECT_ALIAS_INFO;
|
||||
use crate::nodes::items::ITEM_ASPECT_ALIAS_INFO;
|
||||
use crate::nodes::Aspect;
|
||||
use crate::{
|
||||
core::{client::Client, registry::Registry, scenegraph::MethodResponseSender},
|
||||
create_interface,
|
||||
nodes::{
|
||||
drawable::{
|
||||
model::{MaterialWrapper, ModelPart},
|
||||
@@ -48,6 +46,12 @@ lazy_static! {
|
||||
ui: Default::default(),
|
||||
items: Registry::new(),
|
||||
acceptors: Registry::new(),
|
||||
add_acceptor_aspect: |node| {
|
||||
node.add_aspect(CameraItemAcceptor);
|
||||
},
|
||||
add_ui_aspect: |node| {
|
||||
node.add_aspect(CameraItemUi);
|
||||
},
|
||||
new_acceptor_fn: |node, acceptor, acceptor_field| {
|
||||
let _ = camera_item_ui_client::create_acceptor(node, acceptor, acceptor_field);
|
||||
}
|
||||
@@ -85,7 +89,7 @@ impl CameraItem {
|
||||
apply_to: Registry::new(),
|
||||
}),
|
||||
);
|
||||
// <CameraItem as CameraItemAspect>::node_methods(node);
|
||||
node.add_aspect(CameraItemUi);
|
||||
}
|
||||
|
||||
fn frame_flex(
|
||||
@@ -169,7 +173,17 @@ impl CameraItem {
|
||||
}
|
||||
impl CameraItemAspect for CameraItem {}
|
||||
|
||||
impl CameraItemAcceptorAspect for ItemAcceptor {
|
||||
pub struct CameraItemUi;
|
||||
impl Aspect for CameraItemUi {
|
||||
impl_aspect_for_camera_item_ui_aspect! {}
|
||||
}
|
||||
impl CameraItemUiAspect for CameraItemUi {}
|
||||
|
||||
pub struct CameraItemAcceptor;
|
||||
impl Aspect for CameraItemAcceptor {
|
||||
impl_aspect_for_camera_item_acceptor_aspect! {}
|
||||
}
|
||||
impl CameraItemAcceptorAspect for CameraItemAcceptor {
|
||||
fn capture_item(node: Arc<Node>, _calling_client: Arc<Client>, item: Arc<Node>) -> Result<()> {
|
||||
super::acceptor_capture_item_flex(node, item)
|
||||
}
|
||||
@@ -184,8 +198,7 @@ pub fn update(token: &MainThreadToken) {
|
||||
}
|
||||
}
|
||||
|
||||
create_interface!(ItemInterface);
|
||||
impl InterfaceAspect for ItemInterface {
|
||||
impl InterfaceAspect for Interface {
|
||||
#[doc = "Create a camera item at a specific location"]
|
||||
fn create_camera_item(
|
||||
_node: Arc<Node>,
|
||||
@@ -206,19 +219,21 @@ impl InterfaceAspect for ItemInterface {
|
||||
}
|
||||
|
||||
#[doc = "Register this client to manage camera items and create default 3D UI for them."]
|
||||
fn register_camera_item_ui(_node: Arc<Node>, calling_client: Arc<Client>) -> Result<()> {
|
||||
fn register_camera_item_ui(node: Arc<Node>, calling_client: Arc<Client>) -> Result<()> {
|
||||
node.add_aspect(CameraItemUi);
|
||||
register_item_ui_flex(calling_client, &ITEM_TYPE_INFO_CAMERA)
|
||||
}
|
||||
|
||||
#[doc = "Create an item acceptor to allow temporary ownership of a given type of item. Creates a node at `/item/camera/acceptor/<name>`."]
|
||||
fn create_camera_item_acceptor(
|
||||
_node: Arc<Node>,
|
||||
node: Arc<Node>,
|
||||
calling_client: Arc<Client>,
|
||||
id: u64,
|
||||
parent: Arc<Node>,
|
||||
transform: Transform,
|
||||
field: Arc<Node>,
|
||||
) -> Result<()> {
|
||||
node.add_aspect(CameraItemAcceptor);
|
||||
create_item_acceptor_flex(
|
||||
calling_client,
|
||||
id,
|
||||
|
||||
@@ -47,6 +47,8 @@ pub struct TypeInfo {
|
||||
pub ui: Mutex<Weak<ItemUI>>,
|
||||
pub items: Registry<Item>,
|
||||
pub acceptors: Registry<ItemAcceptor>,
|
||||
pub add_ui_aspect: fn(node: &Node),
|
||||
pub add_acceptor_aspect: fn(node: &Node),
|
||||
pub new_acceptor_fn: fn(node: &Node, acceptor: &Arc<Node>, acceptor_field: &Arc<Node>),
|
||||
}
|
||||
impl Hash for TypeInfo {
|
||||
@@ -81,7 +83,6 @@ impl Item {
|
||||
};
|
||||
let item = type_info.items.add(item);
|
||||
|
||||
<Item as ItemAspect>::add_node_members(node);
|
||||
if let Some(ui) = type_info.ui.lock().upgrade() {
|
||||
ui.handle_create_item(&item);
|
||||
}
|
||||
@@ -109,7 +110,7 @@ impl Item {
|
||||
}
|
||||
}
|
||||
impl Aspect for Item {
|
||||
const NAME: &'static str = "Item";
|
||||
impl_aspect_for_item_aspect! {}
|
||||
}
|
||||
impl ItemAspect for Item {
|
||||
fn release(node: Arc<Node>, _calling_client: Arc<Client>) -> Result<()> {
|
||||
@@ -285,7 +286,7 @@ impl ItemUI {
|
||||
}
|
||||
}
|
||||
impl Aspect for ItemUI {
|
||||
const NAME: &'static str = "Item";
|
||||
impl_aspect_for_item_ui_aspect! {}
|
||||
}
|
||||
impl Drop for ItemUI {
|
||||
fn drop(&mut self) {
|
||||
@@ -343,7 +344,7 @@ impl ItemAcceptor {
|
||||
}
|
||||
}
|
||||
impl Aspect for ItemAcceptor {
|
||||
const NAME: &'static str = "ItemAcceptor";
|
||||
impl_aspect_for_item_acceptor_aspect! {}
|
||||
}
|
||||
impl ItemAcceptorAspect for ItemAcceptor {}
|
||||
impl Drop for ItemAcceptor {
|
||||
@@ -364,6 +365,7 @@ pub fn register_item_ui_flex(
|
||||
) -> Result<()> {
|
||||
let ui = Node::from_id(&calling_client, type_info.ui_node_id, true).add_to_scenegraph()?;
|
||||
ItemUI::add_to(&ui, type_info)?;
|
||||
(type_info.add_ui_aspect)(&ui);
|
||||
Ok(())
|
||||
}
|
||||
fn create_item_acceptor_flex(
|
||||
@@ -381,6 +383,7 @@ fn create_item_acceptor_flex(
|
||||
let node = Node::from_id(&calling_client, id, true).add_to_scenegraph()?;
|
||||
Spatial::add_to(&node, Some(space.clone()), transform, false);
|
||||
ItemAcceptor::add_to(&node, type_info, field);
|
||||
(type_info.add_acceptor_aspect)(&node);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -391,6 +394,3 @@ fn acceptor_capture_item_flex(node: Arc<Node>, item: Arc<Node>) -> Result<()> {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
struct ItemInterface;
|
||||
// create_interface!(ItemInterface);
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
use super::{create_item_acceptor_flex, register_item_ui_flex, ItemAcceptor, ItemInterface};
|
||||
use super::camera::CameraItemAcceptor;
|
||||
use super::{create_item_acceptor_flex, register_item_ui_flex};
|
||||
use crate::nodes::items::ITEM_ACCEPTOR_ASPECT_ALIAS_INFO;
|
||||
use crate::nodes::items::ITEM_ASPECT_ALIAS_INFO;
|
||||
use crate::nodes::Aspect;
|
||||
use crate::{
|
||||
core::{
|
||||
client::{get_env, state, Client, INTERNAL_CLIENT},
|
||||
registry::Registry,
|
||||
},
|
||||
create_interface,
|
||||
nodes::{
|
||||
drawable::model::ModelPart,
|
||||
items::{Item, ItemType, TypeInfo},
|
||||
@@ -39,6 +40,12 @@ lazy_static! {
|
||||
ui: Default::default(),
|
||||
items: Registry::new(),
|
||||
acceptors: Registry::new(),
|
||||
add_acceptor_aspect: |node| {
|
||||
node.add_aspect(PanelItemUi);
|
||||
},
|
||||
add_ui_aspect: |node| {
|
||||
node.add_aspect(PanelItemAcceptor);
|
||||
},
|
||||
new_acceptor_fn: |node, acceptor, acceptor_field| {
|
||||
let _ = panel_item_ui_client::create_acceptor(node, acceptor, acceptor_field);
|
||||
}
|
||||
@@ -115,7 +122,6 @@ impl<B: Backend> PanelItem<B> {
|
||||
&ITEM_TYPE_INFO_PANEL,
|
||||
ItemType::Panel(generic_panel_item),
|
||||
);
|
||||
<Self as PanelItemAspect>::add_node_members(&node);
|
||||
|
||||
(node, panel_item)
|
||||
}
|
||||
@@ -198,8 +204,9 @@ impl<B: Backend> PanelItem<B> {
|
||||
}
|
||||
}
|
||||
|
||||
// make these stupid vectors u32 in the protocol somehow!!!!!!!1
|
||||
|
||||
impl<B: Backend> Aspect for PanelItem<B> {
|
||||
impl_aspect_for_panel_item_aspect! {}
|
||||
}
|
||||
#[allow(unused)]
|
||||
impl<B: Backend> PanelItemAspect for PanelItem<B> {
|
||||
#[doc = "Apply the cursor as a material to a model."]
|
||||
@@ -405,7 +412,17 @@ impl<B: Backend> PanelItemAspect for PanelItem<B> {
|
||||
}
|
||||
}
|
||||
|
||||
impl PanelItemAcceptorAspect for ItemAcceptor {
|
||||
pub struct PanelItemUi;
|
||||
impl Aspect for PanelItemUi {
|
||||
impl_aspect_for_panel_item_ui_aspect! {}
|
||||
}
|
||||
impl PanelItemUiAspect for PanelItemUi {}
|
||||
|
||||
pub struct PanelItemAcceptor;
|
||||
impl Aspect for PanelItemAcceptor {
|
||||
impl_aspect_for_panel_item_acceptor_aspect! {}
|
||||
}
|
||||
impl PanelItemAcceptorAspect for PanelItemAcceptor {
|
||||
fn capture_item(node: Arc<Node>, _calling_client: Arc<Client>, item: Arc<Node>) -> Result<()> {
|
||||
super::acceptor_capture_item_flex(node, item)
|
||||
}
|
||||
@@ -435,22 +452,23 @@ impl<B: Backend> Drop for PanelItem<B> {
|
||||
}
|
||||
}
|
||||
|
||||
create_interface!(ItemInterface);
|
||||
impl InterfaceAspect for ItemInterface {
|
||||
impl InterfaceAspect for Interface {
|
||||
#[doc = "Register this client to manage the items of a certain type and create default 3D UI for them."]
|
||||
fn register_panel_item_ui(_node: Arc<Node>, calling_client: Arc<Client>) -> Result<()> {
|
||||
fn register_panel_item_ui(node: Arc<Node>, calling_client: Arc<Client>) -> Result<()> {
|
||||
node.add_aspect(CameraItemAcceptor);
|
||||
register_item_ui_flex(calling_client, &ITEM_TYPE_INFO_PANEL)
|
||||
}
|
||||
|
||||
#[doc = "Create an item acceptor to allow temporary ownership of a given type of item. Creates a node at `/item/<item_type>/acceptor/<name>`."]
|
||||
fn create_panel_item_acceptor(
|
||||
_node: Arc<Node>,
|
||||
node: Arc<Node>,
|
||||
calling_client: Arc<Client>,
|
||||
id: u64,
|
||||
parent: Arc<Node>,
|
||||
transform: Transform,
|
||||
field: Arc<Node>,
|
||||
) -> Result<()> {
|
||||
node.add_aspect(PanelItemAcceptor);
|
||||
create_item_acceptor_flex(
|
||||
calling_client,
|
||||
id,
|
||||
|
||||
129
src/nodes/mod.rs
129
src/nodes/mod.rs
@@ -21,7 +21,7 @@ use spatial::Spatial;
|
||||
use stardust_xr::messenger::MessageSenderHandle;
|
||||
use stardust_xr::scenegraph::ScenegraphError;
|
||||
use stardust_xr::schemas::flex::{deserialize, serialize};
|
||||
use std::any::{Any, TypeId};
|
||||
use std::any::Any;
|
||||
use std::fmt::Debug;
|
||||
use std::os::fd::OwnedFd;
|
||||
use std::sync::{Arc, Weak};
|
||||
@@ -46,11 +46,26 @@ impl AsRef<[u8]> for Message {
|
||||
}
|
||||
}
|
||||
|
||||
pub type Signal = fn(Arc<Node>, Arc<Client>, Message) -> Result<()>;
|
||||
pub type Method = fn(Arc<Node>, Arc<Client>, Message, MethodResponseSender);
|
||||
|
||||
stardust_xr_server_codegen::codegen_node_protocol!();
|
||||
|
||||
pub struct Owned;
|
||||
impl Aspect for Owned {
|
||||
impl_aspect_for_owned_aspect! {}
|
||||
}
|
||||
impl OwnedAspect for Owned {
|
||||
fn set_enabled(node: Arc<Node>, _calling_client: Arc<Client>, enabled: bool) -> Result<()> {
|
||||
node.set_enabled(enabled);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn destroy(node: Arc<Node>, _calling_client: Arc<Client>) -> Result<()> {
|
||||
if node.destroyable {
|
||||
node.destroy();
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub struct OwnedNode(pub Arc<Node>);
|
||||
impl Drop for OwnedNode {
|
||||
fn drop(&mut self) {
|
||||
@@ -64,8 +79,6 @@ pub struct Node {
|
||||
client: Weak<Client>,
|
||||
message_sender_handle: Option<MessageSenderHandle>,
|
||||
|
||||
local_signals: Mutex<FxHashMap<u64, Signal>>,
|
||||
local_methods: Mutex<FxHashMap<u64, Method>>,
|
||||
aliases: Registry<Alias>,
|
||||
aspects: Aspects,
|
||||
destroyable: bool,
|
||||
@@ -87,13 +100,11 @@ impl Node {
|
||||
client: Arc::downgrade(client),
|
||||
message_sender_handle: client.message_sender_handle.clone(),
|
||||
id,
|
||||
local_signals: Default::default(),
|
||||
local_methods: Default::default(),
|
||||
aliases: Default::default(),
|
||||
aspects: Default::default(),
|
||||
destroyable,
|
||||
};
|
||||
<Node as OwnedAspect>::add_node_members(&node);
|
||||
node.aspects.add(Owned);
|
||||
node
|
||||
}
|
||||
pub fn add_to_scenegraph(self) -> Result<Arc<Node>> {
|
||||
@@ -146,13 +157,6 @@ impl Node {
|
||||
// Ok(serialize(pid)?.into())
|
||||
// }
|
||||
|
||||
pub fn add_local_signal(&self, id: u64, signal: Signal) {
|
||||
self.local_signals.lock().insert(id, signal);
|
||||
}
|
||||
pub fn add_local_method(&self, id: u64, method: Method) {
|
||||
self.local_methods.lock().insert(id, method);
|
||||
}
|
||||
|
||||
pub fn add_aspect<A: Aspect>(&self, aspect: A) -> Arc<A> {
|
||||
self.aspects.add(aspect)
|
||||
}
|
||||
@@ -166,6 +170,7 @@ impl Node {
|
||||
pub fn send_local_signal(
|
||||
self: Arc<Self>,
|
||||
calling_client: Arc<Client>,
|
||||
aspect_id: u64,
|
||||
method: u64,
|
||||
message: Message,
|
||||
) -> Result<(), ScenegraphError> {
|
||||
@@ -177,22 +182,26 @@ impl Node {
|
||||
.original
|
||||
.upgrade()
|
||||
.ok_or(ScenegraphError::BrokenAlias)?
|
||||
.send_local_signal(calling_client, method, message)
|
||||
.send_local_signal(calling_client, aspect_id, method, message)
|
||||
} else {
|
||||
let signal = self
|
||||
.local_signals
|
||||
let aspect = self
|
||||
.aspects
|
||||
.0
|
||||
.lock()
|
||||
.get(&method)
|
||||
.cloned()
|
||||
.ok_or(ScenegraphError::SignalNotFound)?;
|
||||
signal(self, calling_client, message).map_err(|error| ScenegraphError::SignalError {
|
||||
error: error.to_string(),
|
||||
})
|
||||
.get(&aspect_id)
|
||||
.ok_or(ScenegraphError::AspectNotFound)?
|
||||
.clone();
|
||||
aspect
|
||||
.run_signal(calling_client, self.clone(), method, message)
|
||||
.map_err(|error| ScenegraphError::SignalError {
|
||||
error: error.to_string(),
|
||||
})
|
||||
}
|
||||
}
|
||||
pub fn execute_local_method(
|
||||
self: Arc<Self>,
|
||||
calling_client: Arc<Client>,
|
||||
aspect_id: u64,
|
||||
method: u64,
|
||||
message: Message,
|
||||
response: MethodResponseSender,
|
||||
@@ -208,6 +217,7 @@ impl Node {
|
||||
};
|
||||
alias.execute_local_method(
|
||||
calling_client,
|
||||
aspect_id,
|
||||
method,
|
||||
Message {
|
||||
data: message.data.clone(),
|
||||
@@ -216,14 +226,19 @@ impl Node {
|
||||
response,
|
||||
)
|
||||
} else {
|
||||
let Some(method) = self.local_methods.lock().get(&method).cloned() else {
|
||||
response.send(Err(ScenegraphError::MethodNotFound));
|
||||
let Some(aspect) = self.aspects.0.lock().get(&aspect_id).cloned() else {
|
||||
response.send(Err(ScenegraphError::AspectNotFound));
|
||||
return;
|
||||
};
|
||||
method(self, calling_client, message, response);
|
||||
aspect.run_method(calling_client, self.clone(), method, message, response);
|
||||
}
|
||||
}
|
||||
pub fn send_remote_signal(&self, method: u64, message: impl Into<Message>) -> Result<()> {
|
||||
pub fn send_remote_signal(
|
||||
&self,
|
||||
aspect_id: u64,
|
||||
method: u64,
|
||||
message: impl Into<Message>,
|
||||
) -> Result<()> {
|
||||
let message = message.into();
|
||||
self.aliases
|
||||
.get_valid_contents()
|
||||
@@ -233,6 +248,7 @@ impl Node {
|
||||
.for_each(|node| {
|
||||
// Beware! file descriptors will not be sent to aliases!!!
|
||||
let _ = node.send_remote_signal(
|
||||
aspect_id,
|
||||
method,
|
||||
Message {
|
||||
data: message.data.clone(),
|
||||
@@ -241,12 +257,13 @@ impl Node {
|
||||
);
|
||||
});
|
||||
if let Some(handle) = self.message_sender_handle.as_ref() {
|
||||
handle.signal(self.id, method, &message.data, message.fds)?;
|
||||
handle.signal(self.id, aspect_id, method, &message.data, message.fds)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
pub async fn execute_remote_method_typed<S: Serialize, D: DeserializeOwned>(
|
||||
&self,
|
||||
aspect_id: u64,
|
||||
method: u64,
|
||||
input: S,
|
||||
fds: Vec<OwnedFd>,
|
||||
@@ -258,7 +275,7 @@ impl Node {
|
||||
|
||||
let serialized = serialize(input)?;
|
||||
let result = message_sender_handle
|
||||
.method(self.id, method, &serialized, fds)?
|
||||
.method(self.id, aspect_id, method, &serialized, fds)?
|
||||
.await
|
||||
.map_err(|e| eyre!(e))?;
|
||||
|
||||
@@ -271,25 +288,10 @@ impl Debug for Node {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_struct("Node")
|
||||
.field("id", &self.id)
|
||||
.field("local_signals", &self.local_signals.lock().keys())
|
||||
.field("local_methods", &self.local_methods.lock().keys())
|
||||
.field("destroyable", &self.destroyable)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
impl OwnedAspect for Node {
|
||||
fn set_enabled(node: Arc<Node>, _calling_client: Arc<Client>, enabled: bool) -> Result<()> {
|
||||
node.set_enabled(enabled);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn destroy(node: Arc<Node>, _calling_client: Arc<Client>) -> Result<()> {
|
||||
if node.destroyable {
|
||||
node.destroy();
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
impl Drop for Node {
|
||||
fn drop(&mut self) {
|
||||
// Debug breakpoint
|
||||
@@ -297,12 +299,28 @@ impl Drop for Node {
|
||||
}
|
||||
|
||||
pub trait Aspect: Any + Send + Sync + 'static {
|
||||
const NAME: &'static str;
|
||||
fn name(&self) -> String;
|
||||
fn id(&self) -> u64;
|
||||
fn as_any(self: Arc<Self>) -> Arc<dyn Any + Send + Sync + 'static>;
|
||||
fn run_signal(
|
||||
&self,
|
||||
calling_client: Arc<Client>,
|
||||
node: Arc<Node>,
|
||||
signal: u64,
|
||||
message: Message,
|
||||
) -> Result<(), stardust_xr::scenegraph::ScenegraphError>;
|
||||
fn run_method(
|
||||
&self,
|
||||
calling_client: Arc<Client>,
|
||||
node: Arc<Node>,
|
||||
method: u64,
|
||||
message: Message,
|
||||
response: MethodResponseSender,
|
||||
);
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct Aspects(Mutex<FxHashMap<TypeId, Arc<dyn Any + Send + Sync + 'static>>>);
|
||||
|
||||
struct Aspects(Mutex<FxHashMap<u64, Arc<dyn Aspect>>>);
|
||||
impl Aspects {
|
||||
fn add<A: Aspect>(&self, t: A) -> Arc<A> {
|
||||
let aspect = Arc::new(t);
|
||||
@@ -310,18 +328,15 @@ impl Aspects {
|
||||
aspect
|
||||
}
|
||||
fn add_raw<A: Aspect>(&self, aspect: Arc<A>) {
|
||||
self.0.lock().insert(Self::type_key::<A>(), aspect);
|
||||
let id = aspect.id();
|
||||
self.0.lock().insert(id, aspect);
|
||||
}
|
||||
fn get<A: Aspect>(&self) -> Result<Arc<A>> {
|
||||
self.0
|
||||
.lock()
|
||||
.get(&Self::type_key::<A>())
|
||||
.and_then(|a| Arc::downcast(a.clone()).ok())
|
||||
.ok_or(eyre!("Couldn't get aspect {}", A::NAME.to_lowercase()))
|
||||
}
|
||||
|
||||
fn type_key<A: 'static>() -> TypeId {
|
||||
TypeId::of::<A>()
|
||||
.values()
|
||||
.find_map(|a| Arc::downcast(a.clone().as_any()).ok())
|
||||
.ok_or(eyre!("Couldn't get aspect"))
|
||||
}
|
||||
}
|
||||
impl Drop for Aspects {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use super::spatial::Spatial;
|
||||
use super::Node;
|
||||
use super::{Aspect, Node};
|
||||
use crate::core::client::Client;
|
||||
use crate::core::client_state::ClientStateParsed;
|
||||
use crate::core::registry::Registry;
|
||||
@@ -23,14 +23,14 @@ pub struct Root {
|
||||
impl Root {
|
||||
pub fn create(client: &Arc<Client>, transform: Mat4) -> Result<Arc<Self>> {
|
||||
let node = Node::from_id(client, 0, false);
|
||||
<Self as RootAspect>::add_node_members(&node);
|
||||
let node = node.add_to_scenegraph()?;
|
||||
let _ = Spatial::add_to(&node, None, transform, false);
|
||||
|
||||
Ok(ROOT_REGISTRY.add(Root {
|
||||
node,
|
||||
let root_aspect = node.add_aspect(Root {
|
||||
node: node.clone(),
|
||||
connect_instant: Instant::now(),
|
||||
}))
|
||||
});
|
||||
ROOT_REGISTRY.add_raw(&root_aspect);
|
||||
Ok(root_aspect)
|
||||
}
|
||||
|
||||
pub fn send_frame_events(delta: f64) {
|
||||
@@ -54,6 +54,9 @@ impl Root {
|
||||
Ok(root_client::save_state(&self.node).await?.0)
|
||||
}
|
||||
}
|
||||
impl Aspect for Root {
|
||||
impl_aspect_for_root_aspect! {}
|
||||
}
|
||||
impl RootAspect for Root {
|
||||
async fn get_state(_node: Arc<Node>, calling_client: Arc<Client>) -> Result<ClientState> {
|
||||
let Some(state) = calling_client.state.get() else {
|
||||
|
||||
@@ -6,7 +6,6 @@ use super::fields::{Field, FieldTrait};
|
||||
use super::Aspect;
|
||||
use crate::core::client::Client;
|
||||
use crate::core::registry::Registry;
|
||||
use crate::create_interface;
|
||||
use crate::nodes::{Node, OWNED_ASPECT_ALIAS_INFO};
|
||||
use color_eyre::eyre::{eyre, OptionExt, Result};
|
||||
use glam::{vec3a, Mat4, Quat, Vec3};
|
||||
@@ -38,6 +37,9 @@ impl Transform {
|
||||
Mat4::from_scale_rotation_translation(scale.into(), rotation.into(), position.into())
|
||||
}
|
||||
}
|
||||
impl Aspect for Zone {
|
||||
impl_aspect_for_zone_aspect! {}
|
||||
}
|
||||
|
||||
lazy_static::lazy_static! {
|
||||
pub static ref EXPORTED_SPATIALS: Mutex<FxHashMap<u64, Arc<Node>>> = Mutex::new(FxHashMap::default());
|
||||
@@ -74,16 +76,14 @@ impl Spatial {
|
||||
zoneable: bool,
|
||||
) -> Arc<Spatial> {
|
||||
let spatial = Spatial::new(Arc::downgrade(node), parent.clone(), transform);
|
||||
<Spatial as SpatialAspect>::add_node_members(node);
|
||||
if zoneable {
|
||||
ZONEABLE_REGISTRY.add_raw(&spatial);
|
||||
}
|
||||
if let Some(parent) = parent {
|
||||
parent.children.add_raw(&spatial);
|
||||
}
|
||||
<Spatial as SpatialRefAspect>::add_node_members(node);
|
||||
<Spatial as SpatialAspect>::add_node_members(node);
|
||||
node.add_aspect_raw(spatial.clone());
|
||||
node.add_aspect(SpatialRef);
|
||||
spatial
|
||||
}
|
||||
|
||||
@@ -242,66 +242,7 @@ impl Spatial {
|
||||
}
|
||||
}
|
||||
impl Aspect for Spatial {
|
||||
const NAME: &'static str = "Spatial";
|
||||
}
|
||||
impl SpatialRefAspect for Spatial {
|
||||
async fn get_local_bounding_box(
|
||||
node: Arc<Node>,
|
||||
_calling_client: Arc<Client>,
|
||||
) -> Result<BoundingBox> {
|
||||
let this_spatial = node.get_aspect::<Spatial>()?;
|
||||
let bounds = this_spatial.get_bounding_box();
|
||||
|
||||
Ok(BoundingBox {
|
||||
center: Vec3::from(bounds.center).into(),
|
||||
size: Vec3::from(bounds.dimensions).into(),
|
||||
})
|
||||
}
|
||||
|
||||
async fn get_relative_bounding_box(
|
||||
node: Arc<Node>,
|
||||
_calling_client: Arc<Client>,
|
||||
relative_to: Arc<Node>,
|
||||
) -> Result<BoundingBox> {
|
||||
let this_spatial = node.get_aspect::<Spatial>()?;
|
||||
let relative_spatial = relative_to.get_aspect::<Spatial>()?;
|
||||
let center = Spatial::space_to_space_matrix(Some(&this_spatial), Some(&relative_spatial))
|
||||
.transform_point3([0.0; 3].into());
|
||||
let mut bounds = Bounds {
|
||||
center: center.into(),
|
||||
dimensions: [0.0; 3].into(),
|
||||
};
|
||||
bounds.grown_box(
|
||||
this_spatial.get_bounding_box(),
|
||||
Spatial::space_to_space_matrix(Some(&this_spatial), Some(&relative_spatial)),
|
||||
);
|
||||
|
||||
Ok(BoundingBox {
|
||||
center: Vec3::from(bounds.center).into(),
|
||||
size: Vec3::from(bounds.dimensions).into(),
|
||||
})
|
||||
}
|
||||
|
||||
async fn get_transform(
|
||||
node: Arc<Node>,
|
||||
_calling_client: Arc<Client>,
|
||||
relative_to: Arc<Node>,
|
||||
) -> Result<Transform> {
|
||||
let this_spatial = node.get_aspect::<Spatial>()?;
|
||||
let relative_spatial = relative_to.get_aspect::<Spatial>()?;
|
||||
|
||||
let (scale, rotation, position) = Spatial::space_to_space_matrix(
|
||||
Some(this_spatial.as_ref()),
|
||||
Some(relative_spatial.as_ref()),
|
||||
)
|
||||
.to_scale_rotation_translation();
|
||||
|
||||
Ok(Transform {
|
||||
translation: Some(position.into()),
|
||||
rotation: Some(rotation.into()),
|
||||
scale: Some(scale.into()),
|
||||
})
|
||||
}
|
||||
impl_aspect_for_spatial_aspect! {}
|
||||
}
|
||||
impl SpatialAspect for Spatial {
|
||||
fn set_local_transform(
|
||||
@@ -389,6 +330,70 @@ impl Drop for Spatial {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SpatialRef;
|
||||
impl Aspect for SpatialRef {
|
||||
impl_aspect_for_spatial_ref_aspect! {}
|
||||
}
|
||||
impl SpatialRefAspect for SpatialRef {
|
||||
async fn get_local_bounding_box(
|
||||
node: Arc<Node>,
|
||||
_calling_client: Arc<Client>,
|
||||
) -> Result<BoundingBox> {
|
||||
let this_spatial = node.get_aspect::<Spatial>()?;
|
||||
let bounds = this_spatial.get_bounding_box();
|
||||
|
||||
Ok(BoundingBox {
|
||||
center: Vec3::from(bounds.center).into(),
|
||||
size: Vec3::from(bounds.dimensions).into(),
|
||||
})
|
||||
}
|
||||
|
||||
async fn get_relative_bounding_box(
|
||||
node: Arc<Node>,
|
||||
_calling_client: Arc<Client>,
|
||||
relative_to: Arc<Node>,
|
||||
) -> Result<BoundingBox> {
|
||||
let this_spatial = node.get_aspect::<Spatial>()?;
|
||||
let relative_spatial = relative_to.get_aspect::<Spatial>()?;
|
||||
let center = Spatial::space_to_space_matrix(Some(&this_spatial), Some(&relative_spatial))
|
||||
.transform_point3([0.0; 3].into());
|
||||
let mut bounds = Bounds {
|
||||
center: center.into(),
|
||||
dimensions: [0.0; 3].into(),
|
||||
};
|
||||
bounds.grown_box(
|
||||
this_spatial.get_bounding_box(),
|
||||
Spatial::space_to_space_matrix(Some(&this_spatial), Some(&relative_spatial)),
|
||||
);
|
||||
|
||||
Ok(BoundingBox {
|
||||
center: Vec3::from(bounds.center).into(),
|
||||
size: Vec3::from(bounds.dimensions).into(),
|
||||
})
|
||||
}
|
||||
|
||||
async fn get_transform(
|
||||
node: Arc<Node>,
|
||||
_calling_client: Arc<Client>,
|
||||
relative_to: Arc<Node>,
|
||||
) -> Result<Transform> {
|
||||
let this_spatial = node.get_aspect::<Spatial>()?;
|
||||
let relative_spatial = relative_to.get_aspect::<Spatial>()?;
|
||||
|
||||
let (scale, rotation, position) = Spatial::space_to_space_matrix(
|
||||
Some(this_spatial.as_ref()),
|
||||
Some(relative_spatial.as_ref()),
|
||||
)
|
||||
.to_scale_rotation_translation();
|
||||
|
||||
Ok(Transform {
|
||||
translation: Some(position.into()),
|
||||
rotation: Some(rotation.into()),
|
||||
scale: Some(scale.into()),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse_transform(transform: Transform, position: bool, rotation: bool, scale: bool) -> Mat4 {
|
||||
let position = position
|
||||
.then_some(transform.translation)
|
||||
@@ -406,8 +411,7 @@ pub fn parse_transform(transform: Transform, position: bool, rotation: bool, sca
|
||||
Mat4::from_scale_rotation_translation(scale.into(), rotation.into(), position.into())
|
||||
}
|
||||
|
||||
pub struct SpatialInterface;
|
||||
impl InterfaceAspect for SpatialInterface {
|
||||
impl InterfaceAspect for Interface {
|
||||
fn create_spatial(
|
||||
_node: Arc<Node>,
|
||||
calling_client: Arc<Client>,
|
||||
@@ -460,5 +464,3 @@ impl InterfaceAspect for SpatialInterface {
|
||||
.ok_or_eyre("Couldn't find spatial with that ID")
|
||||
}
|
||||
}
|
||||
|
||||
create_interface!(SpatialInterface);
|
||||
|
||||
@@ -7,7 +7,7 @@ use crate::{
|
||||
nodes::{
|
||||
alias::{get_original, Alias, AliasList},
|
||||
fields::{Field, FieldTrait},
|
||||
Aspect, Node,
|
||||
Node,
|
||||
},
|
||||
};
|
||||
use color_eyre::eyre::Result;
|
||||
@@ -73,7 +73,6 @@ impl Zone {
|
||||
intersecting: AliasList::default(),
|
||||
captured: AliasList::default(),
|
||||
});
|
||||
<Zone as ZoneAspect>::add_node_members(node);
|
||||
node.add_aspect_raw(zone.clone());
|
||||
zone
|
||||
}
|
||||
@@ -124,9 +123,6 @@ impl Zone {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
impl Aspect for Zone {
|
||||
const NAME: &'static str = "Zone";
|
||||
}
|
||||
impl ZoneAspect for Zone {
|
||||
fn update(node: Arc<Node>, _calling_client: Arc<Client>) -> Result<()> {
|
||||
let zone = node.get_aspect::<Zone>()?;
|
||||
|
||||
@@ -12,7 +12,6 @@ use color_eyre::eyre::Result;
|
||||
use glam::{Mat4, Quat, Vec3};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use stardust_xr::values::Datamap;
|
||||
use std::f32::INFINITY;
|
||||
use std::sync::Arc;
|
||||
use stereokit_rust::sk::{DisplayMode, MainThreadToken, Sk};
|
||||
use stereokit_rust::system::{HandJoint, HandSource, Handed, Input, LinePoint, Lines};
|
||||
|
||||
@@ -93,7 +93,6 @@ impl Drop for UnownedFd {
|
||||
|
||||
pub struct Wayland {
|
||||
display: Arc<DisplayWrapper>,
|
||||
pub socket_name: Option<String>,
|
||||
join_handle: JoinHandle<Result<()>>,
|
||||
renderer: GlesRenderer,
|
||||
output: Output,
|
||||
@@ -133,7 +132,6 @@ impl Wayland {
|
||||
|
||||
Ok(Wayland {
|
||||
display,
|
||||
socket_name,
|
||||
join_handle,
|
||||
renderer,
|
||||
output,
|
||||
|
||||
Reference in New Issue
Block a user