session ending works but segfaults on my machine

Signed-off-by: Schmarni <marnistromer@gmail.com>
This commit is contained in:
Schmarni
2024-05-23 22:05:14 +02:00
parent fb9ec378c8
commit 31c1daf2d4
8 changed files with 64 additions and 20 deletions

View File

@@ -20,15 +20,19 @@ fn handle_input(
mut create: EventWriter<bevy_xr::session::CreateXrSession>, mut create: EventWriter<bevy_xr::session::CreateXrSession>,
) { ) {
if keys.just_pressed(KeyCode::KeyE) { if keys.just_pressed(KeyCode::KeyE) {
info!("sending end");
end.send_default(); end.send_default();
} }
if keys.just_pressed(KeyCode::KeyD) { if keys.just_pressed(KeyCode::KeyD) {
info!("sending destroy");
destroy.send_default(); destroy.send_default();
} }
if keys.just_pressed(KeyCode::KeyB) { if keys.just_pressed(KeyCode::KeyB) {
info!("sending begin");
begin.send_default(); begin.send_default();
} }
if keys.just_pressed(KeyCode::KeyC) { if keys.just_pressed(KeyCode::KeyC) {
info!("sending create");
create.send_default(); create.send_default();
} }
} }

View File

@@ -2,7 +2,7 @@ use bevy::prelude::*;
use bevy_xr::hands::{LeftHand, RightHand}; use bevy_xr::hands::{LeftHand, RightHand};
use bevy_xr::{ use bevy_xr::{
hands::{HandBone, HandBoneRadius}, hands::{HandBone, HandBoneRadius},
session::{session_running, XrSessionCreated, XrSessionEnding}, session::{session_running, XrSessionCreated, XrSessionExiting},
}; };
use openxr::SpaceLocationFlags; use openxr::SpaceLocationFlags;
@@ -28,7 +28,7 @@ impl Plugin for HandTrackingPlugin {
fn build(&self, app: &mut App) { fn build(&self, app: &mut App) {
app.add_systems(PreUpdate, locate_hands.run_if(session_running)); app.add_systems(PreUpdate, locate_hands.run_if(session_running));
if self.default_hands { 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); app.add_systems(XrSessionCreated, spawn_default_hands);
} }
} }

View File

@@ -131,7 +131,7 @@ impl Plugin for OxrInitPlugin {
.run_if(status_equals(XrStatus::Ready)), .run_if(status_equals(XrStatus::Ready)),
end_xr_session end_xr_session
.run_if(on_event::<EndXrSession>()) .run_if(on_event::<EndXrSession>())
.run_if(status_equals(XrStatus::Stopping)), .run_if(status_equals(XrStatus::Running)),
destroy_xr_session destroy_xr_session
.run_if(on_event::<DestroyXrSession>()) .run_if(on_event::<DestroyXrSession>())
.run_if(status_equals(XrStatus::Exiting)), .run_if(status_equals(XrStatus::Exiting)),
@@ -489,8 +489,11 @@ pub fn begin_xr_session(session: Res<OxrSession>, session_started: Res<OxrSessio
pub fn end_xr_session(session: Res<OxrSession>, session_started: Res<OxrSessionStarted>) { pub fn end_xr_session(session: Res<OxrSession>, session_started: Res<OxrSessionStarted>) {
let _span = info_span!("xr_end_session"); let _span = info_span!("xr_end_session");
session.end().expect("Failed to end session"); session
session_started.set(false); .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. /// This system transfers important render resources from the main world to the render world when a session is created.

View File

@@ -5,7 +5,7 @@ use bevy::{
render::extract_resource::{ExtractResource, ExtractResourcePlugin}, render::extract_resource::{ExtractResource, ExtractResourcePlugin},
}; };
use bevy_xr::session::{ use bevy_xr::session::{
status_changed_to, XrRenderSessionEnding, XrSessionCreated, XrSessionEnding, XrStatus, status_changed_to, XrRenderSessionEnding, XrSessionCreated, XrSessionExiting, XrStatus,
}; };
use crate::{init::OxrPreUpdateSet, session::OxrSession}; use crate::{init::OxrPreUpdateSet, session::OxrSession};
@@ -36,7 +36,7 @@ impl Plugin for OxrReferenceSpacePlugin {
app.insert_resource(OxrDefaultPrimaryReferenceSpaceType(self.default_primary_ref_space)); app.insert_resource(OxrDefaultPrimaryReferenceSpaceType(self.default_primary_ref_space));
app.add_plugins(ExtractResourcePlugin::<OxrPrimaryReferenceSpace>::default()); app.add_plugins(ExtractResourcePlugin::<OxrPrimaryReferenceSpace>::default());
app.add_systems(XrSessionCreated, set_primary_ref_space); app.add_systems(XrSessionCreated, set_primary_ref_space);
app.add_systems(XrSessionEnding, cleanup); app.add_systems(XrSessionExiting, cleanup);
app.add_systems(XrRenderSessionEnding, cleanup); app.add_systems(XrRenderSessionEnding, cleanup);
} }
} }

View File

@@ -12,11 +12,10 @@ use bevy::{
}; };
use bevy_xr::{ use bevy_xr::{
camera::{XrCamera, XrCameraBundle, XrProjection}, camera::{XrCamera, XrCameraBundle, XrProjection},
session::session_running, session::{session_running, XrSessionExiting},
}; };
use openxr::ViewStateFlags; use openxr::ViewStateFlags;
use crate::{ use crate::{
init::{session_started, OxrPreUpdateSet, OxrTrackingRoot}, init::{session_started, OxrPreUpdateSet, OxrTrackingRoot},
layer_builder::ProjectionLayer, session::OxrSession, layer_builder::ProjectionLayer, session::OxrSession,
@@ -45,7 +44,8 @@ impl Plugin for OxrRenderPlugin {
.run_if(session_running) .run_if(session_running)
.before(TransformSystem::TransformPropagate), .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) app.sub_app_mut(RenderApp)
.add_systems( .add_systems(
Render, Render,
@@ -73,6 +73,17 @@ impl Plugin for OxrRenderPlugin {
pub const XR_TEXTURE_INDEX: u32 = 3383858418; pub const XR_TEXTURE_INDEX: u32 = 3383858418;
pub fn clean_views(
mut manual_texture_views: ResMut<ManualTextureViews>,
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. // 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. /// 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( pub fn init_views(

View File

@@ -218,6 +218,11 @@ pub struct OxrFrameWaiter(pub openxr::FrameWaiter);
/// Graphics agnostic wrapper around [openxr::Swapchain] /// Graphics agnostic wrapper around [openxr::Swapchain]
#[derive(Resource)] #[derive(Resource)]
pub struct OxrSwapchain(pub GraphicsWrap<Self>); pub struct OxrSwapchain(pub GraphicsWrap<Self>);
impl Drop for OxrSwapchain {
fn drop(&mut self) {
info!("Dropping Swapchain");
}
}
impl GraphicsType for OxrSwapchain { impl GraphicsType for OxrSwapchain {
type Inner<G: GraphicsExt> = openxr::Swapchain<G>; type Inner<G: GraphicsExt> = openxr::Swapchain<G>;
@@ -287,6 +292,11 @@ impl OxrSwapchain {
/// Stores the generated swapchain images. /// Stores the generated swapchain images.
#[derive(Debug, Deref, Resource, Clone)] #[derive(Debug, Deref, Resource, Clone)]
pub struct OxrSwapchainImages(pub Arc<Vec<wgpu::Texture>>); pub struct OxrSwapchainImages(pub Arc<Vec<wgpu::Texture>>);
impl Drop for OxrSwapchainImages {
fn drop(&mut self) {
info!("Dropping Swapchain Images");
}
}
/// Thread safe wrapper around [openxr::Space] representing the stage. /// Thread safe wrapper around [openxr::Space] representing the stage.
// #[derive(Deref, Clone, Resource)] // #[derive(Deref, Clone, Resource)]

View File

@@ -1,9 +1,13 @@
use crate::init::OxrPreUpdateSet; 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 crate::types::{Result, SwapchainCreateInfo};
use bevy::ecs::system::{RunSystemOnce, SystemState}; use bevy::ecs::system::{RunSystemOnce, SystemState};
use bevy::prelude::*; 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 openxr::AnyGraphics;
use crate::graphics::{graphics_match, GraphicsExt, GraphicsType, GraphicsWrap}; use crate::graphics::{graphics_match, GraphicsExt, GraphicsType, GraphicsWrap};
@@ -23,13 +27,23 @@ impl Plugin for OxrSessionPlugin {
PreUpdate, PreUpdate,
run_session_status_schedules.in_set(OxrPreUpdateSet::HandleEvents), 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| { app.add_systems(XrRenderSessionEnding, |mut cmds: Commands| {
cmds.remove_resource::<OxrSession>() cmds.remove_resource::<OxrSession>();
cmds.remove_resource::<OxrCleanupSession>();
}); });
app.add_systems(
PreUpdate,
handle_stopping_state.run_if(status_changed_to(XrStatus::Stopping)),
);
} }
} }
fn handle_stopping_state(session: Res<OxrSession>, session_started: Res<OxrSessionStarted>) {
session.end().expect("Failed to end session");
session_started.set(false);
}
fn clean_session(mut cmds: Commands) { fn clean_session(mut cmds: Commands) {
cmds.remove_resource::<OxrSession>(); cmds.remove_resource::<OxrSession>();
cmds.insert_resource(OxrCleanupSession(true)); cmds.insert_resource(OxrCleanupSession(true));
@@ -46,7 +60,7 @@ fn run_session_status_schedules(world: &mut World) {
world.run_system_once(apply_deferred); world.run_system_once(apply_deferred);
} }
OxrSessionStatusEvent::AboutToBeDestroyed => { OxrSessionStatusEvent::AboutToBeDestroyed => {
world.run_schedule(XrSessionEnding); world.run_schedule(XrSessionExiting);
world.run_system_once(apply_deferred); world.run_system_once(apply_deferred);
} }
} }

View File

@@ -1,13 +1,13 @@
use std::sync::{Arc, RwLock}; use std::sync::{Arc, RwLock};
use bevy::{ecs::schedule::ScheduleLabel, prelude::*}; use bevy::{ecs::schedule::ScheduleLabel, prelude::*, render::RenderApp};
pub struct XrSessionPlugin; 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_schedule(XrSessionCreated); app.init_schedule(XrSessionCreated);
app.init_schedule(XrSessionEnding); app.init_schedule(XrSessionExiting);
app.add_event::<CreateXrSession>() app.add_event::<CreateXrSession>()
.add_event::<DestroyXrSession>() .add_event::<DestroyXrSession>()
.add_event::<BeginXrSession>() .add_event::<BeginXrSession>()
@@ -20,7 +20,9 @@ impl Plugin for XrSessionPlugin {
} }
fn finish(&self, app: &mut App) { fn finish(&self, app: &mut App) {
// This is in finnish because we need the RenderPlugin to already be added. // 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; pub struct XrSessionCreated;
#[derive(ScheduleLabel, Clone, Copy, PartialEq, Eq, Debug, Hash)] #[derive(ScheduleLabel, Clone, Copy, PartialEq, Eq, Debug, Hash)]
pub struct XrSessionEnding; pub struct XrSessionExiting;
#[derive(ScheduleLabel, Clone, Copy, PartialEq, Eq, Debug, Hash)] #[derive(ScheduleLabel, Clone, Copy, PartialEq, Eq, Debug, Hash)]
pub struct XrRenderSessionEnding; pub struct XrRenderSessionEnding;
@@ -93,7 +95,7 @@ pub fn handle_session(
} }
XrStatus::Running => {} XrStatus::Running => {}
XrStatus::Stopping => { XrStatus::Stopping => {
end_session.send_default(); // end_session.send_default();
} }
XrStatus::Exiting => { XrStatus::Exiting => {
destroy_session.send_default(); destroy_session.send_default();