Merge pull request #154 from Schmarni-Dev/fix-destruction
fix session destroying
This commit is contained in:
657
Cargo.lock
generated
657
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -37,7 +37,7 @@ ash = { version = "0.37.3", optional = true }
|
||||
|
||||
[target.'cfg(target_family = "unix")'.dependencies]
|
||||
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]
|
||||
openxr = { version = "0.18.0", features = ["mint", "static"] }
|
||||
|
||||
@@ -6,7 +6,7 @@ use bevy_mod_xr::session::{XrSessionPlugin, XrState};
|
||||
|
||||
fn main() {
|
||||
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_systems(Startup, setup)
|
||||
.add_systems(Update, handle_input)
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
use std::sync::atomic::Ordering;
|
||||
use std::sync::Arc;
|
||||
|
||||
use bevy::ecs::system::RunSystemOnce;
|
||||
use bevy::prelude::*;
|
||||
use bevy::render::extract_resource::ExtractResource;
|
||||
use bevy::render::extract_resource::ExtractResourcePlugin;
|
||||
use bevy::render::renderer::RenderAdapter;
|
||||
use bevy::render::renderer::RenderAdapterInfo;
|
||||
@@ -10,6 +13,7 @@ use bevy::render::renderer::RenderQueue;
|
||||
use bevy::render::renderer::WgpuWrapper;
|
||||
use bevy::render::settings::RenderCreation;
|
||||
use bevy::render::MainWorld;
|
||||
use bevy::render::Render;
|
||||
use bevy::render::RenderApp;
|
||||
use bevy::render::RenderPlugin;
|
||||
use bevy::winit::UpdateMode;
|
||||
@@ -116,7 +120,13 @@ impl Plugin for OxrInitPlugin {
|
||||
create_xr_session
|
||||
.run_if(state_equals(XrState::Available))
|
||||
.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(on_event::<XrDestroySessionEvent>()),
|
||||
begin_xr_session
|
||||
@@ -143,7 +153,7 @@ impl Plugin for OxrInitPlugin {
|
||||
.init_non_send_resource::<OxrSessionCreateNextChain>();
|
||||
|
||||
app.world_mut()
|
||||
.spawn((TransformBundle::default(), XrTrackingRoot));
|
||||
.spawn((SpatialBundle::default(), XrTrackingRoot));
|
||||
|
||||
app.world_mut()
|
||||
.resource_mut::<Events<XrStateChanged>>()
|
||||
@@ -167,8 +177,17 @@ impl Plugin for OxrInitPlugin {
|
||||
}
|
||||
|
||||
fn finish(&self, app: &mut App) {
|
||||
app.sub_app_mut(RenderApp)
|
||||
.add_systems(XrPreDestroySession, destroy_xr_session);
|
||||
app.sub_app_mut(RenderApp).add_systems(
|
||||
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,
|
||||
images,
|
||||
graphics_info,
|
||||
session_destroy_flag: world
|
||||
.get_resource::<XrDestroySessionRender>()
|
||||
.expect("added by xr session plugin")
|
||||
.clone(),
|
||||
});
|
||||
}
|
||||
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) {
|
||||
world.run_schedule(XrPreDestroySession);
|
||||
world.insert_resource(XrDestroySessionRender);
|
||||
world.remove_resource::<OxrSession>();
|
||||
world.remove_resource::<OxrFrameWaiter>();
|
||||
world.remove_resource::<OxrFrameStream>();
|
||||
@@ -550,6 +572,7 @@ struct OxrRenderResources {
|
||||
swapchain: OxrSwapchain,
|
||||
images: OxrSwapchainImages,
|
||||
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.
|
||||
@@ -560,6 +583,7 @@ pub fn transfer_xr_resources(mut commands: Commands, mut world: ResMut<MainWorld
|
||||
swapchain,
|
||||
images,
|
||||
graphics_info,
|
||||
session_destroy_flag,
|
||||
}) = world.remove_resource()
|
||||
else {
|
||||
return;
|
||||
@@ -570,4 +594,5 @@ pub fn transfer_xr_resources(mut commands: Commands, mut world: ResMut<MainWorld
|
||||
commands.insert_resource(swapchain);
|
||||
commands.insert_resource(images);
|
||||
commands.insert_resource(graphics_info);
|
||||
commands.insert_resource(session_destroy_flag);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
use std::sync::atomic::AtomicBool;
|
||||
use std::sync::Arc;
|
||||
|
||||
use bevy::app::{AppExit, MainScheduleOrder};
|
||||
use bevy::ecs::schedule::ScheduleLabel;
|
||||
use bevy::prelude::*;
|
||||
@@ -22,8 +25,8 @@ pub struct XrSessionCreatedEvent;
|
||||
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.
|
||||
#[derive(Resource, ExtractResource, Clone, Copy, Default)]
|
||||
pub struct XrDestroySessionRender;
|
||||
#[derive(Resource, Clone, Default)]
|
||||
pub struct XrDestroySessionRender(pub Arc<AtomicBool>);
|
||||
|
||||
/// Schedule thats ran whenever the XrSession is about to be destroyed
|
||||
#[derive(Clone, Copy, Default, PartialEq, Eq, Debug, Hash, ScheduleLabel)]
|
||||
@@ -89,6 +92,7 @@ pub struct XrSessionPlugin {
|
||||
|
||||
impl Plugin for XrSessionPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.init_resource::<XrDestroySessionRender>();
|
||||
let mut xr_first = Schedule::new(XrFirst);
|
||||
xr_first.set_executor_kind(bevy::ecs::schedule::ExecutorKind::Simple);
|
||||
app.add_event::<XrCreateSessionEvent>()
|
||||
@@ -120,10 +124,6 @@ impl Plugin for XrSessionPlugin {
|
||||
.run_if(on_event::<AppExit>())
|
||||
.run_if(session_created)
|
||||
.in_set(XrHandleEvents::ExitEvents),
|
||||
)
|
||||
.add_systems(
|
||||
XrFirst,
|
||||
reset_per_frame_resources.in_set(XrHandleEvents::Cleanup),
|
||||
);
|
||||
app.world_mut()
|
||||
.resource_mut::<MainScheduleOrder>()
|
||||
@@ -142,7 +142,6 @@ impl Plugin for XrSessionPlugin {
|
||||
|
||||
app.add_plugins((
|
||||
ExtractResourcePlugin::<XrState>::default(),
|
||||
ExtractResourcePlugin::<XrDestroySessionRender>::default(),
|
||||
ExtractResourcePlugin::<XrRootTransform>::default(),
|
||||
))
|
||||
.init_resource::<XrRootTransform>()
|
||||
@@ -181,15 +180,6 @@ impl Plugin for XrSessionPlugin {
|
||||
XrRenderSet::PostRender
|
||||
.after(RenderSet::Render)
|
||||
.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,29 +215,29 @@ pub enum XrState {
|
||||
},
|
||||
}
|
||||
|
||||
pub fn reset_per_frame_resources(world: &mut World) {
|
||||
world.remove_resource::<XrDestroySessionRender>();
|
||||
}
|
||||
|
||||
pub fn auto_handle_session(
|
||||
mut state_changed: EventReader<XrStateChanged>,
|
||||
mut create_session: EventWriter<XrCreateSessionEvent>,
|
||||
mut begin_session: EventWriter<XrBeginSessionEvent>,
|
||||
mut end_session: EventWriter<XrEndSessionEvent>,
|
||||
mut destroy_session: EventWriter<XrDestroySessionEvent>,
|
||||
mut no_auto_restart: Local<bool>,
|
||||
) {
|
||||
for XrStateChanged(state) in state_changed.read() {
|
||||
match state {
|
||||
XrState::Available => {
|
||||
if !*no_auto_restart {
|
||||
create_session.send_default();
|
||||
}
|
||||
}
|
||||
XrState::Ready => {
|
||||
begin_session.send_default();
|
||||
}
|
||||
XrState::Stopping => {
|
||||
end_session.send_default();
|
||||
}
|
||||
XrState::Exiting { .. } => {
|
||||
XrState::Exiting { should_restart } => {
|
||||
*no_auto_restart = !should_restart;
|
||||
destroy_session.send_default();
|
||||
}
|
||||
_ => (),
|
||||
|
||||
Reference in New Issue
Block a user