From e3321c54fb0fa5c9489616154fd58bb55ba828e3 Mon Sep 17 00:00:00 2001 From: Schmarni Date: Mon, 16 Dec 2024 21:26:48 +0100 Subject: [PATCH] refactor: IT RUNS! Signed-off-by: Schmarni --- Cargo.toml | 1 + src/bevy_plugin.rs | 15 ++++++++- src/core/scenegraph.rs | 3 +- src/core/task.rs | 4 ++- src/main.rs | 53 ++++++++++++++++++++---------- src/nodes/drawable/text.rs | 5 +-- src/objects/input/sk_controller.rs | 36 ++++++++++---------- src/objects/mod.rs | 13 +++++--- src/oxr_render_plugin.rs | 6 ---- 9 files changed, 84 insertions(+), 52 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index c59168f..600a0a3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -43,6 +43,7 @@ bevy_mod_xr = { git = "https://github.com/Schmarni-Dev/bevy_openxr", branch = "0 bevy_mod_openxr = { git = "https://github.com/Schmarni-Dev/bevy_openxr", branch = "0.15rc" } bevy_xr_utils = { git = "https://github.com/Schmarni-Dev/bevy_openxr", branch = "0.15rc" } openxr = "0.19" +winit = { version = "0.30", default-features = false, features = [] } # small utility thingys once_cell = "1.19.0" nanoid = "0.4.0" diff --git a/src/bevy_plugin.rs b/src/bevy_plugin.rs index d727618..31f9c91 100644 --- a/src/bevy_plugin.rs +++ b/src/bevy_plugin.rs @@ -5,7 +5,7 @@ use bevy::{ prelude::*, }; use bevy_mod_openxr::session::OxrSession; -use bevy_mod_xr::session::{session_available, XrSessionCreated}; +use bevy_mod_xr::session::{session_available, XrFirst, XrSessionCreated}; use openxr::ReferenceSpaceType; use stardust_xr::values::color::{color_space::LinearRgb, AlphaColor, Rgb}; @@ -18,6 +18,8 @@ pub struct DbusConnection(pub zbus::Connection); #[derive(ScheduleLabel, Hash, Debug, PartialEq, Eq, Clone)] pub struct InputUpdate; +#[derive(ScheduleLabel, Hash, Debug, PartialEq, Eq, Clone)] +pub struct StardustFirst; impl Plugin for StardustBevyPlugin { fn build(&self, app: &mut App) { app.init_schedule(StardustExtract); @@ -29,6 +31,17 @@ impl Plugin for StardustBevyPlugin { let mut schedule = Schedule::new(InputUpdate); schedule.set_executor_kind(ExecutorKind::Simple); app.add_schedule(schedule); + + let mut schedule = Schedule::new(StardustFirst); + schedule.set_executor_kind(ExecutorKind::Simple); + app.add_schedule(schedule); + + let labels = &mut app.world_mut().resource_mut::().labels; + let xr_first_intern = (XrFirst).intern(); + if labels.remove(0) != xr_first_intern { + panic!("first schedule was not XrFirst!"); + } + labels.insert(0, (StardustFirst).intern()); } } diff --git a/src/core/scenegraph.rs b/src/core/scenegraph.rs index 745b3c3..88e50e0 100644 --- a/src/core/scenegraph.rs +++ b/src/core/scenegraph.rs @@ -1,6 +1,7 @@ use crate::core::error::Result; use crate::nodes::alias::get_original; use crate::nodes::Node; +use crate::TOKIO; use crate::{core::client::Client, nodes::Message}; use once_cell::sync::OnceCell; use parking_lot::Mutex; @@ -68,7 +69,7 @@ impl MethodResponseSender { self, f: impl Future)>> + Send + 'static, ) { - tokio::task::spawn(async move { self.0.send(map_method_return(f.await)) }); + TOKIO.spawn(async move { self.0.send(map_method_return(f.await)) }); } } fn map_method_return( diff --git a/src/core/task.rs b/src/core/task.rs index 43bffd8..bb8941c 100644 --- a/src/core/task.rs +++ b/src/core/task.rs @@ -2,6 +2,8 @@ use color_eyre::eyre::Result; use std::future::Future; use tokio::task::JoinHandle; +use crate::TOKIO; + #[allow(unused_variables)] pub fn new< F: FnOnce() -> S, @@ -13,7 +15,7 @@ pub fn new< async_future: A, ) -> Result> { #[cfg(not(feature = "profile_tokio"))] - let result = Ok(tokio::task::spawn(async_future)); + let result = Ok(TOKIO.spawn(async_future)); #[cfg(feature = "profile_tokio")] let result = tokio::task::Builder::new() .name(name_fn().as_ref()) diff --git a/src/main.rs b/src/main.rs index 9f7755b..8ae6e12 100644 --- a/src/main.rs +++ b/src/main.rs @@ -12,7 +12,7 @@ use crate::core::destroy_queue; // use crate::nodes::items::camera; use crate::nodes::{audio, drawable, input}; -use bevy::app::{App, PluginGroup, Startup, Update}; +use bevy::app::{App, PluginGroup, PluginsState, Startup, Update}; use bevy::asset::{AssetServer, Handle}; use bevy::core_pipeline::Skybox; use bevy::image::Image; @@ -20,12 +20,12 @@ use bevy::log::LogPlugin; use bevy::pbr::StandardMaterial; use bevy::prelude::{ on_event, resource_added, Camera3d, ClearColor, Commands, Entity, EventReader, - IntoSystemConfigs, Local, Query, Res, Resource, With, + IntoSystemConfigs, Local, Query, Res, Resource, With, World, }; use bevy::render::pipelined_rendering::PipelinedRenderingPlugin; use bevy::time::Time; use bevy::utils::default; -use bevy::winit::{WakeUp, WinitPlugin}; +use bevy::winit::{EventLoopProxyWrapper, WakeUp, WinitPlugin}; use bevy::DefaultPlugins; use bevy_mod_openxr::action_set_syncing::{OxrActionSyncingPlugin, OxrSyncActionSet}; use bevy_mod_openxr::exts::OxrExtensions; @@ -37,7 +37,7 @@ use bevy_mod_openxr::session::OxrSession; use bevy_mod_openxr::types::{AppInfo, Version}; use bevy_mod_openxr::{add_xr_plugins, openxr_session_running}; use bevy_mod_xr::session::{XrFirst, XrSessionCreated, XrSessionPlugin}; -use bevy_plugin::{DbusConnection, InputUpdate, StardustBevyPlugin}; +use bevy_plugin::{DbusConnection, InputUpdate, StardustBevyPlugin, StardustFirst}; use clap::Parser; use core::client::Client; use core::task; @@ -54,12 +54,11 @@ use oxr_render_plugin::StardustOxrRenderPlugin; use session::{launch_start, save_session}; use stardust_xr::schemas::dbus::object_registry::ObjectRegistry; use stardust_xr::server; +use std::ops::Deref; use std::path::PathBuf; use std::sync::Arc; -use std::time::Duration; use tokio::net::UnixListener; use tokio::sync::Notify; -use tracing::metadata::LevelFilter; use tracing::{debug_span, error, info, warn}; use tracing_subscriber::{fmt, prelude::*, EnvFilter}; use zbus::fdo::ObjectManager; @@ -99,10 +98,26 @@ struct CliArgs { } static STARDUST_INSTANCE: OnceCell = OnceCell::new(); +static TOKIO: RuntimeWrapper = RuntimeWrapper(OnceCell::new()); -// #[tokio::main] -#[tokio::main(flavor = "current_thread")] -async fn main() { +struct RuntimeWrapper(OnceCell); +impl Deref for RuntimeWrapper { + type Target = tokio::runtime::Runtime; + + fn deref(&self) -> &Self::Target { + self.0.get().unwrap() + } +} + +fn main() { + let runtime = tokio::runtime::Builder::new_multi_thread() + .enable_all() + .build() + .unwrap(); + TOKIO.0.set(runtime).unwrap(); + TOKIO.block_on(setup()) +} +async fn setup() { color_eyre::install().unwrap(); let registry = tracing_subscriber::registry(); @@ -245,7 +260,7 @@ fn stereokit_loop( exts }, blend_modes: Some(vec![ - openxr::EnvironmentBlendMode::ALPHA_BLEND, + // openxr::EnvironmentBlendMode::ALPHA_BLEND, openxr::EnvironmentBlendMode::OPAQUE, ]), synchronous_pipeline_compilation: false, @@ -262,6 +277,7 @@ fn stereokit_loop( }); } bevy_app.add_event::(); + bevy_app.add_plugins(bevy_xr_utils::hand_gizmos::HandGizmosPlugin); } bevy_app.add_plugins(StardustBevyPlugin); bevy_app.add_plugins(( @@ -343,16 +359,16 @@ fn stereokit_loop( } } - debug_span!("bevy").in_scope(|| loop { + bevy_app.insert_resource(objects); + + let bevy_step = |world: &mut World| { let _span = debug_span!("Bevy step"); let _span = _span.enter(); - // camera::update(token); #[cfg(feature = "wayland")] wayland.frame_event(); destroy_queue::clear(); - let world = bevy_app.world_mut(); let time = world.get_resource_mut::().map(|mut s| { let t = openxr::Time::from_nanos( s.predicted_display_time.as_nanos() + s.predicted_display_period.as_nanos(), @@ -369,7 +385,9 @@ fn stereokit_loop( } world.run_schedule(InputUpdate); let session = world.remove_resource::(); + let mut objects = world.remove_resource::().unwrap(); objects.update(session.as_deref(), time); + world.insert_resource(objects); if let Some(session) = session { world.insert_resource(session); } @@ -382,15 +400,14 @@ fn stereokit_loop( let mut waiter = world.remove_resource::().unwrap(); let state = waiter.wait().unwrap(); world.insert_resource(OxrFrameState(state)); + world.insert_resource(waiter); world.run_system_cached(update_cameras); } #[cfg(feature = "wayland")] wayland.update(); - bevy_app.update(); - if let Some(exit) = bevy_app.should_exit() { - break; - } - }); + }; + bevy_app.add_systems(StardustFirst, bevy_step); + bevy_app.run(); #[cfg(feature = "wayland")] drop(wayland); diff --git a/src/nodes/drawable/text.rs b/src/nodes/drawable/text.rs index f5e2dcb..9b5bd25 100644 --- a/src/nodes/drawable/text.rs +++ b/src/nodes/drawable/text.rs @@ -8,7 +8,7 @@ use crate::{ DefaultMaterial, }; use bevy::{ - app::{App, Plugin}, + app::{App, Plugin, PostUpdate, PreUpdate}, asset::{AssetServer, Assets, RenderAssetUsages}, color::Color, image::Image, @@ -54,7 +54,8 @@ impl Plugin for StardustTextPlugin { let (tx, rx) = crossbeam_channel::unbounded(); SPAWN_TEXT_SENDER.set(tx); app.insert_resource(SpawnTextReader(rx)); - todo!() + app.add_systems(PostUpdate, update_text); + app.add_systems(PreUpdate, spawn_text); } } diff --git a/src/objects/input/sk_controller.rs b/src/objects/input/sk_controller.rs index eb1d75b..055d1ef 100644 --- a/src/objects/input/sk_controller.rs +++ b/src/objects/input/sk_controller.rs @@ -111,24 +111,24 @@ fn update_controllers( .spatial .set_local_transform(world_transform); } - controller.datamap.select = controller - .actions - .trigger - .state(&session, openxr::Path::NULL) - .map(|v| v.current_state) - .unwrap_or_default(); - controller.datamap.grab = controller - .actions - .grip - .state(&session, openxr::Path::NULL) - .map(|v| v.current_state) - .unwrap_or_default(); - controller.datamap.scroll = controller - .actions - .stick - .state(&session, openxr::Path::NULL) - .map(|v| v.current_state.to_vec2()) - .unwrap_or_default(); + // controller.datamap.select = controller + // .actions + // .trigger + // .state(&session, openxr::Path::NULL) + // .map(|v| v.current_state) + // .unwrap_or_default(); + // controller.datamap.grab = controller + // .actions + // .grip + // .state(&session, openxr::Path::NULL) + // .map(|v| v.current_state) + // .unwrap_or_default(); + // controller.datamap.scroll = controller + // .actions + // .stick + // .state(&session, openxr::Path::NULL) + // .map(|v| v.current_state.to_vec2()) + // .unwrap_or_default(); *controller.input.datamap.lock() = Datamap::from_typed(&controller.datamap).unwrap(); // remove the capture when it's removed from captures list diff --git a/src/objects/mod.rs b/src/objects/mod.rs index b5b29d2..430bab7 100644 --- a/src/objects/mod.rs +++ b/src/objects/mod.rs @@ -7,7 +7,9 @@ use crate::{ spatial::{Spatial, EXPORTED_SPATIALS}, Node, OwnedNode, }, + TOKIO, }; +use bevy::prelude::Resource; use bevy_mod_openxr::helper_traits::{ToQuat, ToVec3}; use glam::{vec3, Mat4}; use input::{ @@ -46,6 +48,7 @@ struct ControllerInput { scroll: openxr::Action, } +#[derive(Resource)] pub struct ServerObjects { connection: Connection, hmd: (Arc, ObjectHandle), @@ -76,7 +79,7 @@ impl ServerObjects { // let play_space = None; // if play_space.is_some() { // let dbus_connection = connection.clone(); - // tokio::task::spawn(async move { + // TOKIO.spawn(async move { // PlaySpaceBounds::create(&dbus_connection).await; // dbus_connection // .request_name("org.stardustxr.PlaySpace") @@ -85,7 +88,7 @@ impl ServerObjects { // }); // } - tokio::task::spawn({ + TOKIO.spawn({ let connection = connection.clone(); async move { connection @@ -224,7 +227,7 @@ impl Drop for ObjectHandle { fn drop(&mut self) { let connection = self.0.clone(); let object_path = self.1.clone(); - tokio::task::spawn(async move { + TOKIO.spawn(async move { connection.object_server().remove::(object_path); }); } @@ -238,7 +241,7 @@ impl SpatialRef { let uid: u64 = rand::random(); EXPORTED_SPATIALS.lock().insert(uid, node.0.clone()); - tokio::task::spawn({ + TOKIO.spawn({ let connection = connection.clone(); let path = path.to_string(); async move { @@ -280,7 +283,7 @@ impl FieldRef { let uid: u64 = rand::random(); EXPORTED_FIELDS.lock().insert(uid, node.0.clone()); - tokio::task::spawn({ + TOKIO.spawn({ let connection = connection.clone(); let path = path.to_string(); async move { diff --git a/src/oxr_render_plugin.rs b/src/oxr_render_plugin.rs index b4e73da..ccac1ff 100644 --- a/src/oxr_render_plugin.rs +++ b/src/oxr_render_plugin.rs @@ -49,12 +49,6 @@ impl Plugin for StardustOxrRenderPlugin { ) .init_resource::(); - let labels = &mut app.world_mut().resource_mut::().labels; - let xr_first_intern = (XrFirst).intern(); - if labels.remove(0) != xr_first_intern { - panic!("first schedule was not XrFirst!"); - } - let render_app = app.sub_app_mut(RenderApp); render_app