From a1bcdc4228e2ac553610a09f923f7695c668db0f Mon Sep 17 00:00:00 2001 From: Nova Date: Sun, 27 Nov 2022 22:04:12 -0500 Subject: [PATCH] feat: animation on launch and proper close --- Cargo.lock | 118 +++++++++++++++++++++++++++++++++++++++++------ Cargo.toml | 4 +- src/main.rs | 7 ++- src/protostar.rs | 66 ++++++++++++++------------ 4 files changed, 146 insertions(+), 49 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4b89564..f9e57ba 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,6 +8,17 @@ version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" +[[package]] +name = "ahash" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +dependencies = [ + "getrandom", + "once_cell", + "version_check", +] + [[package]] name = "aho-corasick" version = "0.7.20" @@ -322,6 +333,15 @@ dependencies = [ "cxx-build", ] +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", +] + [[package]] name = "js-sys" version = "0.3.60" @@ -389,6 +409,15 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +[[package]] +name = "memoffset" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +dependencies = [ + "autocfg", +] + [[package]] name = "mint" version = "0.5.9" @@ -419,6 +448,20 @@ dependencies = [ "rand", ] +[[package]] +name = "nix" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e322c04a9e3440c327fca7b6c8a63e6890a32fa2ad689db972425f07e0d22abb" +dependencies = [ + "autocfg", + "bitflags", + "cfg-if", + "libc", + "memoffset", + "pin-utils", +] + [[package]] name = "num-integer" version = "0.1.45" @@ -498,6 +541,17 @@ dependencies = [ "syn", ] +[[package]] +name = "parking_lot" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" +dependencies = [ + "instant", + "lock_api", + "parking_lot_core 0.8.5", +] + [[package]] name = "parking_lot" version = "0.12.1" @@ -505,7 +559,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" dependencies = [ "lock_api", - "parking_lot_core", + "parking_lot_core 0.9.4", +] + +[[package]] +name = "parking_lot_core" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" +dependencies = [ + "cfg-if", + "instant", + "libc", + "redox_syscall", + "smallvec", + "winapi", ] [[package]] @@ -527,6 +595,12 @@ version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + [[package]] name = "ppv-lite86" version = "0.2.17" @@ -579,16 +653,18 @@ dependencies = [ [[package]] name = "protostar" -version = "0.1.0" +version = "0.2.0" dependencies = [ "anyhow", "glam 0.22.0", "manifest-dir-macros", "mint", + "nix", "rustc-hash", "stardust-xr-molecules", "tokio", "tween", + "ustr", ] [[package]] @@ -687,18 +763,18 @@ checksum = "9c8132065adcfd6e02db789d9285a0deb2f3fcb04002865ab67d5fb103533898" [[package]] name = "serde" -version = "1.0.147" +version = "1.0.148" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d193d69bae983fc11a79df82342761dfbf28a99fc8d203dca4c3c1b590948965" +checksum = "e53f64bb4ba0191d6d0676e1b141ca55047d83b74f5607e6d8eb88126c52c2dc" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.147" +version = "1.0.148" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f1d362ca8fc9c3e3a7484440752472d68a6caa98f1ab81d99b5dfe517cec852" +checksum = "a55492425aa53521babf6137309e7d34c20bbfbbfcfe2c7f3a047fd1f6b92c0c" dependencies = [ "proc-macro2", "quote", @@ -754,7 +830,7 @@ dependencies = [ "flatbuffers", "flexbuffers", "mint", - "parking_lot", + "parking_lot 0.12.1", "rustc-hash", "serde", "stardust-xr-schemas", @@ -765,9 +841,9 @@ dependencies = [ [[package]] name = "stardust-xr-fusion" -version = "0.22.0" +version = "0.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce1305463319add3ce6f9bd2864d79a3a836c752929f052743b8a1e90f3d62d8" +checksum = "357475624cc78941af592c755fd51a7f6b85b3323df10542c53993030fbea5a8" dependencies = [ "anyhow", "buildstructor", @@ -777,7 +853,7 @@ dependencies = [ "glam 0.22.0", "mint", "nanoid", - "parking_lot", + "parking_lot 0.12.1", "rustc-hash", "serde", "serde_repr", @@ -789,9 +865,9 @@ dependencies = [ [[package]] name = "stardust-xr-molecules" -version = "0.5.2" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59264c72fa87768563ba781264843b1412aaf3bdb4dcec19d7b1b15fbc3027a5" +checksum = "e04616f27e92c2d40595c0fbe4f96e5788adca3a855611794c6f202bf2c0ddd0" dependencies = [ "color-rs", "flexbuffers", @@ -833,9 +909,9 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.103" +version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a864042229133ada95abf3b54fdc62ef5ccabe9515b64717bcb9a1919e59445d" +checksum = "4ae548ec36cf198c0ef7710d3c230987c2d6d7bd98ad6edc0274462724c585ce" dependencies = [ "proc-macro2", "quote", @@ -894,7 +970,7 @@ dependencies = [ "memchr", "mio", "num_cpus", - "parking_lot", + "parking_lot 0.12.1", "pin-project-lite", "signal-hook-registry", "socket2", @@ -961,6 +1037,18 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" +[[package]] +name = "ustr" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "371436099f2980de56dc385b615696d3eabbdac9649a72b85f9d75f68474fa9c" +dependencies = [ + "ahash", + "byteorder", + "lazy_static", + "parking_lot 0.11.2", +] + [[package]] name = "version_check" version = "0.9.4" diff --git a/Cargo.toml b/Cargo.toml index 5b31ac3..adbdb49 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "protostar" -version = "0.1.0" +version = "0.2.0" edition = "2021" [dependencies] @@ -8,7 +8,9 @@ anyhow = "1.0.66" glam = { version = "0.22.0", features = ["mint"] } manifest-dir-macros = "0.1.16" mint = "0.5.9" +nix = "0.25.0" rustc-hash = "1.1.0" stardust-xr-molecules = "0.5.2" tokio = { version = "1.22.0", features = ["full"] } tween = "1.0.1" +ustr = "0.9.0" diff --git a/src/main.rs b/src/main.rs index 357b636..406298f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,15 +11,14 @@ async fn main() { client.set_base_prefixes(&[directory_relative_path!("res")]); let _root = client.wrap_root(ProtoStar::new( - &client, + client.clone(), PathBuf::from_str(&args().nth(2).unwrap()).unwrap(), 0.1, PathBuf::from_str(&args().nth(1).unwrap()).unwrap(), )); tokio::select! { - _ = tokio::signal::ctrl_c() => Ok(()), - _ = event_loop => Err(anyhow::anyhow!("Server crashed")), + _ = tokio::signal::ctrl_c() => (), + e = event_loop => e.unwrap().unwrap(), } - .unwrap(); } diff --git a/src/protostar.rs b/src/protostar.rs index 3caac18..6fb8752 100644 --- a/src/protostar.rs +++ b/src/protostar.rs @@ -1,5 +1,6 @@ use glam::Quat; use mint::Vector3; +use nix::unistd::{execv, fork}; use stardust_xr_molecules::{ fusion::{ client::{Client, LifeCycleHandler, LogicStepInfo}, @@ -10,11 +11,13 @@ use stardust_xr_molecules::{ }, Grabbable, }; -use std::{path::PathBuf, process::Command}; +use std::{ffi::CString, path::PathBuf, sync::Arc}; use tween::{QuartInOut, Tweener}; +use ustr::ustr; pub struct ProtoStar { - grabbable: Option, + client: Arc, + grabbable: Grabbable, field: SphereField, icon: Model, icon_shrink: Option>>, @@ -22,7 +25,7 @@ pub struct ProtoStar { executable_path: PathBuf, } impl ProtoStar { - pub fn new(client: &Client, icon: PathBuf, size: f32, executable_path: PathBuf) -> Self { + pub fn new(client: Arc, icon: PathBuf, size: f32, executable_path: PathBuf) -> Self { let field = SphereField::builder() .spatial_parent(client.get_root()) .radius(size * 0.5) @@ -39,7 +42,8 @@ impl ProtoStar { .build() .unwrap(); ProtoStar { - grabbable: Some(grabbable), + client, + grabbable, field, icon, icon_shrink: None, @@ -50,37 +54,41 @@ impl ProtoStar { } impl LifeCycleHandler for ProtoStar { fn logic_step(&mut self, info: LogicStepInfo) { - if let Some(grabbable) = &mut self.grabbable { - grabbable.update(); - if grabbable.grab_action().actor_stopped() { - let startup_settings = - StartupSettings::create(&self.field.spatial.client().unwrap()).unwrap(); - grabbable - .content_parent() - .set_rotation( - Some(&self.field.client().unwrap().get_root()), - Quat::IDENTITY, - ) - .unwrap(); - startup_settings - .set_root(grabbable.content_parent()) - .unwrap(); - drop(self.grabbable.take()); - self.icon_shrink = Some(Tweener::new(QuartInOut::new(self.size..=0.0, 0.25))); - let future = startup_settings.generate_desktop_startup_id().unwrap(); - let mut command = Command::new(self.executable_path.clone()); - tokio::task::spawn(async move { - command.env("DESKTOP_STARTUP_ID", future.await.unwrap()); - command.spawn().unwrap(); - drop(startup_settings); - }); - } + self.grabbable.update(); + if self.grabbable.grab_action().actor_stopped() { + let startup_settings = + StartupSettings::create(&self.field.spatial.client().unwrap()).unwrap(); + self.grabbable + .content_parent() + .set_rotation( + Some(&self.field.client().unwrap().get_root()), + Quat::IDENTITY, + ) + .unwrap(); + self.icon + .set_spatial_parent_in_place(self.client.get_root()) + .unwrap(); + startup_settings + .set_root(self.grabbable.content_parent()) + .unwrap(); + self.icon_shrink = Some(Tweener::new(QuartInOut::new(self.size..=0.0, 0.25))); + let future = startup_settings.generate_desktop_startup_id().unwrap(); + let executable = self.executable_path.clone(); + tokio::task::spawn(async move { + std::env::set_var("DESKTOP_STARTUP_ID", future.await.unwrap()); + if unsafe { fork() }.unwrap().is_parent() { + let executable = ustr(executable.to_str().unwrap()); + execv::(executable.as_cstr(), &[]).unwrap(); + } + }); } if let Some(icon_shrink) = &mut self.icon_shrink { if let Some(scale) = icon_shrink.update(info.delta) { self.icon .set_scale(None, Vector3::from([scale; 3])) .unwrap(); + } else { + self.client.stop_loop(); } } }