Merge pull request #154 from Schmarni-Dev/fix-destruction

fix session destroying
This commit is contained in:
Schmarni
2024-09-07 12:02:27 +02:00
committed by GitHub
5 changed files with 397 additions and 333 deletions

657
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -37,7 +37,7 @@ ash = { version = "0.37.3", optional = true }
[target.'cfg(target_family = "unix")'.dependencies] [target.'cfg(target_family = "unix")'.dependencies]
openxr = { version = "0.18.0", features = ["mint"] } openxr = { version = "0.18.0", features = ["mint"] }
wgpu = { version = "0.19.3", features = ["vulkan-portability"] } wgpu = { version = "0.20", features = ["vulkan-portability"] }
[target.'cfg(target_family = "windows")'.dependencies] [target.'cfg(target_family = "windows")'.dependencies]
openxr = { version = "0.18.0", features = ["mint", "static"] } openxr = { version = "0.18.0", features = ["mint", "static"] }

View File

@@ -6,7 +6,7 @@ use bevy_mod_xr::session::{XrSessionPlugin, XrState};
fn main() { fn main() {
App::new() App::new()
.add_plugins(add_xr_plugins(DefaultPlugins).set(XrSessionPlugin { auto_handle: false })) .add_plugins(add_xr_plugins(DefaultPlugins).set(XrSessionPlugin { auto_handle: true }))
.add_plugins(bevy_xr_utils::hand_gizmos::HandGizmosPlugin) .add_plugins(bevy_xr_utils::hand_gizmos::HandGizmosPlugin)
.add_systems(Startup, setup) .add_systems(Startup, setup)
.add_systems(Update, handle_input) .add_systems(Update, handle_input)

View File

@@ -1,6 +1,9 @@
use std::sync::atomic::Ordering;
use std::sync::Arc; use std::sync::Arc;
use bevy::ecs::system::RunSystemOnce;
use bevy::prelude::*; use bevy::prelude::*;
use bevy::render::extract_resource::ExtractResource;
use bevy::render::extract_resource::ExtractResourcePlugin; use bevy::render::extract_resource::ExtractResourcePlugin;
use bevy::render::renderer::RenderAdapter; use bevy::render::renderer::RenderAdapter;
use bevy::render::renderer::RenderAdapterInfo; use bevy::render::renderer::RenderAdapterInfo;
@@ -10,6 +13,7 @@ use bevy::render::renderer::RenderQueue;
use bevy::render::renderer::WgpuWrapper; use bevy::render::renderer::WgpuWrapper;
use bevy::render::settings::RenderCreation; use bevy::render::settings::RenderCreation;
use bevy::render::MainWorld; use bevy::render::MainWorld;
use bevy::render::Render;
use bevy::render::RenderApp; use bevy::render::RenderApp;
use bevy::render::RenderPlugin; use bevy::render::RenderPlugin;
use bevy::winit::UpdateMode; use bevy::winit::UpdateMode;
@@ -116,7 +120,13 @@ impl Plugin for OxrInitPlugin {
create_xr_session create_xr_session
.run_if(state_equals(XrState::Available)) .run_if(state_equals(XrState::Available))
.run_if(on_event::<XrCreateSessionEvent>()), .run_if(on_event::<XrCreateSessionEvent>()),
destroy_xr_session (
destroy_xr_session,
(|v: Res<XrDestroySessionRender>| {
v.0.store(true, Ordering::Relaxed);
info!("setting destroy render session");
}),
)
.run_if(state_matches!(XrState::Exiting { .. })) .run_if(state_matches!(XrState::Exiting { .. }))
.run_if(on_event::<XrDestroySessionEvent>()), .run_if(on_event::<XrDestroySessionEvent>()),
begin_xr_session begin_xr_session
@@ -143,7 +153,7 @@ impl Plugin for OxrInitPlugin {
.init_non_send_resource::<OxrSessionCreateNextChain>(); .init_non_send_resource::<OxrSessionCreateNextChain>();
app.world_mut() app.world_mut()
.spawn((TransformBundle::default(), XrTrackingRoot)); .spawn((SpatialBundle::default(), XrTrackingRoot));
app.world_mut() app.world_mut()
.resource_mut::<Events<XrStateChanged>>() .resource_mut::<Events<XrStateChanged>>()
@@ -167,8 +177,17 @@ impl Plugin for OxrInitPlugin {
} }
fn finish(&self, app: &mut App) { fn finish(&self, app: &mut App) {
app.sub_app_mut(RenderApp) app.sub_app_mut(RenderApp).add_systems(
.add_systems(XrPreDestroySession, destroy_xr_session); Render,
(destroy_xr_session, |v: Res<XrDestroySessionRender>| {
v.0.store(false, Ordering::Relaxed)
})
.run_if(
resource_exists::<XrDestroySessionRender>
.and_then(|v: Res<XrDestroySessionRender>| v.0.load(Ordering::Relaxed)),
)
.chain(),
);
} }
} }
@@ -488,6 +507,10 @@ pub fn create_xr_session(world: &mut World) {
swapchain, swapchain,
images, images,
graphics_info, graphics_info,
session_destroy_flag: world
.get_resource::<XrDestroySessionRender>()
.expect("added by xr session plugin")
.clone(),
}); });
} }
Err(e) => error!("Failed to initialize XrSession: {e}"), Err(e) => error!("Failed to initialize XrSession: {e}"),
@@ -499,7 +522,6 @@ pub fn create_xr_session(world: &mut World) {
pub fn destroy_xr_session(world: &mut World) { pub fn destroy_xr_session(world: &mut World) {
world.run_schedule(XrPreDestroySession); world.run_schedule(XrPreDestroySession);
world.insert_resource(XrDestroySessionRender);
world.remove_resource::<OxrSession>(); world.remove_resource::<OxrSession>();
world.remove_resource::<OxrFrameWaiter>(); world.remove_resource::<OxrFrameWaiter>();
world.remove_resource::<OxrFrameStream>(); world.remove_resource::<OxrFrameStream>();
@@ -550,6 +572,7 @@ struct OxrRenderResources {
swapchain: OxrSwapchain, swapchain: OxrSwapchain,
images: OxrSwapchainImages, images: OxrSwapchainImages,
graphics_info: OxrGraphicsInfo, graphics_info: OxrGraphicsInfo,
session_destroy_flag: XrDestroySessionRender,
} }
/// This system transfers important render resources from the main world to the render world when a session is created. /// This system transfers important render resources from the main world to the render world when a session is created.
@@ -560,6 +583,7 @@ pub fn transfer_xr_resources(mut commands: Commands, mut world: ResMut<MainWorld
swapchain, swapchain,
images, images,
graphics_info, graphics_info,
session_destroy_flag,
}) = world.remove_resource() }) = world.remove_resource()
else { else {
return; return;
@@ -570,4 +594,5 @@ pub fn transfer_xr_resources(mut commands: Commands, mut world: ResMut<MainWorld
commands.insert_resource(swapchain); commands.insert_resource(swapchain);
commands.insert_resource(images); commands.insert_resource(images);
commands.insert_resource(graphics_info); commands.insert_resource(graphics_info);
commands.insert_resource(session_destroy_flag);
} }

View File

@@ -1,3 +1,6 @@
use std::sync::atomic::AtomicBool;
use std::sync::Arc;
use bevy::app::{AppExit, MainScheduleOrder}; use bevy::app::{AppExit, MainScheduleOrder};
use bevy::ecs::schedule::ScheduleLabel; use bevy::ecs::schedule::ScheduleLabel;
use bevy::prelude::*; use bevy::prelude::*;
@@ -22,8 +25,8 @@ pub struct XrSessionCreatedEvent;
pub struct XrDestroySessionEvent; pub struct XrDestroySessionEvent;
/// Resource flag thats inserted into the world and extracted to the render world to inform any session resources in the render world to drop. /// Resource flag thats inserted into the world and extracted to the render world to inform any session resources in the render world to drop.
#[derive(Resource, ExtractResource, Clone, Copy, Default)] #[derive(Resource, Clone, Default)]
pub struct XrDestroySessionRender; pub struct XrDestroySessionRender(pub Arc<AtomicBool>);
/// Schedule thats ran whenever the XrSession is about to be destroyed /// Schedule thats ran whenever the XrSession is about to be destroyed
#[derive(Clone, Copy, Default, PartialEq, Eq, Debug, Hash, ScheduleLabel)] #[derive(Clone, Copy, Default, PartialEq, Eq, Debug, Hash, ScheduleLabel)]
@@ -89,6 +92,7 @@ pub struct XrSessionPlugin {
impl Plugin for XrSessionPlugin { impl Plugin for XrSessionPlugin {
fn build(&self, app: &mut App) { fn build(&self, app: &mut App) {
app.init_resource::<XrDestroySessionRender>();
let mut xr_first = Schedule::new(XrFirst); let mut xr_first = Schedule::new(XrFirst);
xr_first.set_executor_kind(bevy::ecs::schedule::ExecutorKind::Simple); xr_first.set_executor_kind(bevy::ecs::schedule::ExecutorKind::Simple);
app.add_event::<XrCreateSessionEvent>() app.add_event::<XrCreateSessionEvent>()
@@ -120,10 +124,6 @@ impl Plugin for XrSessionPlugin {
.run_if(on_event::<AppExit>()) .run_if(on_event::<AppExit>())
.run_if(session_created) .run_if(session_created)
.in_set(XrHandleEvents::ExitEvents), .in_set(XrHandleEvents::ExitEvents),
)
.add_systems(
XrFirst,
reset_per_frame_resources.in_set(XrHandleEvents::Cleanup),
); );
app.world_mut() app.world_mut()
.resource_mut::<MainScheduleOrder>() .resource_mut::<MainScheduleOrder>()
@@ -142,7 +142,6 @@ impl Plugin for XrSessionPlugin {
app.add_plugins(( app.add_plugins((
ExtractResourcePlugin::<XrState>::default(), ExtractResourcePlugin::<XrState>::default(),
ExtractResourcePlugin::<XrDestroySessionRender>::default(),
ExtractResourcePlugin::<XrRootTransform>::default(), ExtractResourcePlugin::<XrRootTransform>::default(),
)) ))
.init_resource::<XrRootTransform>() .init_resource::<XrRootTransform>()
@@ -181,15 +180,6 @@ impl Plugin for XrSessionPlugin {
XrRenderSet::PostRender XrRenderSet::PostRender
.after(RenderSet::Render) .after(RenderSet::Render)
.before(RenderSet::Cleanup), .before(RenderSet::Cleanup),
)
.add_systems(
Render,
(
// run_xr_destroy_session
// .run_if(resource_exists::<XrDestroySessionRender>)
// .in_set(XrRenderSet::HandleEvents),
reset_per_frame_resources.in_set(RenderSet::Cleanup),
),
); );
} }
} }
@@ -225,21 +215,20 @@ pub enum XrState {
}, },
} }
pub fn reset_per_frame_resources(world: &mut World) {
world.remove_resource::<XrDestroySessionRender>();
}
pub fn auto_handle_session( pub fn auto_handle_session(
mut state_changed: EventReader<XrStateChanged>, mut state_changed: EventReader<XrStateChanged>,
mut create_session: EventWriter<XrCreateSessionEvent>, mut create_session: EventWriter<XrCreateSessionEvent>,
mut begin_session: EventWriter<XrBeginSessionEvent>, mut begin_session: EventWriter<XrBeginSessionEvent>,
mut end_session: EventWriter<XrEndSessionEvent>, mut end_session: EventWriter<XrEndSessionEvent>,
mut destroy_session: EventWriter<XrDestroySessionEvent>, mut destroy_session: EventWriter<XrDestroySessionEvent>,
mut no_auto_restart: Local<bool>,
) { ) {
for XrStateChanged(state) in state_changed.read() { for XrStateChanged(state) in state_changed.read() {
match state { match state {
XrState::Available => { XrState::Available => {
create_session.send_default(); if !*no_auto_restart {
create_session.send_default();
}
} }
XrState::Ready => { XrState::Ready => {
begin_session.send_default(); begin_session.send_default();
@@ -247,7 +236,8 @@ pub fn auto_handle_session(
XrState::Stopping => { XrState::Stopping => {
end_session.send_default(); end_session.send_default();
} }
XrState::Exiting { .. } => { XrState::Exiting { should_restart } => {
*no_auto_restart = !should_restart;
destroy_session.send_default(); destroy_session.send_default();
} }
_ => (), _ => (),