diff --git a/src/nodes/core.rs b/src/nodes/core.rs index 5be13cb..80954df 100644 --- a/src/nodes/core.rs +++ b/src/nodes/core.rs @@ -1,9 +1,10 @@ -use super::data::{PulseReceiver, PulseSender}; +use super::data::PulseSender; use super::field::Field; use super::spatial::Spatial; use crate::core::client::Client; use anyhow::{anyhow, Result}; use libstardustxr::scenegraph::ScenegraphError; +use rccell::{RcCell, WeakCell}; use std::rc::{Rc, Weak}; use std::sync::Arc; use std::{collections::HashMap, vec::Vec}; @@ -24,6 +25,7 @@ pub struct Node<'a> { local_methods: HashMap>, destroyable: bool, + alias: Option>, pub spatial: Option>, pub field: Option>, pub pulse_sender: Option>, @@ -56,6 +58,7 @@ impl<'a> Node<'a> { local_methods: Default::default(), destroyable, + alias: None, spatial: None, field: None, pulse_sender: None, @@ -89,11 +92,24 @@ impl<'a> Node<'a> { method: &str, data: &[u8], ) -> Result<(), ScenegraphError> { - let signal = self - .local_signals - .get(method) - .ok_or(ScenegraphError::SignalNotFound)?; - signal(self, calling_client, data).map_err(|error| ScenegraphError::SignalError { error }) + if let Some(alias) = self.alias.as_ref() { + if !alias.signals.contains(&method.to_string()) { + return Err(ScenegraphError::SignalNotFound); + } + alias + .original + .upgrade() + .ok_or_else(|| ScenegraphError::BrokenAlias)? + .borrow() + .send_local_signal(calling_client, method, data) + } else { + let signal = self + .local_signals + .get(method) + .ok_or(ScenegraphError::SignalNotFound)?; + signal(self, calling_client, data) + .map_err(|error| ScenegraphError::SignalError { error }) + } } pub fn execute_local_method( &self, @@ -101,11 +117,24 @@ impl<'a> Node<'a> { method: &str, data: &[u8], ) -> Result, ScenegraphError> { - let method = self - .local_methods - .get(method) - .ok_or(ScenegraphError::MethodNotFound)?; - method(self, calling_client, data).map_err(|error| ScenegraphError::MethodError { error }) + if let Some(alias) = self.alias.as_ref() { + if !alias.methods.contains(&method.to_string()) { + return Err(ScenegraphError::MethodNotFound); + } + alias + .original + .upgrade() + .ok_or_else(|| ScenegraphError::BrokenAlias)? + .borrow() + .execute_local_method(calling_client, method, data) + } else { + let method = self + .local_methods + .get(method) + .ok_or(ScenegraphError::MethodNotFound)?; + method(self, calling_client, data) + .map_err(|error| ScenegraphError::MethodError { error }) + } } pub fn send_remote_signal(&self, method: &str, data: &[u8]) -> Result<()> { self.get_client() @@ -127,3 +156,24 @@ impl<'a> Node<'a> { // .map_err(|_| anyhow!("Unable to write in messenger")) // } } + +struct Alias<'a> { + original: WeakCell>, + + signals: Vec, + methods: Vec, +} +impl<'a> Alias<'a> { + pub fn add_to( + node: &RcCell>, + original: &RcCell>, + signals: Vec, + methods: Vec, + ) { + node.borrow_mut().alias = Some(Alias { + original: original.downgrade(), + signals, + methods, + }); + } +}