updated packages
This commit is contained in:
29
Cargo.toml
Normal file
29
Cargo.toml
Normal file
@@ -0,0 +1,29 @@
|
||||
[package]
|
||||
name = "protostar"
|
||||
version = "0.4.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
clap = { version = "4.1.3", features = ["derive"] }
|
||||
color-eyre = "0.6.2"
|
||||
directories = "4.0.1"
|
||||
dirs = "4.0.0"
|
||||
ez-pixmap = "0.2.2"
|
||||
glam = { version = "0.22.0", features = ["mint"] }
|
||||
image = "0.24.5"
|
||||
lazy_static = "1.4.0"
|
||||
manifest-dir-macros = "0.1.16"
|
||||
mint = "0.5.9"
|
||||
nix = "0.26.1"
|
||||
resvg = "0.29.0"
|
||||
rustc-hash = "1.1.0"
|
||||
stardust-xr-fusion = "0.38.0"
|
||||
stardust-xr-molecules = "0.21.0"
|
||||
tokio = { version = "1.24.1", features = ["full"] }
|
||||
tracing-subscriber = { version = "0.3.16", features = ["env-filter"] }
|
||||
tween = "2.0.0"
|
||||
ustr = "0.9.0"
|
||||
walkdir = "2.3.2"
|
||||
|
||||
[dev-dependencies]
|
||||
tempdir = "0.3.7"
|
||||
162
src/protostar.rs
Normal file
162
src/protostar.rs
Normal file
@@ -0,0 +1,162 @@
|
||||
use crate::xdg::{DesktopFile, Icon, RawIconType};
|
||||
use color_eyre::eyre::{eyre, Result};
|
||||
use glam::Quat;
|
||||
use mint::Vector3;
|
||||
use nix::unistd::{execv, fork};
|
||||
use stardust_xr_fusion::{
|
||||
client::{Client, FrameInfo, RootHandler},
|
||||
core::values::Transform,
|
||||
drawable::{MaterialParameter, Model, ResourceID},
|
||||
fields::BoxField,
|
||||
node::NodeType,
|
||||
spatial::Spatial,
|
||||
startup_settings::StartupSettings,
|
||||
};
|
||||
use stardust_xr_molecules::{GrabData, Grabbable};
|
||||
use std::{f32::consts::PI, ffi::CStr, sync::Arc};
|
||||
use tween::{QuartInOut, Tweener};
|
||||
use ustr::ustr;
|
||||
|
||||
fn model_from_icon(parent: &Spatial, icon: &Icon) -> Result<Model> {
|
||||
let model = match icon {
|
||||
Icon::Png(path) => {
|
||||
let model = Model::create(
|
||||
parent,
|
||||
Transform::from_rotation(Quat::from_rotation_y(PI)),
|
||||
&ResourceID::new_namespaced("protostar", "cartridge"),
|
||||
)?;
|
||||
model.set_material_parameter(
|
||||
0,
|
||||
"diffuse",
|
||||
MaterialParameter::Texture(ResourceID::Direct(path.clone())),
|
||||
)?;
|
||||
model
|
||||
}
|
||||
Icon::Gltf(path) => Model::create(
|
||||
parent,
|
||||
Transform::from_scale([0.05; 3]),
|
||||
&ResourceID::new_direct(path)?,
|
||||
)?,
|
||||
};
|
||||
Ok(model)
|
||||
}
|
||||
|
||||
pub struct ProtoStar {
|
||||
client: Arc<Client>,
|
||||
grabbable: Grabbable,
|
||||
field: BoxField,
|
||||
icon: Model,
|
||||
icon_shrink: Option<Tweener<f32, f64, QuartInOut>>,
|
||||
execute_command: String,
|
||||
}
|
||||
impl ProtoStar {
|
||||
pub fn create_from_desktop_file(parent: &Spatial, desktop_file: DesktopFile) -> Result<Self> {
|
||||
// dbg!(&desktop_file);
|
||||
let mut raw_icons = desktop_file.get_raw_icons();
|
||||
let last_icon = raw_icons.pop();
|
||||
let icon = raw_icons
|
||||
.into_iter()
|
||||
.find(|i| match i {
|
||||
RawIconType::Png(_) => false,
|
||||
RawIconType::Svg(_) => false,
|
||||
RawIconType::Gltf(_) => true,
|
||||
})
|
||||
.or(last_icon)
|
||||
.map(|i| dbg!(i.process(64)).ok())
|
||||
.ok_or_else(|| eyre!("No compatible icons found"))?;
|
||||
Self::new_raw(
|
||||
parent,
|
||||
icon,
|
||||
desktop_file.command.ok_or_else(|| eyre!("No command"))?,
|
||||
)
|
||||
}
|
||||
pub fn new_raw(parent: &Spatial, icon: Option<Icon>, execute_command: String) -> Result<Self> {
|
||||
let field = BoxField::create(
|
||||
parent,
|
||||
Transform::default(),
|
||||
match icon.as_ref() {
|
||||
Some(Icon::Png(_)) => [0.05, 0.0665, 0.005],
|
||||
_ => [0.05; 3],
|
||||
},
|
||||
)?;
|
||||
let grabbable = Grabbable::new(
|
||||
parent,
|
||||
Transform::default(),
|
||||
&field,
|
||||
GrabData {
|
||||
max_distance: 0.025,
|
||||
..Default::default()
|
||||
},
|
||||
)?;
|
||||
field.set_spatial_parent(grabbable.content_parent())?;
|
||||
let icon = icon
|
||||
.map(|i| model_from_icon(grabbable.content_parent(), &i))
|
||||
.unwrap_or_else(|| {
|
||||
Ok(Model::create(
|
||||
grabbable.content_parent(),
|
||||
Transform::from_scale([0.05; 3]),
|
||||
&ResourceID::new_namespaced("protostar", "default_icon"),
|
||||
)?)
|
||||
})?;
|
||||
Ok(ProtoStar {
|
||||
client: parent.client()?,
|
||||
grabbable,
|
||||
field,
|
||||
icon,
|
||||
icon_shrink: None,
|
||||
execute_command,
|
||||
})
|
||||
}
|
||||
pub fn content_parent(&self) -> &Spatial {
|
||||
self.grabbable.content_parent()
|
||||
}
|
||||
}
|
||||
impl RootHandler for ProtoStar {
|
||||
fn frame(&mut self, info: FrameInfo) {
|
||||
self.grabbable.update(&info);
|
||||
|
||||
if let Some(icon_shrink) = &mut self.icon_shrink {
|
||||
if !icon_shrink.is_finished() {
|
||||
let scale = icon_shrink.move_by(info.delta);
|
||||
self.icon
|
||||
.set_scale(None, Vector3::from([scale; 3]))
|
||||
.unwrap();
|
||||
} else {
|
||||
self.client.stop_loop();
|
||||
}
|
||||
} else if self.grabbable.grab_action().actor_stopped() {
|
||||
let startup_settings = StartupSettings::create(&self.field.client().unwrap()).unwrap();
|
||||
self.icon
|
||||
.set_spatial_parent_in_place(self.client.get_root())
|
||||
.unwrap();
|
||||
self.grabbable
|
||||
.content_parent()
|
||||
.set_rotation(
|
||||
Some(&self.field.client().unwrap().get_root()),
|
||||
Quat::IDENTITY,
|
||||
)
|
||||
.unwrap();
|
||||
startup_settings
|
||||
.set_root(self.grabbable.content_parent())
|
||||
.unwrap();
|
||||
self.icon_shrink = Some(Tweener::quart_in_out(1.0, 0.0, 0.25));
|
||||
let future = startup_settings.generate_startup_token().unwrap();
|
||||
let executable = dbg!(self.execute_command.clone());
|
||||
tokio::task::spawn(async move {
|
||||
std::env::set_var("STARDUST_STARTUP_TOKEN", future.await.unwrap());
|
||||
if unsafe { fork() }.unwrap().is_parent() {
|
||||
println!("Launching \"{}\"...", &executable);
|
||||
execv::<&CStr>(
|
||||
ustr("/bin/sh").as_cstr(),
|
||||
&[
|
||||
ustr("/bin/sh").as_cstr(),
|
||||
ustr("-c").as_cstr(),
|
||||
ustr(&executable).as_cstr(),
|
||||
],
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user