From 1eed718860b90c70f8580c81308347def46cbfd3 Mon Sep 17 00:00:00 2001 From: Schmarni Date: Fri, 12 Jul 2024 08:20:50 +0200 Subject: [PATCH 1/2] partialy revert the scheduling changes and fix non xr crash Signed-off-by: Schmarni --- Cargo.lock | 2 +- crates/bevy_openxr/examples/raw_actions.rs | 14 ++- .../src/openxr/features/handtracking.rs | 11 +-- crates/bevy_openxr/src/openxr/init.rs | 61 +++++++++--- .../bevy_openxr/src/openxr/reference_space.rs | 11 +-- crates/bevy_openxr/src/openxr/render.rs | 8 +- crates/bevy_openxr/src/openxr/spaces.rs | 7 +- crates/bevy_xr/src/session.rs | 97 +++++++------------ 8 files changed, 111 insertions(+), 100 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ad819be..e933824 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -758,7 +758,7 @@ dependencies = [ "bevy", "bevy_mod_xr", "bevy_xr_utils", - "d3d12 0.19.0", + "d3d12 0.20.0", "jni 0.20.0", "ndk-context", "openxr", diff --git a/crates/bevy_openxr/examples/raw_actions.rs b/crates/bevy_openxr/examples/raw_actions.rs index 50df734..2cb9888 100644 --- a/crates/bevy_openxr/examples/raw_actions.rs +++ b/crates/bevy_openxr/examples/raw_actions.rs @@ -6,13 +6,12 @@ use bevy_mod_openxr::{ action_set_attaching::OxrAttachActionSet, action_set_syncing::{OxrActionSetSyncSet, OxrSyncActionSet}, add_xr_plugins, - init::create_xr_session, resources::OxrInstance, session::OxrSession, spaces::OxrSpaceExt, }; use bevy_mod_xr::{ - session::{session_available, XrCreateSession, XrTrackingRoot}, + session::{session_available, session_running, XrSessionCreated, XrTrackingRoot}, spaces::XrSpace, types::XrPose, }; @@ -21,9 +20,14 @@ use openxr::Posef; fn main() { let mut app = App::new(); app.add_plugins(add_xr_plugins(DefaultPlugins)); - app.add_systems(XrCreateSession, spawn_hands.after(create_xr_session)); - app.add_systems(XrCreateSession, attach_set.after(create_xr_session)); - app.add_systems(PreUpdate, sync_actions.before(OxrActionSetSyncSet)); + app.add_systems(XrSessionCreated, spawn_hands); + app.add_systems(XrSessionCreated, attach_set); + app.add_systems( + PreUpdate, + sync_actions + .before(OxrActionSetSyncSet) + .run_if(session_running), + ); app.add_systems(OxrSendActionBindings, suggest_action_bindings); app.add_systems(Startup, create_actions.run_if(session_available)); app.add_systems(Startup, setup); diff --git a/crates/bevy_openxr/src/openxr/features/handtracking.rs b/crates/bevy_openxr/src/openxr/features/handtracking.rs index ff4beee..df5141e 100644 --- a/crates/bevy_openxr/src/openxr/features/handtracking.rs +++ b/crates/bevy_openxr/src/openxr/features/handtracking.rs @@ -1,6 +1,6 @@ use bevy::prelude::*; use bevy_mod_xr::hands::{LeftHand, RightHand, XrHandBoneEntities, HAND_JOINT_COUNT}; -use bevy_mod_xr::session::{XrCreateSession, XrDestroySession, XrTrackingRoot}; +use bevy_mod_xr::session::{XrPreDestroySession, XrSessionCreated, XrTrackingRoot}; use bevy_mod_xr::spaces::{XrPrimaryReferenceSpace, XrReferenceSpace}; use bevy_mod_xr::{ hands::{HandBone, HandBoneRadius}, @@ -28,13 +28,8 @@ impl Plugin for HandTrackingPlugin { fn build(&self, app: &mut App) { app.add_systems(PreUpdate, locate_hands.run_if(session_running)); if self.default_hands { - app.add_systems(XrDestroySession, clean_up_default_hands) - .add_systems( - XrCreateSession, - (spawn_default_hands, apply_deferred) - .chain() - .after(create_xr_session), - ); + app.add_systems(XrPreDestroySession, clean_up_default_hands) + .add_systems(XrSessionCreated, spawn_default_hands); } } } diff --git a/crates/bevy_openxr/src/openxr/init.rs b/crates/bevy_openxr/src/openxr/init.rs index d1a5e54..1b1440f 100644 --- a/crates/bevy_openxr/src/openxr/init.rs +++ b/crates/bevy_openxr/src/openxr/init.rs @@ -105,14 +105,30 @@ impl Plugin for OxrInitPlugin { .add_systems( XrFirst, poll_events - .before(XrHandleEvents) + .in_set(XrHandleEvents::Poll) .run_if(not(state_equals(XrState::Unavailable))), ) - .add_systems(XrCreateSession, create_xr_session) - .add_systems(XrDestroySession, destroy_xr_session) - .add_systems(XrBeginSession, begin_xr_session) - .add_systems(XrEndSession, end_xr_session) - .add_systems(XrRequestExit, request_exit_xr_session) + .add_systems( + XrFirst, + ( + create_xr_session + .run_if(state_equals(XrState::Available)) + .run_if(on_event::()), + destroy_xr_session + .run_if(state_matches!(XrState::Exiting { .. })) + .run_if(on_event::()), + begin_xr_session + .run_if(state_equals(XrState::Ready)) + .run_if(on_event::()), + end_xr_session + .run_if(state_equals(XrState::Stopping)) + .run_if(on_event::()), + request_exit_xr_session + .run_if(session_created) + .run_if(on_event::()), + ) + .in_set(XrHandleEvents::SessionStateUpdateEvents), + ) .insert_resource(instance.clone()) .insert_resource(system_id) .insert_resource(XrState::Available) @@ -150,7 +166,7 @@ impl Plugin for OxrInitPlugin { fn finish(&self, app: &mut App) { app.sub_app_mut(RenderApp) - .add_systems(XrDestroySession, destroy_xr_session); + .add_systems(XrPreDestroySession, destroy_xr_session); } } @@ -468,9 +484,13 @@ pub fn create_xr_session(world: &mut World) { Err(e) => error!("Failed to initialize XrSession: {e}"), } world.insert_non_send_resource(chain); + world.run_schedule(XrSessionCreated); + world.send_event(XrSessionCreatedEvent); } pub fn destroy_xr_session(world: &mut World) { + world.run_schedule(XrPreDestroySession); + world.insert_resource(XrDestroySessionRender); world.remove_resource::(); world.remove_resource::(); world.remove_resource::(); @@ -480,18 +500,33 @@ pub fn destroy_xr_session(world: &mut World) { world.insert_resource(XrState::Available); } -pub fn begin_xr_session(session: Res, mut session_started: ResMut) { +pub fn begin_xr_session( + world: &mut World, + // session: Res, mut session_started: ResMut +) { let _span = info_span!("xr_begin_session"); - session + world + .get_resource::() + .unwrap() .begin(openxr::ViewConfigurationType::PRIMARY_STEREO) .expect("Failed to begin session"); - session_started.0 = true; + world.get_resource_mut::().unwrap().0 = true; + world.run_schedule(XrBeginSession); } -pub fn end_xr_session(session: Res, mut session_started: ResMut) { +pub fn end_xr_session( + world: &mut World, + // session: Res, mut session_started: ResMut +) { + // Maybe this could be an event? + world.run_schedule(XrEndSession); let _span = info_span!("xr_end_session"); - session.end().expect("Failed to end session"); - session_started.0 = false; + world + .get_resource::() + .unwrap() + .end() + .expect("Failed to end session"); + world.get_resource_mut::().unwrap().0 = false; } pub fn request_exit_xr_session(session: Res) { diff --git a/crates/bevy_openxr/src/openxr/reference_space.rs b/crates/bevy_openxr/src/openxr/reference_space.rs index e6321c8..4ed24c3 100644 --- a/crates/bevy_openxr/src/openxr/reference_space.rs +++ b/crates/bevy_openxr/src/openxr/reference_space.rs @@ -3,7 +3,7 @@ use bevy::{ render::{extract_resource::ExtractResourcePlugin, RenderApp}, }; use bevy_mod_xr::{ - session::{XrCreateSession, XrDestroySession}, + session::{XrPreDestroySession, XrSessionCreated}, spaces::{XrPrimaryReferenceSpace, XrReferenceSpace}, }; @@ -38,15 +38,12 @@ impl Plugin for OxrReferenceSpacePlugin { .insert_resource(OxrDefaultPrimaryReferenceSpaceType( self.default_primary_ref_space, )) - .add_systems( - XrCreateSession, - set_primary_ref_space.after(create_xr_session), - ) - .add_systems(XrDestroySession, cleanup); + .add_systems(XrSessionCreated, set_primary_ref_space) + .add_systems(XrPreDestroySession, cleanup); let render_app = app.sub_app_mut(RenderApp); - render_app.add_systems(XrDestroySession, cleanup); + render_app.add_systems(XrPreDestroySession, cleanup); } } diff --git a/crates/bevy_openxr/src/openxr/render.rs b/crates/bevy_openxr/src/openxr/render.rs index f213b46..3bc154b 100644 --- a/crates/bevy_openxr/src/openxr/render.rs +++ b/crates/bevy_openxr/src/openxr/render.rs @@ -13,7 +13,7 @@ use bevy::{ use bevy_mod_xr::{ camera::{XrCamera, XrCameraBundle, XrProjection}, session::{ - XrDestroySession, XrFirst, XrHandleEvents, XrRenderSet, XrRootTransform, XrTrackingRoot, + XrFirst, XrHandleEvents, XrPreDestroySession, XrRenderSet, XrRootTransform, XrTrackingRoot, }, spaces::XrPrimaryReferenceSpace, }; @@ -46,7 +46,7 @@ impl Plugin for OxrRenderPlugin { ExtractResourcePlugin::::default(), ExtractResourcePlugin::::default(), )) - .add_systems(XrDestroySession, clean_views) + .add_systems(XrPreDestroySession, clean_views) .add_systems( XrFirst, ( @@ -55,7 +55,7 @@ impl Plugin for OxrRenderPlugin { init_views.run_if(resource_added::), ) .chain() - .after(XrHandleEvents), + .in_set(XrHandleEvents::FrameLoop), ) .add_systems( PostUpdate, @@ -70,7 +70,7 @@ impl Plugin for OxrRenderPlugin { let render_app = app.sub_app_mut(RenderApp); render_app - .add_systems(XrDestroySession, clean_views) + .add_systems(XrPreDestroySession, clean_views) .add_systems( Render, ( diff --git a/crates/bevy_openxr/src/openxr/spaces.rs b/crates/bevy_openxr/src/openxr/spaces.rs index 0a6e60e..666ab7e 100644 --- a/crates/bevy_openxr/src/openxr/spaces.rs +++ b/crates/bevy_openxr/src/openxr/spaces.rs @@ -31,7 +31,12 @@ pub struct OxrSpatialPlugin; impl Plugin for OxrSpatialPlugin { fn build(&self, app: &mut App) { app.add_event::() - .add_systems(XrFirst, destroy_space_event.before(XrHandleEvents)) + .add_systems( + XrFirst, + destroy_space_event + .before(XrHandleEvents::Poll) + .run_if(session_available), + ) .add_systems( PreUpdate, update_space_transforms diff --git a/crates/bevy_xr/src/session.rs b/crates/bevy_xr/src/session.rs index 099672a..eca7997 100644 --- a/crates/bevy_xr/src/session.rs +++ b/crates/bevy_xr/src/session.rs @@ -10,7 +10,7 @@ pub struct XrCreateSessionEvent; /// A schedule thats ran whenever an [`XrCreateSessionEvent`] is recieved while the [`XrState`] is [`Available`](XrState::Available) #[derive(Clone, Copy, Default, PartialEq, Eq, Debug, Hash, ScheduleLabel)] -pub struct XrCreateSession; +pub struct XrSessionCreated; /// Event sent when [`XrCreateSession`] is ran #[derive(Event, Clone, Copy, Default)] @@ -27,7 +27,7 @@ pub struct XrDestroySessionRender; /// Schedule thats ran whenever an [`XrDestroySessionEvent`] is recieved while the [`XrState`] is [`Exiting`](XrState::Exiting). #[derive(Clone, Copy, Default, PartialEq, Eq, Debug, Hash, ScheduleLabel)] -pub struct XrDestroySession; +pub struct XrPreDestroySession; /// Event sent to instruct backends to begin an XR session. Only works when the [`XrState`] is [`Ready`](XrState::Ready). #[derive(Event, Clone, Copy, Default)] @@ -49,16 +49,19 @@ pub struct XrEndSession; #[derive(Event, Clone, Copy, Default)] pub struct XrRequestExitEvent; -#[derive(Clone, Copy, Default, PartialEq, Eq, Debug, Hash, ScheduleLabel)] -pub struct XrRequestExit; - /// Schedule ran before [`First`] to handle XR events. #[derive(Clone, Copy, Default, PartialEq, Eq, Debug, Hash, ScheduleLabel)] pub struct XrFirst; -/// System set for systems related to handling XR session events and updating the [`XrState`] +/// System sets for systems related to handling XR session events and updating the [`XrState`] #[derive(Debug, Hash, PartialEq, Eq, Clone, Copy, SystemSet)] -pub struct XrHandleEvents; +pub enum XrHandleEvents { + Poll, + ExitEvents, + SessionStateUpdateEvents, + Cleanup, + FrameLoop, +} /// System sets ran in the render world for XR. #[derive(Debug, Hash, PartialEq, Eq, Clone, Copy, SystemSet)] @@ -95,39 +98,33 @@ impl Plugin for XrSessionPlugin { .add_event::() .add_event::() .add_event::() - .init_schedule(XrCreateSession) - .init_schedule(XrDestroySession) + .init_schedule(XrSessionCreated) + .init_schedule(XrPreDestroySession) .init_schedule(XrBeginSession) .init_schedule(XrEndSession) - .init_schedule(XrRequestExit) .add_schedule(xr_first) - .add_systems( + .configure_sets( XrFirst, ( - exits_session_on_app_exit - .run_if(on_event::()) - .run_if(session_created), - reset_per_frame_resources, - run_xr_create_session - .run_if(state_equals(XrState::Available)) - .run_if(on_event::()), - run_xr_destroy_session - .run_if(state_matches!(XrState::Exiting { .. })) - .run_if(on_event::()), - run_xr_begin_session - .run_if(state_equals(XrState::Ready)) - .run_if(on_event::()), - run_xr_end_session - .run_if(state_equals(XrState::Stopping)) - .run_if(on_event::()), - run_xr_request_exit - .run_if(session_created) - .run_if(on_event::()), + XrHandleEvents::Poll, + XrHandleEvents::ExitEvents, + XrHandleEvents::SessionStateUpdateEvents, + XrHandleEvents::Cleanup, + XrHandleEvents::FrameLoop, ) - .chain() - .in_set(XrHandleEvents), + .chain(), + ) + .add_systems( + XrFirst, + exits_session_on_app_exit + .run_if(on_event::()) + .run_if(session_created) + .in_set(XrHandleEvents::ExitEvents), + ) + .add_systems( + XrFirst, + reset_per_frame_resources.in_set(XrHandleEvents::Cleanup), ); - app.world_mut() .resource_mut::() .labels @@ -156,14 +153,14 @@ impl Plugin for XrSessionPlugin { .add_systems( XrFirst, exits_session_on_app_exit - .before(XrHandleEvents) + .before(XrHandleEvents::ExitEvents) .run_if(on_event::().and_then(session_running)), ); let render_app = app.sub_app_mut(RenderApp); render_app - .init_schedule(XrDestroySession) + .init_schedule(XrPreDestroySession) .init_resource::() .configure_sets( Render, @@ -188,9 +185,9 @@ impl Plugin for XrSessionPlugin { .add_systems( Render, ( - run_xr_destroy_session - .run_if(resource_exists::) - .in_set(XrRenderSet::HandleEvents), + // run_xr_destroy_session + // .run_if(resource_exists::) + // .in_set(XrRenderSet::HandleEvents), reset_per_frame_resources.in_set(RenderSet::Cleanup), ), ); @@ -228,28 +225,6 @@ pub enum XrState { }, } -pub fn run_xr_create_session(world: &mut World) { - world.run_schedule(XrCreateSession); - world.send_event(XrSessionCreatedEvent); -} - -pub fn run_xr_destroy_session(world: &mut World) { - world.run_schedule(XrDestroySession); - world.insert_resource(XrDestroySessionRender); -} - -pub fn run_xr_begin_session(world: &mut World) { - world.run_schedule(XrBeginSession); -} - -pub fn run_xr_end_session(world: &mut World) { - world.run_schedule(XrEndSession); -} - -pub fn run_xr_request_exit(world: &mut World) { - world.run_schedule(XrRequestExit); -} - pub fn reset_per_frame_resources(world: &mut World) { world.remove_resource::(); } @@ -330,7 +305,7 @@ pub fn state_equals(status: XrState) -> impl FnMut(Option>) -> bool #[macro_export] macro_rules! state_matches { ($match:pat) => { - (|state: Option>| core::matches!(state.as_deref(), Some($match))) + |state: Option>| core::matches!(state.as_deref(), Some($match)) }; } From 45fc44db5c6b153481220f75fa369df5e71438f3 Mon Sep 17 00:00:00 2001 From: Schmarni Date: Mon, 15 Jul 2024 19:03:11 +0200 Subject: [PATCH 2/2] rename some schedules and fix comments Signed-off-by: Schmarni --- crates/bevy_openxr/src/openxr/init.rs | 4 ++-- crates/bevy_xr/src/session.rs | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/crates/bevy_openxr/src/openxr/init.rs b/crates/bevy_openxr/src/openxr/init.rs index 1b1440f..41a1943 100644 --- a/crates/bevy_openxr/src/openxr/init.rs +++ b/crates/bevy_openxr/src/openxr/init.rs @@ -511,7 +511,7 @@ pub fn begin_xr_session( .begin(openxr::ViewConfigurationType::PRIMARY_STEREO) .expect("Failed to begin session"); world.get_resource_mut::().unwrap().0 = true; - world.run_schedule(XrBeginSession); + world.run_schedule(XrPostSessionBegin); } pub fn end_xr_session( @@ -519,7 +519,7 @@ pub fn end_xr_session( // session: Res, mut session_started: ResMut ) { // Maybe this could be an event? - world.run_schedule(XrEndSession); + world.run_schedule(XrPreSessionEnd); let _span = info_span!("xr_end_session"); world .get_resource::() diff --git a/crates/bevy_xr/src/session.rs b/crates/bevy_xr/src/session.rs index eca7997..6b19b1e 100644 --- a/crates/bevy_xr/src/session.rs +++ b/crates/bevy_xr/src/session.rs @@ -12,7 +12,7 @@ pub struct XrCreateSessionEvent; #[derive(Clone, Copy, Default, PartialEq, Eq, Debug, Hash, ScheduleLabel)] pub struct XrSessionCreated; -/// Event sent when [`XrCreateSession`] is ran +/// Event sent after the XrSession was created. #[derive(Event, Clone, Copy, Default)] pub struct XrSessionCreatedEvent; @@ -25,7 +25,7 @@ pub struct XrDestroySessionEvent; #[derive(Resource, ExtractResource, Clone, Copy, Default)] pub struct XrDestroySessionRender; -/// Schedule thats ran whenever an [`XrDestroySessionEvent`] is recieved while the [`XrState`] is [`Exiting`](XrState::Exiting). +/// Schedule thats ran whenever the XrSession is about to be destroyed #[derive(Clone, Copy, Default, PartialEq, Eq, Debug, Hash, ScheduleLabel)] pub struct XrPreDestroySession; @@ -33,17 +33,17 @@ pub struct XrPreDestroySession; #[derive(Event, Clone, Copy, Default)] pub struct XrBeginSessionEvent; -/// Schedule thats ran whenever an [`XrBeginSessionEvent`] is recieved while the [`XrState`] is [`Ready`](XrState::Ready). +/// Schedule thats ran when the XrSession has begun. #[derive(Clone, Copy, Default, PartialEq, Eq, Debug, Hash, ScheduleLabel)] -pub struct XrBeginSession; +pub struct XrPostSessionBegin; /// Event sent to backends to end an XR session. Only works when the [`XrState`] is [`Stopping`](XrState::Stopping). #[derive(Event, Clone, Copy, Default)] pub struct XrEndSessionEvent; -/// Schedule thats rna whenever an [`XrEndSessionEvent`] is recieved while the [`XrState`] is [`Stopping`](XrState::Stopping). +/// Schedule thats rna whenever the XrSession is about to end #[derive(Clone, Copy, Default, PartialEq, Eq, Debug, Hash, ScheduleLabel)] -pub struct XrEndSession; +pub struct XrPreSessionEnd; /// Event sent to backends to request the [`XrState`] proceed to [`Exiting`](XrState::Exiting) and for the session to be exited. Can be called at any time a session exists. #[derive(Event, Clone, Copy, Default)] @@ -100,8 +100,8 @@ impl Plugin for XrSessionPlugin { .add_event::() .init_schedule(XrSessionCreated) .init_schedule(XrPreDestroySession) - .init_schedule(XrBeginSession) - .init_schedule(XrEndSession) + .init_schedule(XrPostSessionBegin) + .init_schedule(XrPreSessionEnd) .add_schedule(xr_first) .configure_sets( XrFirst,