diff --git a/crates/bevy_openxr/examples/sessions.rs b/crates/bevy_openxr/examples/sessions.rs index 1b4e480..e3ca3e5 100644 --- a/crates/bevy_openxr/examples/sessions.rs +++ b/crates/bevy_openxr/examples/sessions.rs @@ -2,6 +2,7 @@ use bevy::prelude::*; use bevy_openxr::add_xr_plugins; +use bevy_xr::session::{XrSharedStatus, XrStatus}; fn main() { App::new() @@ -18,6 +19,7 @@ fn handle_input( mut destroy: EventWriter, mut begin: EventWriter, mut create: EventWriter, + state: Res, ) { if keys.just_pressed(KeyCode::KeyE) { info!("sending end"); @@ -35,6 +37,9 @@ fn handle_input( info!("sending create"); create.send_default(); } + if keys.just_pressed(KeyCode::KeyI) { + info!("current state: {:?}", state.get()); + } } /// set up a simple 3D scene diff --git a/crates/bevy_openxr/src/openxr/features/handtracking.rs b/crates/bevy_openxr/src/openxr/features/handtracking.rs index fa87a87..f681cda 100644 --- a/crates/bevy_openxr/src/openxr/features/handtracking.rs +++ b/crates/bevy_openxr/src/openxr/features/handtracking.rs @@ -115,7 +115,8 @@ fn clean_up_default_hands( query: Query, With)>>, ) { for e in &query { - cmds.entity(e).despawn(); + info!("removing_hand_entity"); + cmds.entity(e).despawn_recursive(); } } diff --git a/crates/bevy_openxr/src/openxr/init.rs b/crates/bevy_openxr/src/openxr/init.rs index aee5bf8..0306feb 100644 --- a/crates/bevy_openxr/src/openxr/init.rs +++ b/crates/bevy_openxr/src/openxr/init.rs @@ -24,6 +24,7 @@ use bevy_xr::session::CreateXrSession; use bevy_xr::session::DestroyXrSession; use bevy_xr::session::EndXrSession; use bevy_xr::session::XrRenderSessionEnding; +use bevy_xr::session::XrSessionExiting; use bevy_xr::session::XrSharedStatus; use bevy_xr::session::XrStatus; use bevy_xr::session::XrStatusChanged; @@ -132,13 +133,11 @@ impl Plugin for OxrInitPlugin { end_xr_session .run_if(on_event::()) .run_if(status_equals(XrStatus::Running)), - destroy_xr_session - .run_if(on_event::()) - .run_if(status_equals(XrStatus::Exiting)), ) .in_set(OxrPreUpdateSet::HandleEvents), ), ) + .add_systems(XrSessionExiting, destroy_xr_session) .add_systems( PostUpdate, update_root_transform.after(TransformSystem::TransformPropagate), @@ -456,6 +455,7 @@ pub fn create_xr_session( system_id: Res, mut commands: Commands, ) { + info!("creating session!"); match init_xr_session( device.wgpu_device(), &instance, @@ -481,6 +481,7 @@ pub fn create_xr_session( pub fn begin_xr_session(session: Res, session_started: Res) { let _span = info_span!("xr_begin_session"); + info!("begining session!"); session .begin(openxr::ViewConfigurationType::PRIMARY_STEREO) .expect("Failed to begin session"); @@ -489,6 +490,7 @@ pub fn begin_xr_session(session: Res, session_started: Res, session_started: Res) { let _span = info_span!("xr_end_session"); + info!("ending session!"); session .request_exit() .expect("Failed to request session exit"); @@ -542,6 +544,7 @@ pub fn poll_events( SessionState::IDLE => { if status.get() == XrStatus::Available { session_status_events.send(OxrSessionStatusEvent::Created); + info!("sending create info"); } XrStatus::Idle } @@ -552,6 +555,7 @@ pub fn poll_events( SessionState::STOPPING => XrStatus::Stopping, SessionState::EXITING | SessionState::LOSS_PENDING => { session_status_events.send(OxrSessionStatusEvent::AboutToBeDestroyed); + info!("sending destroy info"); XrStatus::Exiting } _ => unreachable!(), @@ -583,4 +587,10 @@ pub fn destroy_xr_session_render(world: &mut World) { world.remove_resource::(); world.run_schedule(XrRenderSessionEnding); world.run_system_once(apply_deferred); + if let Some(sess) = world.remove_resource::() { + unsafe { + (sess.instance().fp().destroy_session)(sess.as_raw()); + } + Box::leak(Box::new(sess)); + } } diff --git a/crates/bevy_openxr/src/openxr/resources.rs b/crates/bevy_openxr/src/openxr/resources.rs index 15786d9..db8b07d 100644 --- a/crates/bevy_openxr/src/openxr/resources.rs +++ b/crates/bevy_openxr/src/openxr/resources.rs @@ -148,7 +148,6 @@ impl OxrInstance { } } - /// Graphics agnostic wrapper around [openxr::FrameStream] #[derive(Resource)] pub struct OxrFrameStream(pub GraphicsWrap); @@ -283,20 +282,15 @@ impl OxrSwapchain { images.push(Api::to_wgpu_img(image, device, format, resolution)?); } } - Ok(OxrSwapchainImages(images.into())) + Ok(OxrSwapchainImages(images.leak())) } ) } } /// 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"); - } -} +#[derive(Debug, Deref, Resource, Clone, Copy)] +pub struct OxrSwapchainImages(pub &'static [wgpu::Texture]); /// 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 76088b4..9a65ae8 100644 --- a/crates/bevy_openxr/src/openxr/session.rs +++ b/crates/bevy_openxr/src/openxr/session.rs @@ -5,8 +5,11 @@ use crate::resources::{ use crate::types::{Result, SwapchainCreateInfo}; use bevy::ecs::system::{RunSystemOnce, SystemState}; use bevy::prelude::*; +use bevy::render::extract_resource::ExtractResourcePlugin; +use bevy::render::RenderApp; use bevy_xr::session::{ - status_changed_to, XrRenderSessionEnding, XrSessionCreated, XrSessionExiting, XrStatus, + status_changed_to, XrRenderSessionEnding, XrSessionCreated, XrSessionExiting, XrSharedStatus, + XrStatus, }; use openxr::AnyGraphics; @@ -28,10 +31,11 @@ impl Plugin for OxrSessionPlugin { run_session_status_schedules.in_set(OxrPreUpdateSet::HandleEvents), ); app.add_systems(XrSessionExiting, clean_session); - app.add_systems(XrRenderSessionEnding, |mut cmds: Commands| { - cmds.remove_resource::(); - cmds.remove_resource::(); - }); + app.sub_app_mut(RenderApp) + .add_systems(XrRenderSessionEnding, |mut cmds: Commands| { + // cmds.remove_resource::(); + cmds.remove_resource::(); + }); app.add_systems( PreUpdate, handle_stopping_state.run_if(status_changed_to(XrStatus::Stopping)), @@ -44,9 +48,13 @@ fn handle_stopping_state(session: Res, session_started: Res(); - cmds.insert_resource(OxrCleanupSession(true)); +fn clean_session(world: &mut World) { + world.insert_resource(OxrCleanupSession(true)); + // It should be impossible to call this if the session is Unavailable + world + .get_resource::() + .unwrap() + .set(XrStatus::Available); } fn run_session_status_schedules(world: &mut World) { @@ -62,6 +70,11 @@ fn run_session_status_schedules(world: &mut World) { OxrSessionStatusEvent::AboutToBeDestroyed => { world.run_schedule(XrSessionExiting); world.run_system_once(apply_deferred); + if let Some(sess) = world.remove_resource::() { + // unsafe { + // (sess.instance().fp().destroy_session)(sess.as_raw()); + // } + } } } } @@ -80,6 +93,11 @@ pub struct OxrSession( /// This is so that we can still operate on functions that don't take [`AnyGraphics`] as the generic. pub(crate) GraphicsWrap, ); +impl Drop for OxrSession { + fn drop(&mut self) { + info!("dropping session"); + } +} impl GraphicsType for OxrSession { type Inner = openxr::Session; diff --git a/crates/bevy_xr/src/session.rs b/crates/bevy_xr/src/session.rs index 004d2be..76e209b 100644 --- a/crates/bevy_xr/src/session.rs +++ b/crates/bevy_xr/src/session.rs @@ -13,10 +13,10 @@ impl Plugin for XrSessionPlugin { .add_event::() .add_event::() .add_event::() - .add_systems( - PreUpdate, - handle_session.run_if(resource_exists::), - ); + // .add_systems( + // PreUpdate, + // handle_session.run_if(resource_exists::), + /* ) */; } fn finish(&self, app: &mut App) { // This is in finnish because we need the RenderPlugin to already be added.