diff --git a/Cargo.lock b/Cargo.lock index dcebaf1..af413db 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "addr2line" @@ -366,15 +366,6 @@ version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" -[[package]] -name = "block-buffer" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" -dependencies = [ - "generic-array", -] - [[package]] name = "blocking" version = "1.6.1" @@ -568,15 +559,6 @@ version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" -[[package]] -name = "cpufeatures" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" -dependencies = [ - "libc", -] - [[package]] name = "crc32fast" version = "1.4.2" @@ -617,16 +599,6 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" -[[package]] -name = "crypto-common" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" -dependencies = [ - "generic-array", - "typenum", -] - [[package]] name = "darling" version = "0.20.10" @@ -662,6 +634,20 @@ dependencies = [ "syn 2.0.77", ] +[[package]] +name = "dashmap" +version = "6.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf" +dependencies = [ + "cfg-if", + "crossbeam-utils", + "hashbrown 0.14.5", + "lock_api", + "once_cell", + "parking_lot_core 0.9.10", +] + [[package]] name = "data-url" version = "0.2.0" @@ -678,16 +664,6 @@ dependencies = [ "serde", ] -[[package]] -name = "digest" -version = "0.10.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" -dependencies = [ - "block-buffer", - "crypto-common", -] - [[package]] name = "directories" version = "5.0.1" @@ -981,9 +957,9 @@ checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" [[package]] name = "futures-core" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" [[package]] name = "futures-io" @@ -993,9 +969,9 @@ checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" [[package]] name = "futures-lite" -version = "2.3.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52527eb5074e35e9339c6b4e8d12600c7128b68fb25dcb9fa9dec18f7c25f3a5" +checksum = "f5edaec856126859abb19ed65f39e90fea3a9574b9707f13539acf4abf7eb532" dependencies = [ "fastrand", "futures-core", @@ -1006,54 +982,35 @@ dependencies = [ [[package]] name = "futures-macro" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", "syn 2.0.77", ] -[[package]] -name = "futures-sink" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" - [[package]] name = "futures-task" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" [[package]] name = "futures-util" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ "futures-core", - "futures-io", "futures-macro", - "futures-sink", "futures-task", - "memchr", "pin-project-lite", "pin-utils", "slab", ] -[[package]] -name = "generic-array" -version = "0.14.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", -] - [[package]] name = "getrandom" version = "0.2.15" @@ -1118,6 +1075,15 @@ dependencies = [ "mint", ] +[[package]] +name = "glam" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf3aa70d918d2b234126ff4f850f628f172542bf0603ded26b8ee36e5e22d5f9" +dependencies = [ + "mint", +] + [[package]] name = "global_counter" version = "0.2.2" @@ -1568,6 +1534,15 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "nanoid" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ffa00dec017b5b1a8b7cf5e2c008bfda1aa7e0697ac1508b491fdf2622fb4d8" +dependencies = [ + "rand 0.8.5", +] + [[package]] name = "nix" version = "0.27.1" @@ -2334,17 +2309,6 @@ dependencies = [ "syn 2.0.77", ] -[[package]] -name = "sha1" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - [[package]] name = "sharded-slab" version = "0.1.7" @@ -2480,9 +2444,10 @@ checksum = "2f2b15926089e5526bb2dd738a2eb0e59034356e06eb71e1cd912358c0e62c4d" [[package]] name = "stardust-xr" version = "0.45.0" -source = "git+https://github.com/StardustXR/core.git?branch=dev#22fcdda7937308a067a9f61ecbcffb0907739ecb" +source = "git+https://github.com/StardustXR/core.git?branch=dev#d2964d8db079afaadb7faa4987e34814e62d6279" dependencies = [ "cluFlock", + "color-eyre", "dirs 5.0.1", "global_counter", "mint", @@ -2500,15 +2465,17 @@ dependencies = [ [[package]] name = "stardust-xr-fusion" version = "0.45.0" -source = "git+https://github.com/StardustXR/core.git?branch=dev#22fcdda7937308a067a9f61ecbcffb0907739ecb" +source = "git+https://github.com/StardustXR/core.git?branch=dev#d2964d8db079afaadb7faa4987e34814e62d6279" dependencies = [ "color-eyre", - "glam 0.24.2", + "dashmap", + "glam 0.30.1", "global_counter", "parking_lot 0.12.3", "rustc-hash 1.1.0", "serde", "serde_repr", + "split-iter", "stardust-xr", "stardust-xr-fusion-codegen", "thiserror", @@ -2520,7 +2487,7 @@ dependencies = [ [[package]] name = "stardust-xr-fusion-codegen" version = "0.1.0" -source = "git+https://github.com/StardustXR/core.git?branch=dev#22fcdda7937308a067a9f61ecbcffb0907739ecb" +source = "git+https://github.com/StardustXR/core.git?branch=dev#d2964d8db079afaadb7faa4987e34814e62d6279" dependencies = [ "convert_case", "mint", @@ -2533,23 +2500,26 @@ dependencies = [ [[package]] name = "stardust-xr-molecules" version = "0.45.0" -source = "git+https://github.com/StardustXR/molecules.git?branch=dev#c69db9f1bff5087fdcae1c8f1d2d9111e56ec799" +source = "git+https://github.com/StardustXR/molecules.git?branch=dev#4871307e677cab37a606400b3101a51c335f851f" dependencies = [ + "futures-util", "glam 0.27.0", "lazy_static", "lerp", "map-range", + "nanoid", "rustc-hash 1.1.0", "serde", "stardust-xr-fusion", "tokio", "tracing", + "zbus", ] [[package]] name = "stardust-xr-schemas" version = "1.5.3" -source = "git+https://github.com/StardustXR/core.git?branch=dev#22fcdda7937308a067a9f61ecbcffb0907739ecb" +source = "git+https://github.com/StardustXR/core.git?branch=dev#d2964d8db079afaadb7faa4987e34814e62d6279" dependencies = [ "flatbuffers", "flexbuffers", @@ -2557,6 +2527,7 @@ dependencies = [ "futures-util", "kdl", "manifest-dir-macros", + "nanoid", "serde", "serde_repr", "thiserror", @@ -2772,6 +2743,7 @@ dependencies = [ "signal-hook-registry", "socket2", "tokio-macros", + "tracing", "windows-sys 0.52.0", ] @@ -2914,12 +2886,6 @@ version = "2.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "782d1e33eba0670d92d03e4da87f7304490493fc983d229dff383934c23f2d16" -[[package]] -name = "typenum" -version = "1.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" - [[package]] name = "uds_windows" version = "1.1.0" @@ -3331,6 +3297,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "winnow" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e97b544156e9bebe1a0ffbc03484fc1ffe3100cbce3ffb17eac35f7cdd7ab36" +dependencies = [ + "memchr", +] + [[package]] name = "xdg" version = "2.5.2" @@ -3355,9 +3330,9 @@ checksum = "66fee0b777b0f5ac1c69bb06d361268faafa61cd4682ae064a171c16c433e9e4" [[package]] name = "zbus" -version = "4.4.0" +version = "5.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb97012beadd29e654708a0fdb4c84bc046f537aecfde2c3ee0a9e4b4d48c725" +checksum = "59c333f648ea1b647bc95dc1d34807c8e25ed7a6feff3394034dc4776054b236" dependencies = [ "async-broadcast", "async-executor", @@ -3372,19 +3347,18 @@ dependencies = [ "enumflags2", "event-listener", "futures-core", - "futures-sink", - "futures-util", + "futures-lite", "hex", "nix 0.29.0", "ordered-stream", - "rand 0.8.5", "serde", "serde_repr", - "sha1", "static_assertions", + "tokio", "tracing", "uds_windows", - "windows-sys 0.52.0", + "windows-sys 0.59.0", + "winnow 0.7.4", "xdg-home", "zbus_macros", "zbus_names", @@ -3393,25 +3367,28 @@ dependencies = [ [[package]] name = "zbus_macros" -version = "4.4.0" +version = "5.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "267db9407081e90bbfa46d841d3cbc60f59c0351838c4bc65199ecd79ab1983e" +checksum = "f325ad10eb0d0a3eb060203494c3b7ec3162a01a59db75d2deee100339709fc0" dependencies = [ "proc-macro-crate 3.2.0", "proc-macro2", "quote", "syn 2.0.77", + "zbus_names", + "zvariant", "zvariant_utils", ] [[package]] name = "zbus_names" -version = "3.0.0" +version = "4.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b9b1fef7d021261cc16cba64c351d291b715febe0fa10dc3a443ac5a5022e6c" +checksum = "7be68e64bf6ce8db94f63e72f0c7eb9a60d733f7e0499e628dfab0f84d6bcb97" dependencies = [ "serde", "static_assertions", + "winnow 0.7.4", "zvariant", ] @@ -3447,22 +3424,24 @@ dependencies = [ [[package]] name = "zvariant" -version = "4.2.0" +version = "5.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2084290ab9a1c471c38fc524945837734fbf124487e105daec2bb57fd48c81fe" +checksum = "b2df9ee044893fcffbdc25de30546edef3e32341466811ca18421e3cd6c5a3ac" dependencies = [ "endi", "enumflags2", "serde", "static_assertions", + "winnow 0.7.4", "zvariant_derive", + "zvariant_utils", ] [[package]] name = "zvariant_derive" -version = "4.2.0" +version = "5.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73e2ba546bda683a90652bac4a279bc146adad1386f25379cf73200d2002c449" +checksum = "74170caa85b8b84cc4935f2d56a57c7a15ea6185ccdd7eadb57e6edd90f94b2f" dependencies = [ "proc-macro-crate 3.2.0", "proc-macro2", @@ -3473,11 +3452,14 @@ dependencies = [ [[package]] name = "zvariant_utils" -version = "2.1.0" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c51bcff7cc3dbb5055396bcf774748c3dab426b4b8659046963523cee4808340" +checksum = "e16edfee43e5d7b553b77872d99bc36afdda75c223ca7ad5e3fbecd82ca5fc34" dependencies = [ "proc-macro2", "quote", + "serde", + "static_assertions", "syn 2.0.77", + "winnow 0.7.4", ] diff --git a/Cargo.toml b/Cargo.toml index 0e0fee3..1046acb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,4 +1,5 @@ [workspace] +resolver = "2" members = ["app_grid", "hexagon_launcher", "protostar", "single", "sirius"] [workspace.dependencies] diff --git a/app_grid/Cargo.toml b/app_grid/Cargo.toml index c873568..6104359 100644 --- a/app_grid/Cargo.toml +++ b/app_grid/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "app_grid" version = "0.1.0" -edition = "2021" +edition = "2024" [dependencies] tokio = { version = "1.32.0", features = ["rt", "tokio-macros", "sync"] } diff --git a/app_grid/src/main.rs b/app_grid/src/main.rs index 7ffd585..9bd2f37 100644 --- a/app_grid/src/main.rs +++ b/app_grid/src/main.rs @@ -13,11 +13,11 @@ use stardust_xr_fusion::{ YAlign, }, fields::{Field, Shape}, - node::NodeType, - root::{ClientState, FrameInfo, RootAspect, RootHandler}, + root::{ClientState, FrameInfo, RootAspect}, spatial::{Spatial, SpatialAspect, SpatialRefAspect, Transform}, + ClientHandle, }; -use stardust_xr_molecules::{Grabbable, GrabbableSettings}; +use stardust_xr_molecules::{FrameSensitive, Grabbable, GrabbableSettings, UIElement}; use std::f32::consts::PI; const APP_LIMIT: usize = 300; @@ -32,16 +32,34 @@ async fn main() -> Result<()> { .with_env_filter(tracing_subscriber::EnvFilter::from_default_env()) .pretty() .init(); - let (client, event_loop) = Client::connect_with_async_loop().await?; + let owned_client = Client::connect().await?; + let client = owned_client.handle(); + let async_loop = owned_client.async_event_loop(); client - .set_base_prefixes(&[directory_relative_path!("../res")]) + .get_root() + .set_base_prefixes(&[directory_relative_path!("../res").to_string()]) .unwrap(); - let _root = client.get_root().alias().wrap(AppGrid::new(&client))?; + let mut grid = AppGrid::new(&client); + let mut owned_client = async_loop.stop().await.unwrap(); + let event_loop = owned_client.sync_event_loop(|handle, _| { + let Some(event) = handle.get_root().recv_root_event() else { + return; + }; + match event { + stardust_xr_fusion::root::RootEvent::Ping { response } => response.send(Ok(())), + stardust_xr_fusion::root::RootEvent::Frame { info } => { + grid.frame(info); + } + stardust_xr_fusion::root::RootEvent::SaveState { response } => { + response.send(grid.save_state()); + } + } + }); tokio::select! { _ = tokio::signal::ctrl_c() => (), - e = event_loop => e??, + e = event_loop => e?, }; Ok(()) } @@ -51,7 +69,7 @@ struct AppGrid { //style: TextStyle, } impl AppGrid { - fn new(client: &Client) -> Self { + fn new(client: &ClientHandle) -> Self { let apps = get_desktop_files() .filter_map(|d| parse_desktop_file(d).ok()) .filter(|d| !d.no_display) @@ -74,7 +92,7 @@ impl AppGrid { AppGrid { apps } } } -impl RootHandler for AppGrid { +impl AppGrid { fn frame(&mut self, info: FrameInfo) { for app in &mut self.apps { app.frame(&info); @@ -198,7 +216,10 @@ impl App { // } fn frame(&mut self, info: &FrameInfo) { - let _ = self.grabbable.update(info); + if !self.grabbable.handle_events() { + return; + } + self.grabbable.frame(info); if self.grabbable.grab_action().actor_stopped() { self.grabbable.cancel_angular_velocity(); @@ -210,8 +231,8 @@ impl App { // } let application = self.application.clone(); - let space = self.content_parent().alias(); - let root = self.root.alias(); + let space = self.content_parent().clone(); + let root = self.root.clone(); tokio::task::spawn(async move { let Ok(transform) = space.get_transform(&root).await else { diff --git a/hexagon_launcher/Cargo.toml b/hexagon_launcher/Cargo.toml index f65d9f1..c90b4bb 100644 --- a/hexagon_launcher/Cargo.toml +++ b/hexagon_launcher/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "hexagon_launcher" version = "0.1.0" -edition = "2021" +edition = "2024" [dependencies] protostar = { path = "../protostar" } diff --git a/hexagon_launcher/src/app.rs b/hexagon_launcher/src/app.rs index ba56304..933908c 100644 --- a/hexagon_launcher/src/app.rs +++ b/hexagon_launcher/src/app.rs @@ -15,7 +15,7 @@ use stardust_xr_fusion::{ root::FrameInfo, spatial::{Spatial, SpatialAspect, SpatialRefAspect, Transform}, }; -use stardust_xr_molecules::{Grabbable, GrabbableSettings}; +use stardust_xr_molecules::{FrameSensitive as _, Grabbable, GrabbableSettings, UIElement}; use std::f32::consts::PI; use tween::{QuartInOut, Tweener}; @@ -160,7 +160,7 @@ impl App { } Ok(App { - parent: parent.alias(), + parent: parent.clone(), position, grabbable, _field: field, @@ -190,7 +190,9 @@ impl App { } pub fn frame(&mut self, info: &FrameInfo, state: &State) { - let _ = self.grabbable.update(info); + if self.grabbable.handle_events() { + self.grabbable.frame(info); + } if let Some(grabbable_move) = &mut self.grabbable_move { if !grabbable_move.is_finished() { @@ -265,8 +267,8 @@ impl App { self.grabbable_shrink = Some(Tweener::quart_in_out(APP_SIZE * 0.5, 0.0001, 0.25)); let application = self.application.clone(); - let space = self.content_parent().alias(); - let parent = self.parent.alias(); + let space = self.content_parent().clone(); + let parent = self.parent.clone(); //TODO: split the executable string for the args tokio::task::spawn(async move { diff --git a/hexagon_launcher/src/main.rs b/hexagon_launcher/src/main.rs index 0ae6030..160fe44 100644 --- a/hexagon_launcher/src/main.rs +++ b/hexagon_launcher/src/main.rs @@ -15,13 +15,14 @@ use stardust_xr_fusion::{ ResourceID, }, drawable::{MaterialParameter, Model, ModelPartAspect}, - node::{NodeError, NodeType}, - root::{ClientState, FrameInfo, RootAspect, RootHandler}, + node::NodeError, + root::{ClientState, FrameInfo, RootAspect, RootEvent}, spatial::{Spatial, SpatialAspect, Transform}, + ClientHandle, }; use stardust_xr_molecules::{ button::{Button, ButtonSettings}, - Grabbable, GrabbableSettings, PointerMode, + FrameSensitive, Grabbable, GrabbableSettings, PointerMode, UIElement, }; use std::{f32::consts::PI, sync::Arc, time::Duration}; @@ -41,19 +42,33 @@ async fn main() -> Result<()> { .with_env_filter(tracing_subscriber::EnvFilter::from_default_env()) .pretty() .init(); - let (client, event_loop) = Client::connect_with_async_loop().await?; + let owned_client = Client::connect().await?; + let client = owned_client.handle(); + let async_loop = owned_client.async_event_loop(); client - .set_base_prefixes(&[directory_relative_path!("../res")]) - .unwrap(); - - let _root = client .get_root() - .alias() - .wrap(AppHexGrid::new(&client).await)?; + .set_base_prefixes(&[directory_relative_path!("../res").to_string()]) + .unwrap(); + let mut grid = AppHexGrid::new(&client).await; + let mut owned_client = async_loop.stop().await.unwrap(); + let event_loop = owned_client.sync_event_loop(|handle, _| { + let Some(event) = handle.get_root().recv_root_event() else { + return; + }; + match event { + RootEvent::Ping { response } => response.send(Ok(())), + RootEvent::Frame { info } => { + grid.frame(info); + } + RootEvent::SaveState { response } => { + response.send(grid.save_state()); + } + } + }); tokio::select! { _ = tokio::signal::ctrl_c() => (), - e = event_loop => e??, + e = event_loop => e?, } Ok(()) } @@ -70,13 +85,14 @@ struct AppHexGrid { state: State, } impl AppHexGrid { - async fn new(client: &Arc) -> Self { - let state = client.get_state().data().unwrap_or_default(); + async fn new(client: &Arc) -> Self { + let client_state = client.get_root().get_state().await.unwrap(); + let state = client_state.data().unwrap_or_default(); let movable_root = Spatial::create(client.get_root(), Transform::identity(), false).unwrap(); - let button = CenterButton::new(client, client.get_state()).unwrap(); + let button = CenterButton::new(client, &client_state).unwrap(); tokio::time::sleep(Duration::from_millis(10)).await; // give it a bit of time to send the messages properly let mut desktop_files: Vec = get_desktop_files() @@ -120,7 +136,7 @@ impl AppHexGrid { } } } -impl RootHandler for AppHexGrid { +impl AppHexGrid { fn frame(&mut self, info: FrameInfo) { self.button.frame(&info); if self.button.button.pressed() { @@ -173,7 +189,7 @@ struct CenterButton { model: Model, } impl CenterButton { - fn new(client: &Arc, state: &ClientState) -> Result { + fn new(client: &Arc, state: &ClientState) -> Result { // (APP_SIZE + PADDING) / 2.0, let button = Button::create( client.get_root(), @@ -224,7 +240,9 @@ impl CenterButton { } fn frame(&mut self, info: &FrameInfo) { - let _ = self.grabbable.update(info); - self.button.update(); + if self.grabbable.handle_events() { + self.grabbable.frame(info); + } + self.button.handle_events(); } } diff --git a/protostar/Cargo.toml b/protostar/Cargo.toml index bfbaa3e..559abeb 100644 --- a/protostar/Cargo.toml +++ b/protostar/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "protostar" version = "0.4.0" -edition = "2021" +edition = "2024" [dependencies] clap = { version = "4.1.3", features = ["derive"] } diff --git a/protostar/src/application.rs b/protostar/src/application.rs index d54cfbc..6c865fe 100644 --- a/protostar/src/application.rs +++ b/protostar/src/application.rs @@ -44,9 +44,9 @@ impl Application { icon.and_then(|i| i.cached_process(preferred_px_size).ok()) } - pub fn launch(&self, launch_space: &impl SpatialRefAspect) -> NodeResult<()> { + pub fn launch(&self, launch_space: &T) -> NodeResult<()> { let client = launch_space.node().client()?; - let launch_space = launch_space.alias(); + let launch_space = launch_space.clone(); let executable = self .desktop_file @@ -66,10 +66,16 @@ impl Application { return; }; for (k, v) in connection_env.into_iter() { - std::env::set_var(k, v); + // this should be fine, probably? + unsafe { + std::env::set_var(k, v); + } } - std::env::set_var("STARDUST_STARTUP_TOKEN", startup_token); + // this should be fine, probably? + unsafe { + std::env::set_var("STARDUST_STARTUP_TOKEN", startup_token); + } // Strip/ignore field codes https://specifications.freedesktop.org/desktop-entry-spec/latest/ar01s07.html let re = Regex::new(r"%[fFuUdDnNickvm]").unwrap(); diff --git a/single/Cargo.toml b/single/Cargo.toml index 0f7e701..ecc123b 100644 --- a/single/Cargo.toml +++ b/single/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "single" version = "0.1.0" -edition = "2021" +edition = "2024" [dependencies] protostar = { path = "../protostar" } diff --git a/single/src/main.rs b/single/src/main.rs index be1fa87..253201e 100644 --- a/single/src/main.rs +++ b/single/src/main.rs @@ -4,7 +4,7 @@ use clap::Parser; use color_eyre::{eyre::Result, Report}; use manifest_dir_macros::directory_relative_path; use protostar::xdg::parse_desktop_file; -use stardust_xr_fusion::{client::Client, node::NodeType, root::RootAspect}; +use stardust_xr_fusion::{client::Client, root::RootAspect}; use std::path::PathBuf; use tracing_subscriber::EnvFilter; @@ -25,20 +25,38 @@ async fn main() -> Result<()> { .init(); color_eyre::install()?; let args = Args::parse(); - let (client, event_loop) = Client::connect_with_async_loop().await?; - client.set_base_prefixes(&[directory_relative_path!("../res")])?; + let owned_client = Client::connect().await?; + let client = owned_client.handle(); + let async_loop = owned_client.async_event_loop(); + client + .get_root() + .set_base_prefixes(&[directory_relative_path!("../res").to_string()])?; - let protostar = Single::create_from_desktop_file( + let mut protostar = Single::create_from_desktop_file( client.get_root(), [0.0, 0.0, 0.0], parse_desktop_file(args.desktop_file).map_err(Report::msg)?, )?; - let _root = client.get_root().alias().wrap(protostar)?; + let mut owned_client = async_loop.stop().await.unwrap(); + let event_loop = owned_client.sync_event_loop(|handle, _| { + let Some(event) = handle.get_root().recv_root_event() else { + return; + }; + match event { + stardust_xr_fusion::root::RootEvent::Ping { response } => response.send(Ok(())), + stardust_xr_fusion::root::RootEvent::Frame { info } => { + protostar.frame(info); + } + stardust_xr_fusion::root::RootEvent::SaveState { response } => { + response.send(protostar.save_state()); + } + } + }); tokio::select! { _ = tokio::signal::ctrl_c() => (), - e = event_loop => e??, + e = event_loop => e?, }; Ok(()) } diff --git a/single/src/single.rs b/single/src/single.rs index 05c6591..f15bdf1 100644 --- a/single/src/single.rs +++ b/single/src/single.rs @@ -12,10 +12,10 @@ use stardust_xr_fusion::{ }, fields::{Field, Shape}, node::NodeType, - root::{ClientState, FrameInfo, RootHandler}, + root::{ClientState, FrameInfo}, spatial::{Spatial, SpatialAspect, SpatialRefAspect, Transform}, }; -use stardust_xr_molecules::{Grabbable, GrabbableSettings}; +use stardust_xr_molecules::{FrameSensitive, Grabbable, GrabbableSettings, UIElement}; use std::f32::consts::PI; use tween::{QuartInOut, Tweener}; @@ -146,9 +146,11 @@ impl Single { self.grabbable.content_parent() } } -impl RootHandler for Single { - fn frame(&mut self, info: FrameInfo) { - let _ = self.grabbable.update(&info); +impl Single { + pub fn frame(&mut self, info: FrameInfo) { + if self.grabbable.handle_events() { + self.grabbable.frame(&info); + } if let Some(grabbable_move) = &mut self.grabbable_move { if !grabbable_move.is_finished() { @@ -224,8 +226,8 @@ impl RootHandler for Single { self.grabbable_shrink = Some(Tweener::quart_in_out(MODEL_SCALE, 0.0001, 0.25)); let application = self.application.clone(); - let space = self.content_parent().alias(); - let root = self.root.alias(); + let space = self.content_parent().clone(); + let root = self.root.clone(); //TODO: split the executable string for the args tokio::task::spawn(async move { @@ -244,7 +246,7 @@ impl RootHandler for Single { } } - fn save_state(&mut self) -> color_eyre::eyre::Result { + pub fn save_state(&mut self) -> color_eyre::eyre::Result { ClientState::from_root(self.content_parent()) } } diff --git a/sirius/Cargo.toml b/sirius/Cargo.toml index e0a17a9..fd57632 100644 --- a/sirius/Cargo.toml +++ b/sirius/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "sirius" version = "0.1.0" -edition = "2021" +edition = "2024" [dependencies] protostar = { path = "../protostar" } diff --git a/sirius/src/main.rs b/sirius/src/main.rs index d3d01cf..da68fcd 100644 --- a/sirius/src/main.rs +++ b/sirius/src/main.rs @@ -16,12 +16,12 @@ use stardust_xr_fusion::{ }, fields::{Field, Shape}, node::{NodeError, NodeType}, - root::{ClientState, FrameInfo, RootAspect, RootHandler}, - spatial::{Spatial, SpatialAspect, SpatialRefAspect, Transform}, + root::{ClientState, FrameInfo, RootAspect}, + spatial::{Spatial, SpatialAspect, SpatialRefAspect, Transform}, ClientHandle, }; use stardust_xr_molecules::{ button::{Button, ButtonSettings}, - Grabbable, GrabbableSettings, + FrameSensitive, Grabbable, GrabbableSettings, UIElement, }; use std::{f32::consts::PI, path::PathBuf}; @@ -50,17 +50,33 @@ async fn main() -> Result<()> { ) } - let (client, event_loop) = Client::connect_with_async_loop().await?; - client.set_base_prefixes(&[directory_relative_path!("../res")])?; - - let _wrapped_root = client + let owned_client = Client::connect().await?; + let client = owned_client.handle(); + let async_loop = owned_client.async_event_loop(); + client .get_root() - .alias() - .wrap(Sirius::new(&client, args)?)?; + .set_base_prefixes(&[directory_relative_path!("../res").to_string()])?; + let mut sirius = Sirius::new(&client, args)?; + + let mut owned_client = async_loop.stop().await.unwrap(); + let event_loop = owned_client.sync_event_loop(|handle, _| { + let Some(event) = handle.get_root().recv_root_event() else { + return; + }; + match event { + stardust_xr_fusion::root::RootEvent::Ping { response } => response.send(Ok(())), + stardust_xr_fusion::root::RootEvent::Frame { info } => { + sirius.frame(info); + } + stardust_xr_fusion::root::RootEvent::SaveState { response } => { + response.send(sirius.save_state()); + } + } + }); tokio::select! { _ = tokio::signal::ctrl_c() => (), - e = event_loop => e??, + e = event_loop => e?, } Ok(()) } @@ -78,7 +94,7 @@ struct Sirius { grabbable: Grabbable, } impl Sirius { - fn new(client: &Client, args: Args) -> Result { + fn new(client: &ClientHandle, args: Args) -> Result { let root = Spatial::create(client.get_root(), Transform::identity(), false).unwrap(); let field = @@ -141,15 +157,16 @@ impl Sirius { // } // } } -impl RootHandler for Sirius { +impl Sirius { fn frame(&mut self, info: FrameInfo) { for app in &mut self.clients { app.frame(&info); } - self.grabbable.update(&info).unwrap(); - self.button.update(); - if self.button.pressed() { + if self.grabbable.handle_events() { + self.grabbable.frame(&info); + }; + if self.button.handle_events() && self.button.pressed() { println!("Touch started"); self.state.visible = !self.state.visible; match self.state.visible { @@ -343,7 +360,7 @@ impl App { .ok() }); Ok(App { - parent: parent.alias(), + parent: parent.clone(), position, grabbable, _field: field, @@ -374,7 +391,10 @@ impl App { } fn frame(&mut self, info: &FrameInfo) { - let _ = self.grabbable.update(info); + if !self.grabbable.handle_events() { + return; + } + self.grabbable.frame(info); if let Some(grabbable_move) = &mut self.grabbable_move { if !grabbable_move.is_finished() { @@ -449,8 +469,8 @@ impl App { self.grabbable_shrink = Some(Tweener::quart_in_out(APP_SIZE * 0.5, 0.0001, 0.25)); let application = self.application.clone(); - let space = self.content_parent().alias(); - let parent = self.parent.alias(); + let space = self.content_parent().clone(); + let parent = self.parent.clone(); //TODO: split the executable string for the args tokio::task::spawn(async move {