feat: async all the functions!!
This commit is contained in:
@@ -3,8 +3,6 @@ edition = "2018"
|
|||||||
name = "stardust-xr"
|
name = "stardust-xr"
|
||||||
version = "0.9.0"
|
version = "0.9.0"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "1.0.57"
|
anyhow = "1.0.57"
|
||||||
clap = { version = "3.1.6", features = ["derive"] }
|
clap = { version = "3.1.6", features = ["derive"] }
|
||||||
@@ -15,7 +13,6 @@ flexbuffers = "2.0.0"
|
|||||||
glam = {version = "0.20.5", features = ["mint"]}
|
glam = {version = "0.20.5", features = ["mint"]}
|
||||||
lazy_static = "1.4.0"
|
lazy_static = "1.4.0"
|
||||||
mint = "0.5.9"
|
mint = "0.5.9"
|
||||||
mio = {version = "0.8.3", features = ["net", "os-poll", "os-ext"]}
|
|
||||||
nanoid = "0.4.0"
|
nanoid = "0.4.0"
|
||||||
once_cell = "1.12.0"
|
once_cell = "1.12.0"
|
||||||
parking_lot = "0.12.1"
|
parking_lot = "0.12.1"
|
||||||
@@ -23,12 +20,13 @@ portable-atomic = {version = "0.3.0", features = ["float", "std"]}
|
|||||||
rccell = "0.1.3"
|
rccell = "0.1.3"
|
||||||
rustc-hash = "1.1.0"
|
rustc-hash = "1.1.0"
|
||||||
slab = "0.4.6"
|
slab = "0.4.6"
|
||||||
|
tokio = { version = "1", features = ["full"] }
|
||||||
thiserror = "1.0.31"
|
thiserror = "1.0.31"
|
||||||
|
|
||||||
[dependencies.libstardustxr]
|
[dependencies.libstardustxr]
|
||||||
path = "../libstardustxr-rs"
|
path = "../libstardustxr-rs"
|
||||||
|
|
||||||
[dependencies.stereokit-rs]
|
[dependencies.stereokit]
|
||||||
path = "../stereokit-rs"
|
path = "../stereokit-rs"
|
||||||
default-features = false
|
default-features = false
|
||||||
features = ["linux-egl"]
|
features = ["linux-egl"]
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
use super::eventloop::EventLoop;
|
||||||
use super::scenegraph::Scenegraph;
|
use super::scenegraph::Scenegraph;
|
||||||
use crate::nodes::data;
|
use crate::nodes::data;
|
||||||
use crate::nodes::field;
|
use crate::nodes::field;
|
||||||
@@ -5,32 +6,52 @@ use crate::nodes::input;
|
|||||||
use crate::nodes::item;
|
use crate::nodes::item;
|
||||||
use crate::nodes::root::Root;
|
use crate::nodes::root::Root;
|
||||||
use crate::nodes::spatial;
|
use crate::nodes::spatial;
|
||||||
|
use anyhow::Result;
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use libstardustxr::messenger::Messenger;
|
use libstardustxr::messenger::Messenger;
|
||||||
use mio::net::UnixStream;
|
|
||||||
use once_cell::sync::OnceCell;
|
use once_cell::sync::OnceCell;
|
||||||
use std::sync::Arc;
|
use std::sync::{Arc, Weak};
|
||||||
|
use tokio::net::UnixStream;
|
||||||
|
use tokio::sync::Notify;
|
||||||
|
use tokio::task::JoinHandle;
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
pub static ref INTERNAL_CLIENT: Arc<Client> = Client::new_local();
|
pub static ref INTERNAL_CLIENT: Arc<Client> = Arc::new(Client {
|
||||||
|
event_loop: Weak::new(),
|
||||||
|
index: 0,
|
||||||
|
|
||||||
|
stop_notifier: Default::default(),
|
||||||
|
join_handle: OnceCell::new(),
|
||||||
|
|
||||||
|
messenger: None,
|
||||||
|
scenegraph: Default::default(),
|
||||||
|
root: OnceCell::new(),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Client {
|
pub struct Client {
|
||||||
|
event_loop: Weak<EventLoop>,
|
||||||
|
index: usize,
|
||||||
|
stop_notifier: Arc<Notify>,
|
||||||
|
join_handle: OnceCell<JoinHandle<Result<()>>>,
|
||||||
|
|
||||||
pub messenger: Option<Messenger>,
|
pub messenger: Option<Messenger>,
|
||||||
pub scenegraph: Scenegraph,
|
pub scenegraph: Scenegraph,
|
||||||
pub root: OnceCell<Arc<Root>>,
|
pub root: OnceCell<Arc<Root>>,
|
||||||
}
|
}
|
||||||
impl Client {
|
impl Client {
|
||||||
pub fn new_local() -> Arc<Self> {
|
pub fn from_connection(
|
||||||
Arc::new(Client {
|
index: usize,
|
||||||
messenger: None,
|
event_loop: &Arc<EventLoop>,
|
||||||
scenegraph: Default::default(),
|
connection: UnixStream,
|
||||||
root: OnceCell::new(),
|
) -> Arc<Self> {
|
||||||
})
|
|
||||||
}
|
|
||||||
pub fn from_connection(connection: UnixStream) -> Arc<Self> {
|
|
||||||
println!("New client connected");
|
println!("New client connected");
|
||||||
let client = Arc::new(Client {
|
let client = Arc::new(Client {
|
||||||
|
event_loop: Arc::downgrade(event_loop),
|
||||||
|
index,
|
||||||
|
stop_notifier: Default::default(),
|
||||||
|
join_handle: OnceCell::new(),
|
||||||
|
|
||||||
messenger: Some(Messenger::new(connection)),
|
messenger: Some(Messenger::new(connection)),
|
||||||
scenegraph: Default::default(),
|
scenegraph: Default::default(),
|
||||||
root: OnceCell::new(),
|
root: OnceCell::new(),
|
||||||
@@ -42,18 +63,44 @@ impl Client {
|
|||||||
data::create_interface(&client);
|
data::create_interface(&client);
|
||||||
item::create_interface(&client);
|
item::create_interface(&client);
|
||||||
input::create_interface(&client);
|
input::create_interface(&client);
|
||||||
|
|
||||||
|
let _ = client.join_handle.set(tokio::spawn({
|
||||||
|
let client = client.clone();
|
||||||
|
async move {
|
||||||
|
let dispatch_loop = async {
|
||||||
|
loop {
|
||||||
|
client.dispatch().await?
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let result = tokio::select! {
|
||||||
|
_ = client.stop_notifier.notified() => Ok(()),
|
||||||
|
e = dispatch_loop => e,
|
||||||
|
};
|
||||||
|
client.disconnect().await;
|
||||||
|
result
|
||||||
|
}
|
||||||
|
}));
|
||||||
client
|
client
|
||||||
}
|
}
|
||||||
pub fn dispatch(&self) -> Result<(), std::io::Error> {
|
|
||||||
if let Some(messenger) = &self.messenger {
|
pub async fn dispatch(&self) -> Result<(), std::io::Error> {
|
||||||
messenger.dispatch(&self.scenegraph)
|
match &self.messenger {
|
||||||
} else {
|
Some(messenger) => messenger.dispatch(&self.scenegraph).await,
|
||||||
Err(std::io::Error::from(std::io::ErrorKind::Unsupported))
|
None => Err(std::io::Error::from(std::io::ErrorKind::Unsupported)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn disconnect(&self) {
|
||||||
|
self.stop_notifier.notify_one();
|
||||||
|
if let Some(event_loop) = self.event_loop.upgrade() {
|
||||||
|
event_loop.clients.lock().await.remove(self.index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl Drop for Client {
|
impl Drop for Client {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
|
self.stop_notifier.notify_one();
|
||||||
println!("Client disconnected");
|
println!("Client disconnected");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,143 +1,64 @@
|
|||||||
use super::client::Client;
|
use super::client::Client;
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use libstardustxr::server;
|
use libstardustxr::server;
|
||||||
use mio::net::UnixListener;
|
|
||||||
use mio::unix::pipe;
|
|
||||||
use mio::{Events, Interest, Poll, Token};
|
|
||||||
use slab::Slab;
|
use slab::Slab;
|
||||||
use std::io::Write;
|
|
||||||
use std::sync::atomic::AtomicU64;
|
use std::sync::atomic::AtomicU64;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::thread::{self, JoinHandle};
|
use tokio::net::UnixListener;
|
||||||
|
use tokio::sync::{Mutex, Notify, OnceCell};
|
||||||
|
use tokio::task::JoinHandle;
|
||||||
|
|
||||||
pub static FRAME: AtomicU64 = AtomicU64::new(0);
|
pub static FRAME: AtomicU64 = AtomicU64::new(0);
|
||||||
|
|
||||||
pub struct EventLoop {
|
pub struct EventLoop {
|
||||||
pub socket_path: String,
|
pub socket_path: String,
|
||||||
join_handle: Option<JoinHandle<Result<()>>>,
|
stop_notifier: Arc<Notify>,
|
||||||
stop_write: pipe::Sender,
|
pub clients: Mutex<Slab<OnceCell<Arc<Client>>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EventLoop {
|
impl EventLoop {
|
||||||
pub fn new(timeout: Option<core::time::Duration>) -> Result<Self> {
|
pub fn new() -> Result<(Arc<Self>, JoinHandle<Result<()>>)> {
|
||||||
let socket_path = server::get_free_socket_path()
|
let socket_path = server::get_free_socket_path()
|
||||||
.ok_or_else(|| std::io::Error::from(std::io::ErrorKind::Other))?;
|
.ok_or_else(|| std::io::Error::from(std::io::ErrorKind::Other))?;
|
||||||
let (sender, receiver) = pipe::new()?;
|
let socket = UnixListener::bind(socket_path.clone())?;
|
||||||
let socket_path_captured = socket_path.clone();
|
|
||||||
let join_handle = thread::Builder::new()
|
let event_loop = Arc::new(EventLoop {
|
||||||
.name("event_loop".to_owned())
|
|
||||||
.spawn(move || EventLoop::run_loop(timeout, socket_path_captured, receiver))
|
|
||||||
.ok();
|
|
||||||
Ok(EventLoop {
|
|
||||||
socket_path,
|
socket_path,
|
||||||
join_handle,
|
stop_notifier: Default::default(),
|
||||||
stop_write: sender,
|
clients: Mutex::new(Slab::new()),
|
||||||
})
|
});
|
||||||
|
|
||||||
|
let event_loop_join_handle = tokio::spawn({
|
||||||
|
let event_loop = event_loop.clone();
|
||||||
|
async move { EventLoop::event_loop(socket, event_loop).await }
|
||||||
|
});
|
||||||
|
|
||||||
|
Ok((event_loop, event_loop_join_handle))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_loop(
|
async fn event_loop(socket: UnixListener, event_loop: Arc<EventLoop>) -> Result<()> {
|
||||||
timeout: Option<core::time::Duration>,
|
let event_loop_async = async {
|
||||||
socket_path: String,
|
|
||||||
stop_receiver: pipe::Receiver,
|
|
||||||
) -> Result<()> {
|
|
||||||
let mut stop_receiver = stop_receiver;
|
|
||||||
let mut socket = UnixListener::bind(socket_path)?;
|
|
||||||
let mut clients: Slab<Option<Arc<Client>>> = Slab::new();
|
|
||||||
let mut poll = Poll::new()?;
|
|
||||||
let mut events = Events::with_capacity(1024);
|
|
||||||
const LISTENER: Token = Token(usize::MAX - 1);
|
|
||||||
poll.registry()
|
|
||||||
.register(&mut socket, LISTENER, Interest::READABLE)?;
|
|
||||||
const STOP: Token = Token(usize::MAX);
|
|
||||||
poll.registry()
|
|
||||||
.register(&mut stop_receiver, STOP, Interest::READABLE)?;
|
|
||||||
'event_loop: loop {
|
|
||||||
match poll.poll(&mut events, timeout) {
|
|
||||||
Err(e) => {
|
|
||||||
if e.kind() == std::io::ErrorKind::Interrupted {
|
|
||||||
continue 'event_loop;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
for event in &events {
|
|
||||||
match event.token() {
|
|
||||||
LISTENER => EventLoop::accept_client(&socket, &mut clients, &poll)?,
|
|
||||||
STOP => break 'event_loop,
|
|
||||||
token => EventLoop::handle_client_message(token.0, &mut clients)?,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
clients.clear(); // for better log messages
|
|
||||||
println!("Event loop gracefully finished");
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn accept_client(
|
|
||||||
socket: &UnixListener,
|
|
||||||
clients: &mut Slab<Option<Arc<Client>>>,
|
|
||||||
poll: &Poll,
|
|
||||||
) -> Result<()> {
|
|
||||||
loop {
|
|
||||||
match socket.accept() {
|
|
||||||
Ok((mut socket, _)) => {
|
|
||||||
let client_number = clients.insert(None);
|
|
||||||
poll.registry().register(
|
|
||||||
&mut socket,
|
|
||||||
Token(client_number),
|
|
||||||
Interest::READABLE,
|
|
||||||
)?;
|
|
||||||
let client = Client::from_connection(socket);
|
|
||||||
*clients.get_mut(client_number).unwrap() = Some(client);
|
|
||||||
}
|
|
||||||
Err(e) => match e.kind() {
|
|
||||||
std::io::ErrorKind::WouldBlock => break,
|
|
||||||
_ => return Err(e.into()),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn handle_client_message(
|
|
||||||
client_id: usize,
|
|
||||||
clients: &mut Slab<Option<Arc<Client>>>,
|
|
||||||
) -> Result<()> {
|
|
||||||
let client = clients.get(client_id).and_then(|client| client.as_ref());
|
|
||||||
if let Some(client) = client {
|
|
||||||
loop {
|
loop {
|
||||||
let dispatch_result = client.dispatch();
|
let (socket, _) = socket.accept().await?;
|
||||||
match dispatch_result {
|
let mut clients = event_loop.clients.lock().await;
|
||||||
Ok(_) => continue,
|
let idx = clients.insert(OnceCell::new());
|
||||||
Err(e) => match e.kind() {
|
let _ = clients.get(idx).unwrap().set(Client::from_connection(
|
||||||
std::io::ErrorKind::WouldBlock => break,
|
idx,
|
||||||
std::io::ErrorKind::Interrupted => continue,
|
&event_loop,
|
||||||
_ => {
|
socket,
|
||||||
clients.remove(client_id);
|
));
|
||||||
break;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
tokio::select! {
|
||||||
|
_ = event_loop.stop_notifier.notified() => Ok(()),
|
||||||
|
e = event_loop_async => e,
|
||||||
}
|
}
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for EventLoop {
|
impl Drop for EventLoop {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
let buf: [u8; 1] = [1; 1];
|
self.stop_notifier.notify_one();
|
||||||
let _ = self.stop_write.write(buf.as_slice());
|
|
||||||
if let Some(handle) = self.join_handle.take() {
|
|
||||||
match handle.join() {
|
|
||||||
Ok(r) => {
|
|
||||||
if let Err(e) = r {
|
|
||||||
eprintln!("Event loop error: {}", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(e) => eprintln!("Event loop failed to rejoin with error: {:#?}", e),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
78
src/main.rs
78
src/main.rs
@@ -2,11 +2,15 @@ mod core;
|
|||||||
mod nodes;
|
mod nodes;
|
||||||
|
|
||||||
use self::core::eventloop::EventLoop;
|
use self::core::eventloop::EventLoop;
|
||||||
use anyhow::{ensure, Result};
|
use anyhow::Result;
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use stereokit_rs as sk;
|
use once_cell::sync::Lazy;
|
||||||
use stereokit_rs::enums::DisplayMode;
|
use parking_lot::Mutex;
|
||||||
use stereokit_rs::functions::*;
|
use std::sync::Arc;
|
||||||
|
use stereokit::{lifecycle::DisplayMode, Settings};
|
||||||
|
use tokio::runtime::Handle;
|
||||||
|
|
||||||
|
static TOKIO_HANDLE: Lazy<Mutex<Option<Handle>>> = Lazy::new(Default::default);
|
||||||
|
|
||||||
#[derive(Parser)]
|
#[derive(Parser)]
|
||||||
#[clap(author, version, about, long_about = None)]
|
#[clap(author, version, about, long_about = None)]
|
||||||
@@ -14,32 +18,64 @@ struct CliArgs {
|
|||||||
/// Force flatscreen mode and use the mouse pointer as a 3D pointer
|
/// Force flatscreen mode and use the mouse pointer as a 3D pointer
|
||||||
#[clap(short, action)]
|
#[clap(short, action)]
|
||||||
flatscreen: bool,
|
flatscreen: bool,
|
||||||
|
|
||||||
|
/// Run Stardust XR as an overlay
|
||||||
|
#[clap(short, action)]
|
||||||
|
overlay: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() -> Result<()> {
|
fn main() -> Result<()> {
|
||||||
let cli_args = CliArgs::parse();
|
let cli_args = Arc::new(CliArgs::parse());
|
||||||
ctrlc::set_handler(sk_quit).expect("Error setting Ctrl-C handler");
|
|
||||||
|
|
||||||
let mut init_settings = SKSettings::default().app_name("Stardust XR");
|
let mut init_settings = Settings::default()
|
||||||
|
.app_name("Stardust XR")
|
||||||
|
.overlay_app(cli_args.overlay)
|
||||||
|
.overlay_priority(u32::MAX);
|
||||||
if cli_args.flatscreen {
|
if cli_args.flatscreen {
|
||||||
init_settings = init_settings.display_preference(DisplayMode::Flatscreen);
|
init_settings = init_settings.display_preference(DisplayMode::Flatscreen);
|
||||||
}
|
}
|
||||||
ensure!(init_settings.init(), "StereoKit failed to initialize");
|
let stereokit = init_settings
|
||||||
|
.init()
|
||||||
|
.expect("StereoKit failed to initialize");
|
||||||
|
|
||||||
let event_loop = EventLoop::new(None).expect("Couldn't create server socket");
|
let event_thread = std::thread::Builder::new()
|
||||||
println!("Stardust socket created at {}", event_loop.socket_path);
|
.name("event_loop".to_owned())
|
||||||
|
.spawn(event_loop)?;
|
||||||
|
|
||||||
let mut previous_time = 0_f64;
|
stereokit.run(
|
||||||
sk_run(
|
|_draw_ctx| {
|
||||||
&mut Box::new(&mut move || {
|
nodes::root::Root::logic_step(stereokit.time_elapsed());
|
||||||
let current_time = unsafe { sk::sys::time_get() };
|
},
|
||||||
nodes::root::Root::logic_step(current_time - previous_time);
|
|| {
|
||||||
previous_time = current_time;
|
println!("Shut down StereoKit");
|
||||||
}),
|
},
|
||||||
&mut Box::new(&mut || {
|
|
||||||
println!("Shutting down...");
|
|
||||||
}),
|
|
||||||
);
|
);
|
||||||
|
event_thread
|
||||||
|
.join()
|
||||||
|
.expect("Failed to cleanly shut down event loop")?;
|
||||||
|
println!("Cleanly shut down Stardust");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::main]
|
||||||
|
async fn event_loop() -> anyhow::Result<()> {
|
||||||
|
TOKIO_HANDLE.lock().replace(Handle::current());
|
||||||
|
|
||||||
|
let (event_loop, event_loop_join_handle) =
|
||||||
|
EventLoop::new().expect("Couldn't create server socket");
|
||||||
|
println!("Init event loop");
|
||||||
|
println!("Stardust socket created at {}", event_loop.socket_path);
|
||||||
|
|
||||||
|
let result = tokio::select! {
|
||||||
|
biased;
|
||||||
|
_ = tokio::signal::ctrl_c() => Ok(()),
|
||||||
|
// e = task => e?,
|
||||||
|
e = event_loop_join_handle => e?,
|
||||||
|
};
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
stereokit::sys::sk_quit();
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ use super::item::{Item, ItemAcceptor, ItemUI};
|
|||||||
use super::spatial::Spatial;
|
use super::spatial::Spatial;
|
||||||
use crate::core::client::Client;
|
use crate::core::client::Client;
|
||||||
use crate::core::registry::Registry;
|
use crate::core::registry::Registry;
|
||||||
|
use crate::TOKIO_HANDLE;
|
||||||
use anyhow::{anyhow, Result};
|
use anyhow::{anyhow, Result};
|
||||||
use libstardustxr::scenegraph::ScenegraphError;
|
use libstardustxr::scenegraph::ScenegraphError;
|
||||||
use nanoid::nanoid;
|
use nanoid::nanoid;
|
||||||
@@ -156,7 +157,8 @@ impl Node {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn send_remote_signal(&self, method: &str, data: &[u8]) -> Result<()> {
|
pub fn send_remote_signal(&self, method: &str, data: &[u8]) -> Result<()> {
|
||||||
self.aliases
|
let _ = self
|
||||||
|
.aliases
|
||||||
.get_valid_contents()
|
.get_valid_contents()
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|alias| alias.remote_signals.iter().any(|e| e == &method))
|
.filter(|alias| alias.remote_signals.iter().any(|e| e == &method))
|
||||||
@@ -167,25 +169,28 @@ impl Node {
|
|||||||
.unwrap()
|
.unwrap()
|
||||||
.send_remote_signal(method, data);
|
.send_remote_signal(method, data);
|
||||||
});
|
});
|
||||||
self.get_client()
|
let client = self.get_client();
|
||||||
.messenger
|
let path = self.path.clone();
|
||||||
.as_ref()
|
let method = method.to_string();
|
||||||
.ok_or_else(|| anyhow!("Node's client has no messenger"))?
|
let data = data.to_vec();
|
||||||
.send_remote_signal(self.path.as_str(), method, data)
|
TOKIO_HANDLE.lock().as_ref().unwrap().spawn(async move {
|
||||||
.map_err(|_| anyhow!("Unable to write in messenger"))
|
if let Some(messenger) = client.messenger.as_ref() {
|
||||||
|
let _ = messenger
|
||||||
|
.send_remote_signal(path.as_str(), method.as_str(), data.as_slice())
|
||||||
|
.await;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
pub fn execute_remote_method(
|
pub async fn execute_remote_method(&self, method: &str, data: Vec<u8>) -> Result<Vec<u8>> {
|
||||||
&self,
|
match self.get_client().messenger.as_ref() {
|
||||||
method: &str,
|
None => Err(anyhow!("Messenger does not exist for this node's client")),
|
||||||
data: &[u8],
|
Some(messenger) => {
|
||||||
callback: Box<dyn FnOnce(&[u8]) + Send + Sync>,
|
messenger
|
||||||
) -> Result<()> {
|
.execute_remote_method(self.path.as_str(), method, &data)
|
||||||
self.get_client()
|
.await
|
||||||
.messenger
|
}
|
||||||
.as_ref()
|
}
|
||||||
.ok_or_else(|| anyhow!("Node's client has no messenger"))?
|
|
||||||
.execute_remote_method(self.path.as_str(), method, data, callback)
|
|
||||||
.map_err(|_| anyhow!("Unable to write in messenger"))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -156,23 +156,23 @@ impl InputHandler {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let serialized_data = distance_link.serialize();
|
match distance_link.serialize() {
|
||||||
|
None => InputHandler::next_input(old_frame, distance_links),
|
||||||
|
Some(data) => {
|
||||||
|
let node = self.node.upgrade().unwrap();
|
||||||
|
|
||||||
if let Some(data) = serialized_data {
|
tokio::spawn(async move {
|
||||||
let _ = self.node.upgrade().unwrap().execute_remote_method(
|
let data = node.execute_remote_method("input", data).await;
|
||||||
"input",
|
if let Ok(data) = data {
|
||||||
&data,
|
let capture = flexbuffers::Reader::get_root(data.as_slice())
|
||||||
Box::new(move |data| {
|
.and_then(|data| data.get_bool())
|
||||||
let capture = flexbuffers::Reader::get_root(data)
|
.unwrap_or(false);
|
||||||
.and_then(|data| data.get_bool())
|
if !distance_links.is_empty() && !capture {
|
||||||
.unwrap_or(false);
|
InputHandler::next_input(old_frame, distance_links);
|
||||||
if !distance_links.is_empty() && !capture {
|
}
|
||||||
InputHandler::next_input(old_frame, distance_links);
|
|
||||||
}
|
}
|
||||||
}),
|
});
|
||||||
);
|
}
|
||||||
} else {
|
|
||||||
InputHandler::next_input(old_frame, distance_links);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user