feat: animation on launch and proper close
This commit is contained in:
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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<Grabbable>,
|
||||
client: Arc<Client>,
|
||||
grabbable: Grabbable,
|
||||
field: SphereField,
|
||||
icon: Model,
|
||||
icon_shrink: Option<Tweener<QuartInOut<f32, f64>>>,
|
||||
@@ -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<Client>, 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::<CString>(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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user