fix(alias): make output optional
This commit is contained in:
@@ -24,15 +24,22 @@ impl Alias {
|
||||
name: &str,
|
||||
original: &Arc<Node>,
|
||||
info: AliasInfo,
|
||||
) -> Arc<Node> {
|
||||
let node = Node::create(client, parent, name, true).add_to_scenegraph();
|
||||
let alias = Alias {
|
||||
node: Arc::downgrade(&node),
|
||||
original: Arc::downgrade(original),
|
||||
info,
|
||||
};
|
||||
let alias = original.aliases.add(alias);
|
||||
let _ = node.alias.set(alias);
|
||||
node
|
||||
) -> Option<Arc<Node>> {
|
||||
let node_free = client
|
||||
.scenegraph
|
||||
.get_node(&(parent.to_string() + "/" + name))
|
||||
.is_none();
|
||||
|
||||
node_free.then(|| {
|
||||
let node = Node::create(client, parent, name, true).add_to_scenegraph();
|
||||
let alias = Alias {
|
||||
node: Arc::downgrade(&node),
|
||||
original: Arc::downgrade(original),
|
||||
info,
|
||||
};
|
||||
let alias = original.aliases.add(alias);
|
||||
let _ = node.alias.set(alias);
|
||||
node
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,18 +81,9 @@ impl PulseSender {
|
||||
if !mask_matches(&self.mask, &receiver.mask) {
|
||||
return;
|
||||
}
|
||||
let tx_node = match self.node.upgrade() {
|
||||
Some(v) => v,
|
||||
_ => return,
|
||||
};
|
||||
let tx_client = match tx_node.get_client() {
|
||||
Some(v) => v,
|
||||
_ => return,
|
||||
};
|
||||
let rx_node = match receiver.node.upgrade() {
|
||||
Some(v) => v,
|
||||
_ => return,
|
||||
};
|
||||
let Some(tx_node) = self.node.upgrade() else { return };
|
||||
let Some(tx_client) = tx_node.get_client() else { return };
|
||||
let Some(rx_node) = receiver.node.upgrade() else { return };
|
||||
// Receiver itself
|
||||
let rx_alias = Alias::create(
|
||||
&tx_client,
|
||||
@@ -104,22 +95,26 @@ impl PulseSender {
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
self.aliases.add(receiver.uid.clone(), &rx_alias);
|
||||
if let Some(rx_alias) = rx_alias {
|
||||
self.aliases.add(receiver.uid.clone(), &rx_alias);
|
||||
|
||||
if let Some(rx_field_node) = receiver.field.spatial_ref().node.upgrade() {
|
||||
// Receiver's field
|
||||
let rx_field_alias = Alias::create(
|
||||
&tx_client,
|
||||
rx_alias.get_path(),
|
||||
"field",
|
||||
&rx_field_node,
|
||||
AliasInfo {
|
||||
local_methods: vec!["sendData", "getTransform"],
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
self.aliases
|
||||
.add(receiver.uid.clone() + "-field", &rx_field_alias);
|
||||
if let Some(rx_field_node) = receiver.field.spatial_ref().node.upgrade() {
|
||||
// Receiver's field
|
||||
let rx_field_alias = Alias::create(
|
||||
&tx_client,
|
||||
rx_alias.get_path(),
|
||||
"field",
|
||||
&rx_field_node,
|
||||
AliasInfo {
|
||||
local_methods: vec!["sendData", "getTransform"],
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
if let Some(rx_field_alias) = rx_field_alias {
|
||||
self.aliases
|
||||
.add(receiver.uid.clone() + "-field", &rx_field_alias);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
@@ -158,8 +153,7 @@ impl PulseSender {
|
||||
|
||||
fn send_data_flex(node: &Node, calling_client: Arc<Client>, data: &[u8]) -> Result<()> {
|
||||
let info: SendDataInfo = deserialize(data)?;
|
||||
let capture_path = node.path.clone() + "/" + info.uid;
|
||||
let receiver_node = calling_client.get_node("Pulse receiver", &capture_path)?;
|
||||
let receiver_node = calling_client.get_node("Pulse receiver", info.uid)?;
|
||||
let receiver =
|
||||
receiver_node.get_aspect("Pulse Receiver", "pulse receiver", |n| &n.pulse_receiver)?;
|
||||
let receiver_mask = &receiver_node
|
||||
|
||||
@@ -28,7 +28,7 @@ pub fn frame(sk: &StereoKit) {
|
||||
);
|
||||
}
|
||||
|
||||
pub fn make_alias(client: &Arc<Client>) -> Arc<Node> {
|
||||
pub fn make_alias(client: &Arc<Client>) -> Option<Arc<Node>> {
|
||||
Alias::create(
|
||||
client,
|
||||
"",
|
||||
|
||||
@@ -45,12 +45,10 @@ impl EnvironmentItem {
|
||||
}
|
||||
|
||||
fn get_path_flex(node: &Node, _calling_client: Arc<Client>, _data: &[u8]) -> Result<Vec<u8>> {
|
||||
#[allow(unreachable_patterns)]
|
||||
let path: Result<String> = match &node.item.get().unwrap().specialization {
|
||||
ItemType::Environment(env) => Ok(env.path.clone()),
|
||||
_ => Err(anyhow!("")),
|
||||
let ItemType::Environment(environment_item) = &node.item.get().unwrap().specialization else {
|
||||
return Err(anyhow!("Wrong item type?"))
|
||||
};
|
||||
Ok(flexbuffers::singleton(path?.as_str()))
|
||||
Ok(flexbuffers::singleton(environment_item.path.as_str()))
|
||||
}
|
||||
}
|
||||
impl ItemSpecialization for EnvironmentItem {
|
||||
@@ -72,16 +70,16 @@ pub(super) fn create_environment_item_flex(
|
||||
item_data: String,
|
||||
}
|
||||
let info: CreateEnvironmentItemInfo = deserialize(data)?;
|
||||
let parent_name = format!("/item/{}/item/", ITEM_TYPE_INFO_ENVIRONMENT.type_name);
|
||||
let node = Node::create(&INTERNAL_CLIENT, &parent_name, info.name, true);
|
||||
let parent_name = format!("/item/{}/item", ITEM_TYPE_INFO_ENVIRONMENT.type_name);
|
||||
let space = find_spatial_parent(&calling_client, info.parent_path)?;
|
||||
let transform = parse_transform(info.transform, true, true, false)?;
|
||||
let node = node.add_to_scenegraph();
|
||||
|
||||
let node = Node::create(&INTERNAL_CLIENT, &parent_name, info.name, false).add_to_scenegraph();
|
||||
Spatial::add_to(&node, None, transform * space.global_transform(), false)?;
|
||||
EnvironmentItem::add_to(&node, info.item_data);
|
||||
node.item
|
||||
.get()
|
||||
.unwrap()
|
||||
.make_alias(&calling_client, &parent_name);
|
||||
.make_alias_named(&calling_client, &parent_name, info.name);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ use self::environment::{EnvironmentItem, ITEM_TYPE_INFO_ENVIRONMENT};
|
||||
use super::fields::Field;
|
||||
use super::spatial::{find_spatial_parent, parse_transform, Spatial};
|
||||
use super::{Alias, Node};
|
||||
use crate::core::client::{Client, INTERNAL_CLIENT};
|
||||
use crate::core::client::Client;
|
||||
use crate::core::node_collections::LifeLinkedNodeList;
|
||||
use crate::core::registry::Registry;
|
||||
use crate::nodes::alias::AliasInfo;
|
||||
@@ -80,7 +80,7 @@ impl Item {
|
||||
) -> Arc<Self> {
|
||||
let item = Item {
|
||||
node: Arc::downgrade(node),
|
||||
uid: nanoid!(),
|
||||
uid: node.uid.clone(),
|
||||
type_info,
|
||||
captured_acceptor: Default::default(),
|
||||
specialization,
|
||||
@@ -94,11 +94,16 @@ impl Item {
|
||||
let _ = node.item.set(item.clone());
|
||||
item
|
||||
}
|
||||
fn make_alias(&self, client: &Arc<Client>, parent: &str) -> (Arc<Node>, Arc<Alias>) {
|
||||
let node = Alias::create(
|
||||
fn make_alias_named(
|
||||
&self,
|
||||
client: &Arc<Client>,
|
||||
parent: &str,
|
||||
name: &str,
|
||||
) -> Option<Arc<Node>> {
|
||||
Alias::create(
|
||||
client,
|
||||
parent,
|
||||
&self.uid,
|
||||
name,
|
||||
&self.node.upgrade().unwrap(),
|
||||
AliasInfo {
|
||||
local_signals: [
|
||||
@@ -117,9 +122,10 @@ impl Item {
|
||||
]
|
||||
.concat(),
|
||||
},
|
||||
);
|
||||
let alias = node.alias.get().unwrap().clone();
|
||||
(node, alias)
|
||||
)
|
||||
}
|
||||
fn make_alias(&self, client: &Arc<Client>, parent: &str) -> Option<Arc<Node>> {
|
||||
self.make_alias_named(client, parent, &self.uid)
|
||||
}
|
||||
|
||||
fn release_flex(node: &Node, _calling_client: Arc<Client>, _data: &[u8]) -> Result<()> {
|
||||
@@ -196,8 +202,10 @@ impl ItemUI {
|
||||
let Some(node) = self.node.upgrade() else { return };
|
||||
let Some(client) = node.get_client() else { return };
|
||||
|
||||
let (alias_node, _) = item.make_alias(&client, &(node.get_path().to_string() + "/item"));
|
||||
self.aliases.add(Arc::downgrade(&alias_node));
|
||||
if let Some(alias_node) = item.make_alias(&client, &(node.get_path().to_string() + "/item"))
|
||||
{
|
||||
self.aliases.add(Arc::downgrade(&alias_node));
|
||||
}
|
||||
|
||||
let _ = node.send_remote_signal(
|
||||
"create_item",
|
||||
@@ -231,8 +239,12 @@ impl ItemUI {
|
||||
&client,
|
||||
&format!("/item/{}/acceptor", self.type_info.type_name),
|
||||
);
|
||||
self.aliases.add(Arc::downgrade(&alias));
|
||||
self.aliases.add(Arc::downgrade(&field_alias));
|
||||
if let Some(alias) = alias {
|
||||
self.aliases.add(Arc::downgrade(&alias));
|
||||
}
|
||||
if let Some(field_alias) = field_alias {
|
||||
self.aliases.add(Arc::downgrade(&field_alias));
|
||||
}
|
||||
let _ = node.send_remote_signal("create_acceptor", &serialize(&acceptor.uid).unwrap());
|
||||
}
|
||||
fn handle_destroy_acceptor(&self, acceptor: &ItemAcceptor) {
|
||||
@@ -269,7 +281,7 @@ impl ItemAcceptor {
|
||||
}
|
||||
|
||||
fn capture_flex(node: &Node, calling_client: Arc<Client>, data: &[u8]) -> Result<()> {
|
||||
let acceptor = node.get_aspect("Item acceptor", "item acceptor", |n| &n.item_acceptor)?;
|
||||
let acceptor = node.item_acceptor.get().unwrap();
|
||||
let item_path: &str = deserialize(data)?;
|
||||
let item_node = calling_client.get_node("Item", item_path)?;
|
||||
let item = item_node.get_aspect("Item", "item", |n| &n.item)?;
|
||||
@@ -277,7 +289,12 @@ impl ItemAcceptor {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
fn make_aliases(&self, client: &Arc<Client>, parent: &str) -> (Arc<Node>, Arc<Node>) {
|
||||
|
||||
fn make_aliases(
|
||||
&self,
|
||||
client: &Arc<Client>,
|
||||
parent: &str,
|
||||
) -> (Option<Arc<Node>>, Option<Arc<Node>>) {
|
||||
let acceptor_node = &self.node.upgrade().unwrap();
|
||||
let acceptor_alias = Alias::create(
|
||||
client,
|
||||
@@ -289,35 +306,41 @@ impl ItemAcceptor {
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
let acceptor_field_alias = Alias::create(
|
||||
client,
|
||||
acceptor_alias.get_path(),
|
||||
"field",
|
||||
&self.field.spatial_ref().node.upgrade().unwrap(),
|
||||
AliasInfo::default(),
|
||||
);
|
||||
|
||||
let acceptor_field_alias = acceptor_alias.as_ref().and_then(|acceptor_alias| {
|
||||
Alias::create(
|
||||
client,
|
||||
acceptor_alias.get_path(),
|
||||
"field",
|
||||
&self.field.spatial_ref().node.upgrade().unwrap(),
|
||||
AliasInfo::default(),
|
||||
)
|
||||
});
|
||||
|
||||
(acceptor_alias, acceptor_field_alias)
|
||||
}
|
||||
fn send_event(&self, state: &str, name: &str) {
|
||||
fn handle_capture(&self, item: &Arc<Item>) {
|
||||
self.accepted.add_raw(item);
|
||||
let _ = self.node.upgrade().unwrap().send_remote_signal(
|
||||
"capture",
|
||||
&item.specialization.serialize_start_data(&item.uid),
|
||||
);
|
||||
}
|
||||
fn handle_release(&self, item: &Item) {
|
||||
self.accepted.remove(item);
|
||||
let _ = self
|
||||
.node
|
||||
.upgrade()
|
||||
.unwrap()
|
||||
.send_remote_signal(state, flexbuffers::singleton(name).as_slice());
|
||||
}
|
||||
fn handle_capture(&self, item: &Arc<Item>) {
|
||||
self.accepted.add_raw(item);
|
||||
self.send_event("capture", item.uid.as_str());
|
||||
}
|
||||
fn handle_release(&self, item: &Item) {
|
||||
self.accepted.remove(item);
|
||||
self.send_event("release", item.uid.as_str());
|
||||
.send_remote_signal("release", &serialize(&item.uid).unwrap());
|
||||
}
|
||||
}
|
||||
impl Drop for ItemAcceptor {
|
||||
fn drop(&mut self) {
|
||||
self.type_info.acceptors.remove(self);
|
||||
for accepted in self.accepted.get_valid_contents() {
|
||||
release(&accepted);
|
||||
}
|
||||
if let Some(ui) = self.type_info.ui.lock().upgrade() {
|
||||
ui.handle_destroy_acceptor(self);
|
||||
}
|
||||
@@ -372,7 +395,7 @@ fn create_item_acceptor_flex(_node: &Node, calling_client: Arc<Client>, data: &[
|
||||
let type_info = type_info(info.item_type)?;
|
||||
|
||||
let node = Node::create(
|
||||
&INTERNAL_CLIENT,
|
||||
&calling_client,
|
||||
&format!("/item/{}/acceptor", type_info.type_name),
|
||||
info.name,
|
||||
true,
|
||||
|
||||
@@ -68,84 +68,75 @@ impl Zone {
|
||||
}
|
||||
fn capture_flex(node: &Node, calling_client: Arc<Client>, data: &[u8]) -> Result<()> {
|
||||
let zone = node.zone.get().unwrap();
|
||||
let capture_uid: &str = deserialize(data)?;
|
||||
let capture_path = node.path.clone() + "/" + capture_uid;
|
||||
let spatial = find_spatial(&calling_client, "Spatial", &capture_path)?;
|
||||
let capture_path: &str = deserialize(data)?;
|
||||
let spatial = find_spatial(&calling_client, "Spatial", capture_path)?;
|
||||
capture(&spatial, zone);
|
||||
Ok(())
|
||||
}
|
||||
fn release_flex(node: &Node, calling_client: Arc<Client>, data: &[u8]) -> Result<()> {
|
||||
let capture_uid: &str = deserialize(data)?;
|
||||
let capture_path = node.path.clone() + "/" + capture_uid;
|
||||
let spatial = find_spatial(&calling_client, "Spatial", &capture_path)?;
|
||||
fn release_flex(_node: &Node, calling_client: Arc<Client>, data: &[u8]) -> Result<()> {
|
||||
let capture_path: &str = deserialize(data)?;
|
||||
let spatial = find_spatial(&calling_client, "Spatial", capture_path)?;
|
||||
release(&spatial);
|
||||
Ok(())
|
||||
}
|
||||
fn update(node: &Node, _calling_client: Arc<Client>, _data: &[u8]) -> Result<()> {
|
||||
let zone = node.zone.get().unwrap();
|
||||
if let Some(field) = zone.field.upgrade() {
|
||||
if let Some((zone_client, zone_node)) = zone
|
||||
.spatial
|
||||
.node
|
||||
.upgrade()
|
||||
.and_then(|n| n.get_client().zip(Some(n)))
|
||||
{
|
||||
let mut old_zoneables = zone.zoneables.lock();
|
||||
for (_uid, zoneable) in old_zoneables.iter() {
|
||||
zoneable.destroy();
|
||||
}
|
||||
let captured = zone.captured.get_valid_contents();
|
||||
let zoneables = ZONEABLE_REGISTRY
|
||||
.get_valid_contents()
|
||||
.into_iter()
|
||||
.filter(|zoneable| zoneable.node.upgrade().is_some())
|
||||
.filter(|zoneable| {
|
||||
if captured
|
||||
.iter()
|
||||
.any(|captured| Arc::ptr_eq(captured, zoneable))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
let spatial_zone_distance = zoneable.zone_distance();
|
||||
let self_zone_distance = field.distance(zoneable, vec3a(0.0, 0.0, 0.0));
|
||||
self_zone_distance < 0.0 && spatial_zone_distance > self_zone_distance
|
||||
})
|
||||
.map(|zoneable| {
|
||||
let alias = Alias::create(
|
||||
&zone_client,
|
||||
zone_node.get_path(),
|
||||
&zoneable.uid,
|
||||
&zoneable.node.upgrade().unwrap(),
|
||||
AliasInfo {
|
||||
local_signals: vec![
|
||||
"set_transform",
|
||||
"set_spatial_parent",
|
||||
"set_spatial_parent_in_place",
|
||||
],
|
||||
local_methods: vec!["get_transform"],
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
(zoneable.uid.clone(), alias)
|
||||
})
|
||||
.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 left_uid in old_zoneables.keys().filter(|k| !zoneables.contains_key(*k)) {
|
||||
node.send_remote_signal("leave", &serialize(left_uid)?)?;
|
||||
}
|
||||
|
||||
*old_zoneables = zoneables;
|
||||
|
||||
Ok(())
|
||||
} else {
|
||||
Err(anyhow::anyhow!("No client on node?"))
|
||||
}
|
||||
} else {
|
||||
Err(anyhow::anyhow!("Zone's field has been destroyed"))
|
||||
let Some(field) = zone.field.upgrade() else { return Err(anyhow::anyhow!("Zone's field has been destroyed")) };
|
||||
let Some((zone_client, zone_node)) = zone
|
||||
.spatial
|
||||
.node
|
||||
.upgrade()
|
||||
.and_then(|n| n.get_client().zip(Some(n))) else { return Err(anyhow::anyhow!("No client on node?")) };
|
||||
let mut old_zoneables = zone.zoneables.lock();
|
||||
for (_uid, zoneable) in old_zoneables.iter() {
|
||||
zoneable.destroy();
|
||||
}
|
||||
let captured = zone.captured.get_valid_contents();
|
||||
let zoneables = ZONEABLE_REGISTRY
|
||||
.get_valid_contents()
|
||||
.into_iter()
|
||||
.filter(|zoneable| zoneable.node.upgrade().is_some())
|
||||
.filter(|zoneable| {
|
||||
if captured
|
||||
.iter()
|
||||
.any(|captured| Arc::ptr_eq(captured, zoneable))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
let spatial_zone_distance = zoneable.zone_distance();
|
||||
let self_zone_distance = field.distance(zoneable, vec3a(0.0, 0.0, 0.0));
|
||||
self_zone_distance < 0.0 && spatial_zone_distance > self_zone_distance
|
||||
})
|
||||
.filter_map(|zoneable| {
|
||||
let alias = Alias::create(
|
||||
&zone_client,
|
||||
zone_node.get_path(),
|
||||
&zoneable.uid,
|
||||
&zoneable.node.upgrade().unwrap(),
|
||||
AliasInfo {
|
||||
local_signals: vec![
|
||||
"set_transform",
|
||||
"set_spatial_parent",
|
||||
"set_spatial_parent_in_place",
|
||||
],
|
||||
local_methods: vec!["get_transform"],
|
||||
..Default::default()
|
||||
},
|
||||
)?;
|
||||
Some((zoneable.uid.clone(), alias))
|
||||
})
|
||||
.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 left_uid in old_zoneables.keys().filter(|k| !zoneables.contains_key(*k)) {
|
||||
node.send_remote_signal("leave", &serialize(left_uid)?)?;
|
||||
}
|
||||
|
||||
*old_zoneables = zoneables;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
impl Drop for Zone {
|
||||
|
||||
Reference in New Issue
Block a user