From 44ba9f2d680b37c4c774cf8e3d0c473d156d5e07 Mon Sep 17 00:00:00 2001 From: Nova Date: Tue, 12 Jul 2022 14:55:46 -0400 Subject: [PATCH] fix(logic step): proper procedure --- src/core/client.rs | 24 +++++++++++++---- src/core/eventloop.rs | 16 ++++++------ src/main.rs | 8 +++--- src/nodes/root.rs | 61 ++++++++++++++++++++++++++++++------------- 4 files changed, 75 insertions(+), 34 deletions(-) diff --git a/src/core/client.rs b/src/core/client.rs index 7d4b3a9..128239d 100644 --- a/src/core/client.rs +++ b/src/core/client.rs @@ -3,31 +3,40 @@ use crate::nodes::data; use crate::nodes::field; use crate::nodes::input; use crate::nodes::item; -use crate::nodes::root; +use crate::nodes::root::Root; use crate::nodes::spatial; use lazy_static::lazy_static; use libstardustxr::messenger::Messenger; use mio::net::UnixStream; +use once_cell::sync::OnceCell; use std::sync::Arc; lazy_static! { - pub static ref INTERNAL_CLIENT: Arc = Default::default(); + pub static ref INTERNAL_CLIENT: Arc = Client::new_local(); } -#[derive(Default)] pub struct Client { pub messenger: Option, pub scenegraph: Scenegraph, + pub root: OnceCell>, } - impl Client { + pub fn new_local() -> Arc { + Arc::new(Client { + messenger: None, + scenegraph: Default::default(), + root: OnceCell::new(), + }) + } pub fn from_connection(connection: UnixStream) -> Arc { + println!("New client connected"); let client = Arc::new(Client { messenger: Some(Messenger::new(connection)), scenegraph: Default::default(), + root: OnceCell::new(), }); let _ = client.scenegraph.client.set(Arc::downgrade(&client)); - root::create_root(&client); + let _ = client.root.set(Root::create(&client)); spatial::create_interface(&client); field::create_interface(&client); data::create_interface(&client); @@ -43,3 +52,8 @@ impl Client { } } } +impl Drop for Client { + fn drop(&mut self) { + println!("Client disconnected"); + } +} diff --git a/src/core/eventloop.rs b/src/core/eventloop.rs index 87c36b9..d59d15f 100644 --- a/src/core/eventloop.rs +++ b/src/core/eventloop.rs @@ -52,12 +52,10 @@ impl EventLoop { let client = Client::from_connection(socket); *clients.get_mut(client_number).unwrap() = Some(client); } - Err(e) => { - if e.kind() == std::io::ErrorKind::WouldBlock { - break; - } - return Err(e.into()); - } + Err(e) => match e.kind() { + std::io::ErrorKind::WouldBlock => break, + _ => return Err(e.into()), + }, } }, STOP => return Ok(()), @@ -66,7 +64,8 @@ impl EventLoop { clients.get(token.0).and_then(|client| client.as_ref()); if let Some(client) = client { loop { - match client.dispatch() { + let dispatch_result = client.dispatch(); + match dispatch_result { Ok(_) => continue, Err(e) => match e.kind() { std::io::ErrorKind::WouldBlock => break, @@ -97,7 +96,8 @@ impl Drop for EventLoop { let buf: [u8; 1] = [1; 1]; let _ = self.stop_write.write(buf.as_slice()); if let Some(handle) = self.join_handle.take() { - handle.join().unwrap().unwrap(); + let _ = handle.join(); + // handle.join().unwrap().unwrap(); } } } diff --git a/src/main.rs b/src/main.rs index 1be4b53..40aec9d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -29,10 +29,12 @@ fn main() -> Result<()> { let event_loop = EventLoop::new(None).expect("Couldn't create server socket"); println!("Stardust socket created at {}", event_loop.socket_path); + let mut previous_time = 0_f64; sk_run( - &mut Box::new(&mut || { - let time = unsafe { sk::sys::time_get() }; - nodes::root::logic_step(time); + &mut Box::new(&mut move || { + let current_time = unsafe { sk::sys::time_get() }; + nodes::root::Root::logic_step(current_time - previous_time); + previous_time = current_time; }), &mut Box::new(&mut || { println!("Shutting down..."); diff --git a/src/nodes/root.rs b/src/nodes/root.rs index c4b23f5..2281561 100644 --- a/src/nodes/root.rs +++ b/src/nodes/root.rs @@ -6,30 +6,55 @@ use anyhow::Result; use glam::Mat4; use lazy_static::lazy_static; use libstardustxr::flex::flexbuffer_from_vector_arguments; +use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Arc; lazy_static! { - static ref LOGIC_STEP_REGISTRY: Registry = Registry::default(); + static ref ROOT_REGISTRY: Registry = Default::default(); } -pub fn logic_step(delta: f64) { - let data = flexbuffer_from_vector_arguments(move |fbb| { - fbb.push(delta); - fbb.push(0_f64); - }); - for root in LOGIC_STEP_REGISTRY.get_valid_contents() { - root.send_remote_signal("logicStep", &data); +pub struct Root { + node: Arc, + logic_step: AtomicBool, +} +impl Root { + pub fn create(client: &Arc) -> Arc { + let node = Node::create(client, "", "", false); + node.add_local_signal("subscribeLogicStep", Root::subscribe_logic_step); + let node = node.add_to_scenegraph(); + let _ = Spatial::add_to(&node, None, Mat4::IDENTITY); + + ROOT_REGISTRY.add(Root { + node, + logic_step: AtomicBool::from(false), + }) + } + + fn subscribe_logic_step(_node: &Node, calling_client: Arc, _data: &[u8]) -> Result<()> { + calling_client + .root + .get() + .unwrap() + .logic_step + .store(true, Ordering::Relaxed); + Ok(()) + } + + pub fn logic_step(delta: f64) { + let data = flexbuffer_from_vector_arguments(move |fbb| { + fbb.push(delta); + fbb.push(0_f64); + }); + for root in ROOT_REGISTRY.get_valid_contents() { + if root.logic_step.load(Ordering::Relaxed) { + let _ = root.node.send_remote_signal("logicStep", &data); + } + } } } -pub fn create_root(client: &Arc) { - let node = Node::create(client, "", "", false); - node.add_local_signal("subscribeLogicStep", subscribe_logic_step); - let node = node.add_to_scenegraph(); - let _ = Spatial::add_to(&node, None, Mat4::IDENTITY); -} - -fn subscribe_logic_step(node: &Node, calling_client: Arc, data: &[u8]) -> Result<()> { - LOGIC_STEP_REGISTRY.add_raw(&calling_client.scenegraph.get_node("/").unwrap()); - Ok(()) +impl Drop for Root { + fn drop(&mut self) { + ROOT_REGISTRY.remove(self); + } }