diff --git a/crates/bevy_openxr/examples/sessions.rs b/crates/bevy_openxr/examples/sessions.rs index c6b7d1e..1b4e480 100644 --- a/crates/bevy_openxr/examples/sessions.rs +++ b/crates/bevy_openxr/examples/sessions.rs @@ -20,15 +20,19 @@ fn handle_input( mut create: EventWriter, ) { if keys.just_pressed(KeyCode::KeyE) { + info!("sending end"); end.send_default(); } if keys.just_pressed(KeyCode::KeyD) { + info!("sending destroy"); destroy.send_default(); } if keys.just_pressed(KeyCode::KeyB) { + info!("sending begin"); begin.send_default(); } if keys.just_pressed(KeyCode::KeyC) { + info!("sending create"); create.send_default(); } } diff --git a/crates/bevy_openxr/src/openxr/features/handtracking.rs b/crates/bevy_openxr/src/openxr/features/handtracking.rs index 9c1c73a..fa87a87 100644 --- a/crates/bevy_openxr/src/openxr/features/handtracking.rs +++ b/crates/bevy_openxr/src/openxr/features/handtracking.rs @@ -2,7 +2,7 @@ use bevy::prelude::*; use bevy_xr::hands::{LeftHand, RightHand}; use bevy_xr::{ hands::{HandBone, HandBoneRadius}, - session::{session_running, XrSessionCreated, XrSessionEnding}, + session::{session_running, XrSessionCreated, XrSessionExiting}, }; use openxr::SpaceLocationFlags; @@ -28,7 +28,7 @@ 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(XrSessionEnding, clean_up_default_hands); + app.add_systems(XrSessionExiting, clean_up_default_hands); app.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 c21920a..aee5bf8 100644 --- a/crates/bevy_openxr/src/openxr/init.rs +++ b/crates/bevy_openxr/src/openxr/init.rs @@ -131,7 +131,7 @@ impl Plugin for OxrInitPlugin { .run_if(status_equals(XrStatus::Ready)), end_xr_session .run_if(on_event::()) - .run_if(status_equals(XrStatus::Stopping)), + .run_if(status_equals(XrStatus::Running)), destroy_xr_session .run_if(on_event::()) .run_if(status_equals(XrStatus::Exiting)), @@ -489,8 +489,11 @@ pub fn begin_xr_session(session: Res, session_started: Res, session_started: Res) { let _span = info_span!("xr_end_session"); - session.end().expect("Failed to end session"); - session_started.set(false); + session + .request_exit() + .expect("Failed to request session exit"); + // session.end().expect("Failed to end session"); + // session_started.set(false); } /// This system transfers important render resources from the main world to the render world when a session is created. diff --git a/crates/bevy_openxr/src/openxr/reference_space.rs b/crates/bevy_openxr/src/openxr/reference_space.rs index 14b1b5f..2516c03 100644 --- a/crates/bevy_openxr/src/openxr/reference_space.rs +++ b/crates/bevy_openxr/src/openxr/reference_space.rs @@ -5,7 +5,7 @@ use bevy::{ render::extract_resource::{ExtractResource, ExtractResourcePlugin}, }; use bevy_xr::session::{ - status_changed_to, XrRenderSessionEnding, XrSessionCreated, XrSessionEnding, XrStatus, + status_changed_to, XrRenderSessionEnding, XrSessionCreated, XrSessionExiting, XrStatus, }; use crate::{init::OxrPreUpdateSet, session::OxrSession}; @@ -36,7 +36,7 @@ impl Plugin for OxrReferenceSpacePlugin { app.insert_resource(OxrDefaultPrimaryReferenceSpaceType(self.default_primary_ref_space)); app.add_plugins(ExtractResourcePlugin::::default()); app.add_systems(XrSessionCreated, set_primary_ref_space); - app.add_systems(XrSessionEnding, cleanup); + app.add_systems(XrSessionExiting, cleanup); app.add_systems(XrRenderSessionEnding, cleanup); } } diff --git a/crates/bevy_openxr/src/openxr/render.rs b/crates/bevy_openxr/src/openxr/render.rs index eba6f90..d7a07e7 100644 --- a/crates/bevy_openxr/src/openxr/render.rs +++ b/crates/bevy_openxr/src/openxr/render.rs @@ -12,11 +12,10 @@ use bevy::{ }; use bevy_xr::{ camera::{XrCamera, XrCameraBundle, XrProjection}, - session::session_running, + session::{session_running, XrSessionExiting}, }; use openxr::ViewStateFlags; - use crate::{ init::{session_started, OxrPreUpdateSet, OxrTrackingRoot}, layer_builder::ProjectionLayer, session::OxrSession, @@ -45,7 +44,8 @@ impl Plugin for OxrRenderPlugin { .run_if(session_running) .before(TransformSystem::TransformPropagate), ) - .add_systems(Last, wait_frame.run_if(session_started)); + .add_systems(Last, wait_frame.run_if(session_started)) + .add_systems(XrSessionExiting, clean_views); app.sub_app_mut(RenderApp) .add_systems( Render, @@ -73,6 +73,17 @@ impl Plugin for OxrRenderPlugin { pub const XR_TEXTURE_INDEX: u32 = 3383858418; +pub fn clean_views( + mut manual_texture_views: ResMut, + mut commands: Commands, + cam_query: Query<(Entity, &XrCamera)>, +) { + for (e, cam) in &cam_query { + manual_texture_views.remove(&ManualTextureViewHandle(XR_TEXTURE_INDEX + cam.0)); + commands.entity(e).despawn_recursive(); + } +} + // TODO: have cameras initialized externally and then recieved by this function. /// This is needed to properly initialize the texture views so that bevy will set them to the correct resolution despite them being updated in the render world. pub fn init_views( diff --git a/crates/bevy_openxr/src/openxr/resources.rs b/crates/bevy_openxr/src/openxr/resources.rs index f20766a..15786d9 100644 --- a/crates/bevy_openxr/src/openxr/resources.rs +++ b/crates/bevy_openxr/src/openxr/resources.rs @@ -218,6 +218,11 @@ pub struct OxrFrameWaiter(pub openxr::FrameWaiter); /// Graphics agnostic wrapper around [openxr::Swapchain] #[derive(Resource)] pub struct OxrSwapchain(pub GraphicsWrap); +impl Drop for OxrSwapchain { + fn drop(&mut self) { + info!("Dropping Swapchain"); + } +} impl GraphicsType for OxrSwapchain { type Inner = openxr::Swapchain; @@ -287,6 +292,11 @@ impl OxrSwapchain { /// Stores the generated swapchain images. #[derive(Debug, Deref, Resource, Clone)] pub struct OxrSwapchainImages(pub Arc>); +impl Drop for OxrSwapchainImages { + fn drop(&mut self) { + info!("Dropping Swapchain Images"); + } +} /// Thread safe wrapper around [openxr::Space] representing the stage. // #[derive(Deref, Clone, Resource)] diff --git a/crates/bevy_openxr/src/openxr/session.rs b/crates/bevy_openxr/src/openxr/session.rs index bba1f9a..76088b4 100644 --- a/crates/bevy_openxr/src/openxr/session.rs +++ b/crates/bevy_openxr/src/openxr/session.rs @@ -1,9 +1,13 @@ use crate::init::OxrPreUpdateSet; -use crate::resources::{OxrCleanupSession, OxrPassthrough, OxrPassthroughLayer, OxrSwapchain}; +use crate::resources::{ + OxrCleanupSession, OxrPassthrough, OxrPassthroughLayer, OxrSessionStarted, OxrSwapchain, +}; use crate::types::{Result, SwapchainCreateInfo}; use bevy::ecs::system::{RunSystemOnce, SystemState}; use bevy::prelude::*; -use bevy_xr::session::{XrRenderSessionEnding, XrSessionCreated, XrSessionEnding}; +use bevy_xr::session::{ + status_changed_to, XrRenderSessionEnding, XrSessionCreated, XrSessionExiting, XrStatus, +}; use openxr::AnyGraphics; use crate::graphics::{graphics_match, GraphicsExt, GraphicsType, GraphicsWrap}; @@ -23,13 +27,23 @@ impl Plugin for OxrSessionPlugin { PreUpdate, run_session_status_schedules.in_set(OxrPreUpdateSet::HandleEvents), ); - app.add_systems(XrSessionEnding, clean_session); + app.add_systems(XrSessionExiting, clean_session); app.add_systems(XrRenderSessionEnding, |mut cmds: Commands| { - cmds.remove_resource::() + cmds.remove_resource::(); + cmds.remove_resource::(); }); + app.add_systems( + PreUpdate, + handle_stopping_state.run_if(status_changed_to(XrStatus::Stopping)), + ); } } +fn handle_stopping_state(session: Res, session_started: Res) { + session.end().expect("Failed to end session"); + session_started.set(false); +} + fn clean_session(mut cmds: Commands) { cmds.remove_resource::(); cmds.insert_resource(OxrCleanupSession(true)); @@ -46,7 +60,7 @@ fn run_session_status_schedules(world: &mut World) { world.run_system_once(apply_deferred); } OxrSessionStatusEvent::AboutToBeDestroyed => { - world.run_schedule(XrSessionEnding); + world.run_schedule(XrSessionExiting); world.run_system_once(apply_deferred); } } diff --git a/crates/bevy_xr/src/session.rs b/crates/bevy_xr/src/session.rs index dae1cd0..004d2be 100644 --- a/crates/bevy_xr/src/session.rs +++ b/crates/bevy_xr/src/session.rs @@ -1,13 +1,13 @@ use std::sync::{Arc, RwLock}; -use bevy::{ecs::schedule::ScheduleLabel, prelude::*}; +use bevy::{ecs::schedule::ScheduleLabel, prelude::*, render::RenderApp}; pub struct XrSessionPlugin; impl Plugin for XrSessionPlugin { fn build(&self, app: &mut App) { app.init_schedule(XrSessionCreated); - app.init_schedule(XrSessionEnding); + app.init_schedule(XrSessionExiting); app.add_event::() .add_event::() .add_event::() @@ -20,7 +20,9 @@ impl Plugin for XrSessionPlugin { } fn finish(&self, app: &mut App) { // This is in finnish because we need the RenderPlugin to already be added. - app.init_schedule(XrRenderSessionEnding); + app.get_sub_app_mut(RenderApp) + .unwrap() + .init_schedule(XrRenderSessionEnding); } } @@ -28,7 +30,7 @@ impl Plugin for XrSessionPlugin { pub struct XrSessionCreated; #[derive(ScheduleLabel, Clone, Copy, PartialEq, Eq, Debug, Hash)] -pub struct XrSessionEnding; +pub struct XrSessionExiting; #[derive(ScheduleLabel, Clone, Copy, PartialEq, Eq, Debug, Hash)] pub struct XrRenderSessionEnding; @@ -93,7 +95,7 @@ pub fn handle_session( } XrStatus::Running => {} XrStatus::Stopping => { - end_session.send_default(); + // end_session.send_default(); } XrStatus::Exiting => { destroy_session.send_default();