refactor(data): switch to using idl
This commit is contained in:
@@ -306,7 +306,7 @@ fn generate_member(member: &Member) -> TokenStream {
|
|||||||
(Side::Server, MemberType::Method) => {
|
(Side::Server, MemberType::Method) => {
|
||||||
quote! {
|
quote! {
|
||||||
#[doc = #description]
|
#[doc = #description]
|
||||||
fn #name(#argument_decls) -> impl std::future::Future<Output = color_eyre::eyre::Result<(#return_type, Vec<std::os::fd::OwnedFd>)>> + Send + 'static;
|
fn #name(#argument_decls) -> impl std::future::Future<Output = color_eyre::eyre::Result<#return_type>> + Send + 'static;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(Side::Server, MemberType::Signal) => {
|
(Side::Server, MemberType::Signal) => {
|
||||||
@@ -375,7 +375,7 @@ fn generate_handler(member: &Member) -> TokenStream {
|
|||||||
node.add_local_method(#member_name, |_node, _calling_client, _message, _method_response| {
|
node.add_local_method(#member_name, |_node, _calling_client, _message, _method_response| {
|
||||||
_method_response.wrap_async(async move {
|
_method_response.wrap_async(async move {
|
||||||
#deserialize
|
#deserialize
|
||||||
Self::#member_name_ident(_node, _calling_client.clone(), #argument_uses).await
|
Ok((Self::#member_name_ident(_node, _calling_client.clone(), #argument_uses).await?, Vec::new()))
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,24 +1,20 @@
|
|||||||
use super::alias::AliasInfo;
|
use super::alias::AliasInfo;
|
||||||
use super::fields::Field;
|
use super::fields::get_field;
|
||||||
use super::spatial::{parse_transform, Spatial};
|
use super::spatial::{get_spatial, parse_transform, Spatial};
|
||||||
use super::{Alias, Message, Node};
|
use super::{Alias, Node};
|
||||||
use crate::core::client::Client;
|
use crate::core::client::Client;
|
||||||
use crate::core::node_collections::LifeLinkedNodeMap;
|
use crate::core::node_collections::LifeLinkedNodeMap;
|
||||||
use crate::core::registry::Registry;
|
use crate::core::registry::Registry;
|
||||||
use crate::core::scenegraph::MethodResponseSender;
|
use crate::create_interface;
|
||||||
use crate::nodes::fields::{find_field, FIELD_ALIAS_INFO};
|
use crate::nodes::fields::FIELD_ALIAS_INFO;
|
||||||
use crate::nodes::spatial::{find_spatial_parent, Transform};
|
use crate::nodes::spatial::Transform;
|
||||||
use color_eyre::eyre::{bail, ensure, eyre, Result};
|
use color_eyre::eyre::{bail, ensure, eyre, Result};
|
||||||
use glam::vec3a;
|
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use mint::{Quaternion, Vector3};
|
|
||||||
use nanoid::nanoid;
|
use nanoid::nanoid;
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use serde::{Deserialize, Serialize};
|
use stardust_xr::schemas::flex::flexbuffers;
|
||||||
use stardust_xr::schemas::flex::{deserialize, flexbuffers, serialize};
|
use stardust_xr::values::Datamap;
|
||||||
|
|
||||||
use std::fmt::Display;
|
|
||||||
use std::sync::{Arc, Weak};
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
@@ -28,11 +24,17 @@ lazy_static! {
|
|||||||
static PULSE_SENDER_REGISTRY: Registry<PulseSender> = Registry::new();
|
static PULSE_SENDER_REGISTRY: Registry<PulseSender> = Registry::new();
|
||||||
pub static PULSE_RECEIVER_REGISTRY: Registry<PulseReceiver> = Registry::new();
|
pub static PULSE_RECEIVER_REGISTRY: Registry<PulseReceiver> = Registry::new();
|
||||||
|
|
||||||
pub fn mask_matches(mask_map_lesser: &Mask, mask_map_greater: &Mask) -> bool {
|
pub fn get_mask(datamap: &Datamap) -> Result<flexbuffers::MapReader<&[u8]>> {
|
||||||
|
flexbuffers::Reader::get_root(datamap.raw().as_slice())
|
||||||
|
.map_err(|_| eyre!("Mask is not a valid flexbuffer"))?
|
||||||
|
.get_map()
|
||||||
|
.map_err(|_| eyre!("Mask is not a valid map"))
|
||||||
|
}
|
||||||
|
pub fn mask_matches(mask_map_lesser: &Datamap, mask_map_greater: &Datamap) -> bool {
|
||||||
(|| -> Result<_> {
|
(|| -> Result<_> {
|
||||||
for key in mask_map_lesser.get_mask()?.iter_keys() {
|
for key in get_mask(mask_map_lesser)?.iter_keys() {
|
||||||
let lesser_key = mask_map_lesser.get_mask()?.index(key)?;
|
let lesser_key = get_mask(mask_map_lesser)?.index(key)?;
|
||||||
let greater_key = mask_map_greater.get_mask()?.index(key)?;
|
let greater_key = get_mask(mask_map_greater)?.index(key)?;
|
||||||
// otherwise zero-length vectors don't count the same as a single type vector
|
// otherwise zero-length vectors don't count the same as a single type vector
|
||||||
if lesser_key.flexbuffer_type().is_heterogenous_vector()
|
if lesser_key.flexbuffer_type().is_heterogenous_vector()
|
||||||
&& lesser_key.as_vector().len() == 0
|
&& lesser_key.as_vector().len() == 0
|
||||||
@@ -51,57 +53,27 @@ pub fn mask_matches(mask_map_lesser: &Mask, mask_map_greater: &Mask) -> bool {
|
|||||||
.is_ok()
|
.is_ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Mask(pub Vec<u8>);
|
stardust_xr_server_codegen::codegen_data_protocol!();
|
||||||
impl Mask {
|
|
||||||
pub fn from_struct<T: Default + Serialize>() -> Self {
|
|
||||||
let mut serializer = flexbuffers::FlexbufferSerializer::new();
|
|
||||||
T::default().serialize(&mut serializer).unwrap();
|
|
||||||
Mask(serializer.take_buffer())
|
|
||||||
}
|
|
||||||
pub fn get_mask(&self) -> Result<flexbuffers::MapReader<&[u8]>> {
|
|
||||||
flexbuffers::Reader::get_root(self.0.as_slice())
|
|
||||||
.map_err(|_| eyre!("Mask is not a valid flexbuffer"))?
|
|
||||||
.get_map()
|
|
||||||
.map_err(|_| eyre!("Mask is not a valid map"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl Display for Mask {
|
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
||||||
flexbuffers::Reader::get_root(self.0.as_slice())
|
|
||||||
.unwrap()
|
|
||||||
.to_string()
|
|
||||||
.fmt(f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
|
||||||
struct SendDataInfo<'a> {
|
|
||||||
uid: &'a str,
|
|
||||||
data: Vec<u8>,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct PulseSender {
|
pub struct PulseSender {
|
||||||
uid: String,
|
|
||||||
node: Weak<Node>,
|
node: Weak<Node>,
|
||||||
pub mask: Mask,
|
pub mask: Datamap,
|
||||||
aliases: LifeLinkedNodeMap<String>,
|
aliases: LifeLinkedNodeMap<String>,
|
||||||
}
|
}
|
||||||
impl PulseSender {
|
impl PulseSender {
|
||||||
pub fn add_to(node: &Arc<Node>, mask: Mask) -> Result<Arc<PulseSender>> {
|
pub fn add_to(node: &Arc<Node>, mask: Datamap) -> Result<Arc<PulseSender>> {
|
||||||
ensure!(
|
ensure!(
|
||||||
node.spatial.get().is_some(),
|
node.spatial.get().is_some(),
|
||||||
"Internal: Node does not have a spatial attached!"
|
"Internal: Node does not have a spatial attached!"
|
||||||
);
|
);
|
||||||
|
|
||||||
let sender = PulseSender {
|
let sender = PulseSender {
|
||||||
uid: nanoid!(),
|
|
||||||
node: Arc::downgrade(node),
|
node: Arc::downgrade(node),
|
||||||
mask,
|
mask,
|
||||||
aliases: LifeLinkedNodeMap::default(),
|
aliases: LifeLinkedNodeMap::default(),
|
||||||
};
|
};
|
||||||
let sender = PULSE_SENDER_REGISTRY.add(sender);
|
let sender = PULSE_SENDER_REGISTRY.add(sender);
|
||||||
let _ = node.pulse_sender.set(sender.clone());
|
let _ = node.pulse_sender.set(sender.clone());
|
||||||
node.add_local_signal("send_data", PulseSender::send_data_flex);
|
|
||||||
for receiver in PULSE_RECEIVER_REGISTRY.get_valid_contents() {
|
for receiver in PULSE_RECEIVER_REGISTRY.get_valid_contents() {
|
||||||
sender.handle_new_receiver(&receiver);
|
sender.handle_new_receiver(&receiver);
|
||||||
}
|
}
|
||||||
@@ -127,54 +99,28 @@ impl PulseSender {
|
|||||||
receiver.uid.as_str(),
|
receiver.uid.as_str(),
|
||||||
&rx_node,
|
&rx_node,
|
||||||
AliasInfo {
|
AliasInfo {
|
||||||
server_methods: vec!["sendData", "getTransform"],
|
server_methods: vec!["send_data"],
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
if let Ok(rx_alias) = rx_alias {
|
let Ok(rx_alias) = rx_alias else { return };
|
||||||
self.aliases.add(receiver.uid.clone(), &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
|
// Receiver's field
|
||||||
let rx_field_alias = Alias::create(
|
let Ok(rx_field_alias) = Alias::create(
|
||||||
&tx_client,
|
&tx_client,
|
||||||
rx_alias.get_path(),
|
rx_alias.get_path(),
|
||||||
"field",
|
"field",
|
||||||
&rx_field_node,
|
&rx_node.pulse_receiver.get().unwrap().field_node,
|
||||||
FIELD_ALIAS_INFO.clone(),
|
FIELD_ALIAS_INFO.clone(),
|
||||||
);
|
) else {
|
||||||
if let Ok(rx_field_alias) = rx_field_alias {
|
return;
|
||||||
|
};
|
||||||
self.aliases
|
self.aliases
|
||||||
.add(receiver.uid.clone() + "-field", &rx_field_alias);
|
.add(receiver.uid.clone() + "-field", &rx_field_alias);
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Serialize)]
|
let _ =
|
||||||
struct NewReceiverInfo<'a> {
|
pulse_sender_client::new_receiver(&tx_node, &receiver.uid, &rx_alias, &rx_field_alias);
|
||||||
uid: &'a str,
|
|
||||||
distance: f32,
|
|
||||||
position: Vector3<f32>,
|
|
||||||
rotation: Quaternion<f32>,
|
|
||||||
}
|
|
||||||
|
|
||||||
let (_, rotation, position) = Spatial::space_to_space_matrix(
|
|
||||||
rx_node.spatial.get().map(|s| s.as_ref()),
|
|
||||||
tx_node.spatial.get().map(|s| s.as_ref()),
|
|
||||||
)
|
|
||||||
.to_scale_rotation_translation();
|
|
||||||
|
|
||||||
let info = NewReceiverInfo {
|
|
||||||
uid: &receiver.uid,
|
|
||||||
distance: receiver
|
|
||||||
.field
|
|
||||||
.distance(tx_node.spatial.get().unwrap(), vec3a(0.0, 0.0, 0.0)),
|
|
||||||
position: position.into(),
|
|
||||||
rotation: rotation.into(),
|
|
||||||
};
|
|
||||||
|
|
||||||
let Ok(data) = serialize(info) else { return };
|
|
||||||
let _ = tx_node.send_remote_signal("new_receiver", data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_drop_receiver(&self, receiver: &PulseReceiver) {
|
fn handle_drop_receiver(&self, receiver: &PulseReceiver) {
|
||||||
@@ -184,36 +130,10 @@ impl PulseSender {
|
|||||||
let Some(tx_node) = self.node.upgrade() else {
|
let Some(tx_node) = self.node.upgrade() else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
let Ok(data) = serialize(&uid) else { return };
|
let _ = pulse_sender_client::drop_receiver(&tx_node, uid);
|
||||||
let _ = tx_node.send_remote_signal("drop_receiver", data);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn send_data_flex(
|
|
||||||
node: Arc<Node>,
|
|
||||||
calling_client: Arc<Client>,
|
|
||||||
message: Message,
|
|
||||||
) -> Result<()> {
|
|
||||||
let info: SendDataInfo = deserialize(message.as_ref())?;
|
|
||||||
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
|
|
||||||
.get_aspect("Pulse receiver", "pulse receiver", |node| {
|
|
||||||
&node.pulse_receiver
|
|
||||||
})?
|
|
||||||
.mask;
|
|
||||||
|
|
||||||
let data_mask = Mask(info.data);
|
|
||||||
data_mask.get_mask()?;
|
|
||||||
ensure!(
|
|
||||||
mask_matches(receiver_mask, &data_mask),
|
|
||||||
"Message ({}) does not contain the same keys as the receiver's mask ({})",
|
|
||||||
data_mask,
|
|
||||||
receiver_mask
|
|
||||||
);
|
|
||||||
receiver.send_data(&node.pulse_sender.get().unwrap().uid, data_mask.0)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl PulseSenderAspect for PulseSender {}
|
||||||
impl Drop for PulseSender {
|
impl Drop for PulseSender {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
PULSE_SENDER_REGISTRY.remove(self);
|
PULSE_SENDER_REGISTRY.remove(self);
|
||||||
@@ -223,11 +143,15 @@ impl Drop for PulseSender {
|
|||||||
pub struct PulseReceiver {
|
pub struct PulseReceiver {
|
||||||
uid: String,
|
uid: String,
|
||||||
pub node: Weak<Node>,
|
pub node: Weak<Node>,
|
||||||
pub field: Arc<Field>,
|
pub field_node: Arc<Node>,
|
||||||
pub mask: Mask,
|
pub mask: Datamap,
|
||||||
}
|
}
|
||||||
impl PulseReceiver {
|
impl PulseReceiver {
|
||||||
pub fn add_to(node: &Arc<Node>, field: Arc<Field>, mask: Mask) -> Result<Arc<PulseReceiver>> {
|
pub fn add_to(
|
||||||
|
node: &Arc<Node>,
|
||||||
|
field_node: Arc<Node>,
|
||||||
|
mask: Datamap,
|
||||||
|
) -> Result<Arc<PulseReceiver>> {
|
||||||
ensure!(
|
ensure!(
|
||||||
node.spatial.get().is_some(),
|
node.spatial.get().is_some(),
|
||||||
"Internal: Node does not have a spatial attached!"
|
"Internal: Node does not have a spatial attached!"
|
||||||
@@ -236,7 +160,7 @@ impl PulseReceiver {
|
|||||||
let receiver = PulseReceiver {
|
let receiver = PulseReceiver {
|
||||||
uid: nanoid!(),
|
uid: nanoid!(),
|
||||||
node: Arc::downgrade(node),
|
node: Arc::downgrade(node),
|
||||||
field,
|
field_node,
|
||||||
mask,
|
mask,
|
||||||
};
|
};
|
||||||
let receiver = PULSE_RECEIVER_REGISTRY.add(receiver);
|
let receiver = PULSE_RECEIVER_REGISTRY.add(receiver);
|
||||||
@@ -247,15 +171,25 @@ impl PulseReceiver {
|
|||||||
let _ = node.pulse_receiver.set(receiver.clone());
|
let _ = node.pulse_receiver.set(receiver.clone());
|
||||||
Ok(receiver)
|
Ok(receiver)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn send_data(&self, uid: &str, data: Vec<u8>) -> Result<()> {
|
|
||||||
if let Some(node) = self.node.upgrade() {
|
|
||||||
node.send_remote_signal("data", serialize(SendDataInfo { uid, data })?)?;
|
|
||||||
}
|
}
|
||||||
|
impl PulseReceiverAspect for PulseReceiver {
|
||||||
|
fn send_data(
|
||||||
|
node: Arc<Node>,
|
||||||
|
_calling_client: Arc<Client>,
|
||||||
|
sender: Arc<Node>,
|
||||||
|
data: Datamap,
|
||||||
|
) -> Result<()> {
|
||||||
|
let this_receiver = node.pulse_receiver.get().unwrap();
|
||||||
|
|
||||||
|
ensure!(
|
||||||
|
mask_matches(&this_receiver.mask, &data),
|
||||||
|
"Message ({data:?}) does not contain the same keys as the receiver's mask ({:?})",
|
||||||
|
this_receiver.mask
|
||||||
|
);
|
||||||
|
pulse_receiver_client::data(&node, &sender.uid, &data)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for PulseReceiver {
|
impl Drop for PulseReceiver {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
PULSE_RECEIVER_REGISTRY.remove(self);
|
PULSE_RECEIVER_REGISTRY.remove(self);
|
||||||
@@ -265,34 +199,26 @@ impl Drop for PulseReceiver {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_interface(client: &Arc<Client>) -> Result<()> {
|
create_interface!(DataInterface, DataInterfaceAspect, "/data");
|
||||||
let node = Node::create_parent_name(client, "", "data", false);
|
struct DataInterface;
|
||||||
node.add_local_signal("create_pulse_sender", create_pulse_sender_flex);
|
impl DataInterfaceAspect for DataInterface {
|
||||||
node.add_local_signal("create_pulse_receiver", create_pulse_receiver_flex);
|
fn create_pulse_sender(
|
||||||
node.add_local_method("register_keymap", register_keymap_flex);
|
|
||||||
node.add_local_method("get_keymap", get_keymap_flex);
|
|
||||||
node.add_to_scenegraph().map(|_| ())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn create_pulse_sender_flex(
|
|
||||||
_node: Arc<Node>,
|
_node: Arc<Node>,
|
||||||
calling_client: Arc<Client>,
|
calling_client: Arc<Client>,
|
||||||
message: Message,
|
name: String,
|
||||||
) -> Result<()> {
|
parent: Arc<Node>,
|
||||||
#[derive(Deserialize)]
|
|
||||||
struct CreatePulseSenderInfo<'a> {
|
|
||||||
name: &'a str,
|
|
||||||
parent_path: &'a str,
|
|
||||||
transform: Transform,
|
transform: Transform,
|
||||||
mask: Vec<u8>,
|
mask: Datamap,
|
||||||
}
|
) -> Result<()> {
|
||||||
let info: CreatePulseSenderInfo = deserialize(message.as_ref())?;
|
get_mask(&mask)?;
|
||||||
let node = Node::create_parent_name(&calling_client, "/data/sender", info.name, true);
|
let node = Node::create_parent_name(
|
||||||
let parent = find_spatial_parent(&calling_client, info.parent_path)?;
|
&calling_client,
|
||||||
let transform = parse_transform(info.transform, true, true, false);
|
Self::CREATE_PULSE_SENDER_PARENT_PATH,
|
||||||
|
&name,
|
||||||
let mask = Mask(info.mask);
|
true,
|
||||||
mask.get_mask()?;
|
);
|
||||||
|
let parent = get_spatial(&parent, "Spatial parent")?;
|
||||||
|
let transform = transform.to_mat4(true, true, false);
|
||||||
|
|
||||||
let node = node.add_to_scenegraph()?;
|
let node = node.add_to_scenegraph()?;
|
||||||
Spatial::add_to(&node, Some(parent), transform, false)?;
|
Spatial::add_to(&node, Some(parent), transform, false)?;
|
||||||
@@ -300,26 +226,25 @@ pub fn create_pulse_sender_flex(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_pulse_receiver_flex(
|
fn create_pulse_receiver(
|
||||||
_node: Arc<Node>,
|
_node: Arc<Node>,
|
||||||
calling_client: Arc<Client>,
|
calling_client: Arc<Client>,
|
||||||
message: Message,
|
name: String,
|
||||||
) -> Result<()> {
|
parent: Arc<Node>,
|
||||||
#[derive(Deserialize)]
|
|
||||||
struct CreatePulseReceiverInfo<'a> {
|
|
||||||
name: &'a str,
|
|
||||||
parent_path: &'a str,
|
|
||||||
transform: Transform,
|
transform: Transform,
|
||||||
field_path: &'a str,
|
field: Arc<Node>,
|
||||||
mask: Vec<u8>,
|
mask: Datamap,
|
||||||
}
|
) -> Result<()> {
|
||||||
let info: CreatePulseReceiverInfo = deserialize(message.as_ref())?;
|
get_mask(&mask)?;
|
||||||
let node = Node::create_parent_name(&calling_client, "/data/receiver", info.name, true);
|
let node = Node::create_parent_name(
|
||||||
let parent = find_spatial_parent(&calling_client, info.parent_path)?;
|
&calling_client,
|
||||||
let transform = parse_transform(info.transform, true, true, false);
|
Self::CREATE_PULSE_RECEIVER_PARENT_PATH,
|
||||||
let field = find_field(&calling_client, info.field_path)?;
|
&name,
|
||||||
let mask = Mask(info.mask);
|
true,
|
||||||
mask.get_mask()?;
|
);
|
||||||
|
let parent = get_spatial(&parent, "Spatial parent")?;
|
||||||
|
let transform = parse_transform(transform, true, true, false);
|
||||||
|
get_field(&field)?;
|
||||||
|
|
||||||
let node = node.add_to_scenegraph()?;
|
let node = node.add_to_scenegraph()?;
|
||||||
Spatial::add_to(&node, Some(parent), transform, false)?;
|
Spatial::add_to(&node, Some(parent), transform, false)?;
|
||||||
@@ -327,14 +252,11 @@ pub fn create_pulse_receiver_flex(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn register_keymap_flex(
|
async fn register_keymap(
|
||||||
_node: Arc<Node>,
|
_node: Arc<Node>,
|
||||||
_calling_client: Arc<Client>,
|
_calling_client: Arc<Client>,
|
||||||
message: Message,
|
keymap: String,
|
||||||
response: MethodResponseSender,
|
) -> Result<String> {
|
||||||
) {
|
|
||||||
response.wrap_sync(move || {
|
|
||||||
let keymap: String = deserialize(message.as_ref())?;
|
|
||||||
let mut keymaps = KEYMAPS.lock();
|
let mut keymaps = KEYMAPS.lock();
|
||||||
if let Some(found_keymap_id) = keymaps
|
if let Some(found_keymap_id) = keymaps
|
||||||
.iter()
|
.iter()
|
||||||
@@ -342,28 +264,25 @@ pub fn register_keymap_flex(
|
|||||||
.map(|(k, _v)| k)
|
.map(|(k, _v)| k)
|
||||||
.last()
|
.last()
|
||||||
{
|
{
|
||||||
return Ok(serialize(found_keymap_id)?.into());
|
return Ok(found_keymap_id.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
let generated_id = nanoid!();
|
let generated_id = nanoid!();
|
||||||
keymaps.insert(generated_id.clone(), keymap);
|
keymaps.insert(generated_id.clone(), keymap);
|
||||||
|
|
||||||
Ok(serialize(generated_id)?.into())
|
Ok(generated_id)
|
||||||
});
|
|
||||||
}
|
}
|
||||||
pub fn get_keymap_flex(
|
|
||||||
|
async fn get_keymap(
|
||||||
_node: Arc<Node>,
|
_node: Arc<Node>,
|
||||||
_calling_client: Arc<Client>,
|
_calling_client: Arc<Client>,
|
||||||
message: Message,
|
keymap_id: String,
|
||||||
response: MethodResponseSender,
|
) -> Result<String> {
|
||||||
) {
|
|
||||||
response.wrap_sync(move || {
|
|
||||||
let keymap_id: &str = deserialize(message.as_ref())?;
|
|
||||||
let keymaps = KEYMAPS.lock();
|
let keymaps = KEYMAPS.lock();
|
||||||
let Some(keymap) = keymaps.get(keymap_id) else {
|
let Some(keymap) = keymaps.get(&keymap_id) else {
|
||||||
bail!("Could not find keymap. Try registering it")
|
bail!("Could not find keymap. Try registering it")
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(serialize(keymap)?.into())
|
Ok(keymap.clone())
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,10 +16,9 @@ use crate::create_interface;
|
|||||||
use crate::nodes::spatial::Transform;
|
use crate::nodes::spatial::Transform;
|
||||||
use color_eyre::eyre::Result;
|
use color_eyre::eyre::Result;
|
||||||
use glam::{vec2, vec3a, Mat4, Vec3, Vec3A};
|
use glam::{vec2, vec3a, Mat4, Vec3, Vec3A};
|
||||||
|
use mint::Vector3;
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
|
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::os::fd::OwnedFd;
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
// TODO: get SDFs working properly with non-uniform scale and so on, output distance relative to the spatial it's compared against
|
// TODO: get SDFs working properly with non-uniform scale and so on, output distance relative to the spatial it's compared against
|
||||||
@@ -108,74 +107,58 @@ pub trait FieldTrait {
|
|||||||
result
|
result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<Fi: FieldTrait> FieldAspect for Fi {
|
impl<Fi: FieldTrait + 'static> FieldAspect for Fi {
|
||||||
fn distance(
|
async fn distance(
|
||||||
node: Arc<Node>,
|
node: Arc<Node>,
|
||||||
_calling_client: Arc<Client>,
|
_calling_client: Arc<Client>,
|
||||||
space: Arc<Node>,
|
space: Arc<Node>,
|
||||||
point: mint::Vector3<f32>,
|
point: mint::Vector3<f32>,
|
||||||
) -> impl std::future::Future<Output = Result<(f32, Vec<OwnedFd>)>> + Send + 'static {
|
) -> Result<f32> {
|
||||||
async move {
|
|
||||||
let reference_space = get_spatial(&space, "Reference space")?;
|
let reference_space = get_spatial(&space, "Reference space")?;
|
||||||
let this_field = node.field.get().unwrap();
|
let this_field = node.field.get().unwrap();
|
||||||
|
Ok(this_field.distance(reference_space.as_ref(), point.into()))
|
||||||
let distance = this_field.distance(reference_space.as_ref(), point.into());
|
|
||||||
Ok((distance, Vec::new()))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn normal(
|
async fn normal(
|
||||||
node: Arc<Node>,
|
node: Arc<Node>,
|
||||||
_calling_client: Arc<Client>,
|
_calling_client: Arc<Client>,
|
||||||
space: Arc<Node>,
|
space: Arc<Node>,
|
||||||
point: mint::Vector3<f32>,
|
point: mint::Vector3<f32>,
|
||||||
) -> impl std::future::Future<Output = Result<(mint::Vector3<f32>, Vec<OwnedFd>)>> + Send + 'static
|
) -> Result<Vector3<f32>> {
|
||||||
{
|
|
||||||
async move {
|
|
||||||
let reference_space = get_spatial(&space, "Reference space")?;
|
let reference_space = get_spatial(&space, "Reference space")?;
|
||||||
let this_field = node.field.get().unwrap();
|
let this_field = node.field.get().unwrap();
|
||||||
|
Ok(this_field
|
||||||
let normal = this_field.normal(reference_space.as_ref(), point.into(), 0.001);
|
.normal(reference_space.as_ref(), point.into(), 0.001)
|
||||||
Ok((normal.into(), Vec::new()))
|
.into())
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn closest_point(
|
async fn closest_point(
|
||||||
node: Arc<Node>,
|
node: Arc<Node>,
|
||||||
_calling_client: Arc<Client>,
|
_calling_client: Arc<Client>,
|
||||||
space: Arc<Node>,
|
space: Arc<Node>,
|
||||||
point: mint::Vector3<f32>,
|
point: mint::Vector3<f32>,
|
||||||
) -> impl std::future::Future<Output = Result<(mint::Vector3<f32>, Vec<OwnedFd>)>> + Send + 'static
|
) -> Result<Vector3<f32>> {
|
||||||
{
|
|
||||||
async move {
|
|
||||||
let reference_space = get_spatial(&space, "Reference space")?;
|
let reference_space = get_spatial(&space, "Reference space")?;
|
||||||
let this_field = node.field.get().unwrap();
|
let this_field = node.field.get().unwrap();
|
||||||
|
Ok(this_field
|
||||||
let closest_point =
|
.closest_point(reference_space.as_ref(), point.into(), 0.001)
|
||||||
this_field.closest_point(reference_space.as_ref(), point.into(), 0.001);
|
.into())
|
||||||
Ok((closest_point.into(), Vec::new()))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ray_march(
|
async fn ray_march(
|
||||||
node: Arc<Node>,
|
node: Arc<Node>,
|
||||||
_calling_client: Arc<Client>,
|
_calling_client: Arc<Client>,
|
||||||
space: Arc<Node>,
|
space: Arc<Node>,
|
||||||
ray_origin: mint::Vector3<f32>,
|
ray_origin: mint::Vector3<f32>,
|
||||||
ray_direction: mint::Vector3<f32>,
|
ray_direction: mint::Vector3<f32>,
|
||||||
) -> impl std::future::Future<Output = Result<(RayMarchResult, Vec<OwnedFd>)>> + Send + 'static
|
) -> Result<RayMarchResult> {
|
||||||
{
|
|
||||||
async move {
|
|
||||||
let reference_space = get_spatial(&space, "Reference space")?;
|
let reference_space = get_spatial(&space, "Reference space")?;
|
||||||
let this_field = node.field.get().unwrap();
|
let this_field = node.field.get().unwrap();
|
||||||
|
Ok(this_field.ray_march(Ray {
|
||||||
let ray_march = this_field.ray_march(Ray {
|
|
||||||
origin: ray_origin.into(),
|
origin: ray_origin.into(),
|
||||||
direction: ray_direction.into(),
|
direction: ray_direction.into(),
|
||||||
space: reference_space,
|
space: reference_space,
|
||||||
});
|
}))
|
||||||
Ok((ray_march, Vec::new()))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ use nanoid::nanoid;
|
|||||||
use once_cell::sync::OnceCell;
|
use once_cell::sync::OnceCell;
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::os::fd::OwnedFd;
|
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use std::sync::{Arc, Weak};
|
use std::sync::{Arc, Weak};
|
||||||
use stereokit::{bounds_grow_to_fit_box, Bounds};
|
use stereokit::{bounds_grow_to_fit_box, Bounds};
|
||||||
@@ -244,38 +243,33 @@ impl Spatial {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl SpatialAspect for Spatial {
|
impl SpatialAspect for Spatial {
|
||||||
fn get_local_bounding_box(
|
async fn get_local_bounding_box(
|
||||||
node: Arc<Node>,
|
node: Arc<Node>,
|
||||||
_calling_client: Arc<Client>,
|
_calling_client: Arc<Client>,
|
||||||
) -> impl std::future::Future<Output = Result<(BoundingBox, Vec<OwnedFd>)>> + Send + 'static {
|
) -> Result<BoundingBox> {
|
||||||
async move {
|
|
||||||
let this_spatial = node
|
let this_spatial = node
|
||||||
.spatial
|
.spatial
|
||||||
.get()
|
.get()
|
||||||
.ok_or_else(|| eyre!("Node doesn't have a spatial?"))?;
|
.ok_or_else(|| eyre!("Node doesn't have a spatial?"))?;
|
||||||
let bounds = this_spatial.get_bounding_box();
|
let bounds = this_spatial.get_bounding_box();
|
||||||
|
|
||||||
let return_value = BoundingBox {
|
Ok(BoundingBox {
|
||||||
center: mint::Vector3::from(bounds.center),
|
center: mint::Vector3::from(bounds.center),
|
||||||
size: mint::Vector3::from(bounds.dimensions),
|
size: mint::Vector3::from(bounds.dimensions),
|
||||||
};
|
})
|
||||||
Ok((return_value, Vec::new()))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_relative_bounding_box(
|
async fn get_relative_bounding_box(
|
||||||
node: Arc<Node>,
|
node: Arc<Node>,
|
||||||
_calling_client: Arc<Client>,
|
_calling_client: Arc<Client>,
|
||||||
relative_to: Arc<Node>,
|
relative_to: Arc<Node>,
|
||||||
) -> impl std::future::Future<Output = Result<(BoundingBox, Vec<OwnedFd>)>> + Send + 'static {
|
) -> Result<BoundingBox> {
|
||||||
async move {
|
|
||||||
let this_spatial = node
|
let this_spatial = node
|
||||||
.spatial
|
.spatial
|
||||||
.get()
|
.get()
|
||||||
.ok_or_else(|| eyre!("Node doesn't have a spatial?"))?;
|
.ok_or_else(|| eyre!("Node doesn't have a spatial?"))?;
|
||||||
let relative_spatial = get_spatial(&relative_to, "Relative node")?;
|
let relative_spatial = get_spatial(&relative_to, "Relative node")?;
|
||||||
let center =
|
let center = Spatial::space_to_space_matrix(Some(&this_spatial), Some(&relative_spatial))
|
||||||
Spatial::space_to_space_matrix(Some(&this_spatial), Some(&relative_spatial))
|
|
||||||
.transform_point3([0.0; 3].into());
|
.transform_point3([0.0; 3].into());
|
||||||
let bounds = Bounds {
|
let bounds = Bounds {
|
||||||
center,
|
center,
|
||||||
@@ -290,20 +284,17 @@ impl SpatialAspect for Spatial {
|
|||||||
)),
|
)),
|
||||||
);
|
);
|
||||||
|
|
||||||
let return_value = BoundingBox {
|
Ok(BoundingBox {
|
||||||
center: mint::Vector3::from(bounds.center),
|
center: mint::Vector3::from(bounds.center),
|
||||||
size: mint::Vector3::from(bounds.dimensions),
|
size: mint::Vector3::from(bounds.dimensions),
|
||||||
};
|
})
|
||||||
Ok((return_value, Vec::new()))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_transform(
|
async fn get_transform(
|
||||||
node: Arc<Node>,
|
node: Arc<Node>,
|
||||||
_calling_client: Arc<Client>,
|
_calling_client: Arc<Client>,
|
||||||
relative_to: Arc<Node>,
|
relative_to: Arc<Node>,
|
||||||
) -> impl std::future::Future<Output = Result<(Transform, Vec<OwnedFd>)>> + Send + 'static {
|
) -> Result<Transform> {
|
||||||
async move {
|
|
||||||
let this_spatial = node
|
let this_spatial = node
|
||||||
.spatial
|
.spatial
|
||||||
.get()
|
.get()
|
||||||
@@ -316,13 +307,11 @@ impl SpatialAspect for Spatial {
|
|||||||
)
|
)
|
||||||
.to_scale_rotation_translation();
|
.to_scale_rotation_translation();
|
||||||
|
|
||||||
let return_value = Transform {
|
Ok(Transform {
|
||||||
translation: Some(position.into()),
|
translation: Some(position.into()),
|
||||||
rotation: Some(rotation.into()),
|
rotation: Some(rotation.into()),
|
||||||
scale: Some(scale.into()),
|
scale: Some(scale.into()),
|
||||||
};
|
})
|
||||||
Ok((return_value, Vec::new()))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_local_transform(
|
fn set_local_transform(
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
core::client::INTERNAL_CLIENT,
|
core::client::INTERNAL_CLIENT,
|
||||||
nodes::{
|
nodes::{
|
||||||
data::{mask_matches, Mask, PulseSender, KEYMAPS, PULSE_RECEIVER_REGISTRY},
|
data::{
|
||||||
|
mask_matches, pulse_receiver_client, PulseSender, KEYMAPS, PULSE_RECEIVER_REGISTRY,
|
||||||
|
},
|
||||||
fields::Ray,
|
fields::Ray,
|
||||||
input::{pointer::Pointer, InputMethod, InputType},
|
input::{pointer::Pointer, InputMethod, InputType},
|
||||||
spatial::Spatial,
|
spatial::Spatial,
|
||||||
@@ -69,8 +71,11 @@ impl MousePointer {
|
|||||||
.get_as_string(FORMAT_TEXT_V1),
|
.get_as_string(FORMAT_TEXT_V1),
|
||||||
);
|
);
|
||||||
|
|
||||||
let keyboard_sender =
|
let keyboard_sender = PulseSender::add_to(
|
||||||
PulseSender::add_to(&node, Mask::from_struct::<KeyboardEvent>()).unwrap();
|
&node,
|
||||||
|
Datamap::from_typed(KeyboardEvent::default()).unwrap(),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
Ok(MousePointer {
|
Ok(MousePointer {
|
||||||
node,
|
node,
|
||||||
@@ -135,7 +140,7 @@ impl MousePointer {
|
|||||||
.into_iter()
|
.into_iter()
|
||||||
.filter(|rx| mask_matches(&rx.mask, &self.keyboard_sender.mask))
|
.filter(|rx| mask_matches(&rx.mask, &self.keyboard_sender.mask))
|
||||||
.map(|rx| {
|
.map(|rx| {
|
||||||
let result = rx.field.ray_march(Ray {
|
let result = rx.field_node.field.get().unwrap().ray_march(Ray {
|
||||||
origin: vec3(0.0, 0.0, 0.0),
|
origin: vec3(0.0, 0.0, 0.0),
|
||||||
direction: vec3(0.0, 0.0, -1.0),
|
direction: vec3(0.0, 0.0, -1.0),
|
||||||
space: self.spatial.clone(),
|
space: self.spatial.clone(),
|
||||||
@@ -171,12 +176,10 @@ impl MousePointer {
|
|||||||
|
|
||||||
self.keyboard_datamap.keys = keys;
|
self.keyboard_datamap.keys = keys;
|
||||||
if !self.keyboard_datamap.keys.is_empty() {
|
if !self.keyboard_datamap.keys.is_empty() {
|
||||||
rx.send_data(
|
pulse_receiver_client::data(
|
||||||
|
&rx.node.upgrade().unwrap(),
|
||||||
&self.node.uid,
|
&self.node.uid,
|
||||||
Datamap::from_typed(&self.keyboard_datamap)
|
&Datamap::from_typed(&self.keyboard_datamap).unwrap(),
|
||||||
.unwrap()
|
|
||||||
.raw()
|
|
||||||
.clone(),
|
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,12 +5,13 @@ use glam::Mat4;
|
|||||||
use mint::Vector2;
|
use mint::Vector2;
|
||||||
use nanoid::nanoid;
|
use nanoid::nanoid;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use stardust_xr::values::Datamap;
|
||||||
use stereokit::StereoKitMultiThread;
|
use stereokit::StereoKitMultiThread;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
core::client::INTERNAL_CLIENT,
|
core::client::INTERNAL_CLIENT,
|
||||||
nodes::{
|
nodes::{
|
||||||
data::{Mask, PulseReceiver},
|
data::PulseReceiver,
|
||||||
fields::{r#box::BoxField, Field},
|
fields::{r#box::BoxField, Field},
|
||||||
spatial::Spatial,
|
spatial::Spatial,
|
||||||
Node,
|
Node,
|
||||||
@@ -44,8 +45,11 @@ impl PlaySpace {
|
|||||||
let spatial = Spatial::add_to(&node, None, Mat4::IDENTITY, false)?;
|
let spatial = Spatial::add_to(&node, None, Mat4::IDENTITY, false)?;
|
||||||
let field = BoxField::add_to(&node, [0.0; 3].into())?;
|
let field = BoxField::add_to(&node, [0.0; 3].into())?;
|
||||||
|
|
||||||
let pulse_rx =
|
let pulse_rx = PulseReceiver::add_to(
|
||||||
PulseReceiver::add_to(&node, field.clone(), Mask::from_struct::<PlaySpaceMap>())?;
|
&node,
|
||||||
|
node.clone(),
|
||||||
|
Datamap::from_typed(PlaySpaceMap::default())?,
|
||||||
|
)?;
|
||||||
|
|
||||||
Ok(PlaySpace {
|
Ok(PlaySpace {
|
||||||
_node: node,
|
_node: node,
|
||||||
|
|||||||
Reference in New Issue
Block a user