merge both Exit schedules, fix reference space living after the session exits in the render world and general cleanup

Signed-off-by: Schmarni <marnistromer@gmail.com>
This commit is contained in:
Schmarni
2024-05-31 10:48:03 +02:00
parent 40c767c2d2
commit 0e2a5dbf66
6 changed files with 42 additions and 51 deletions

View File

@@ -39,7 +39,7 @@ fn spawn_default_hands(
session: Res<OxrSession>, session: Res<OxrSession>,
root: Query<Entity, With<OxrTrackingRoot>>, root: Query<Entity, With<OxrTrackingRoot>>,
) { ) {
info!("spawning hands"); dbg!("spawning default hands");
let Ok(root) = root.get_single() else { let Ok(root) = root.get_single() else {
error!("unable to get tracking root, skipping hand creation"); error!("unable to get tracking root, skipping hand creation");
return; return;
@@ -71,6 +71,7 @@ fn spawn_default_hands(
for bone in HandBone::get_all_bones() { for bone in HandBone::get_all_bones() {
let bone_left = cmds let bone_left = cmds
.spawn(( .spawn((
DefaultHandBone,
SpatialBundle::default(), SpatialBundle::default(),
bone, bone,
HandBoneRadius(0.0), HandBoneRadius(0.0),
@@ -79,6 +80,7 @@ fn spawn_default_hands(
.id(); .id();
let bone_right = cmds let bone_right = cmds
.spawn(( .spawn((
DefaultHandBone,
SpatialBundle::default(), SpatialBundle::default(),
bone, bone,
HandBoneRadius(0.0), HandBoneRadius(0.0),
@@ -107,15 +109,15 @@ fn spawn_default_hands(
#[derive(Component)] #[derive(Component)]
struct DefaultHandTracker; struct DefaultHandTracker;
#[derive(Component)] #[derive(Component)]
struct DefaultHandBones; struct DefaultHandBone;
#[allow(clippy::type_complexity)] #[allow(clippy::type_complexity)]
fn clean_up_default_hands( fn clean_up_default_hands(
mut cmds: Commands, mut cmds: Commands,
query: Query<Entity, Or<(With<DefaultHandTracker>, With<DefaultHandBones>)>>, query: Query<Entity, Or<(With<DefaultHandTracker>, With<DefaultHandBone>)>>,
) { ) {
for e in &query { for e in &query {
info!("removing_hand_entity"); dbg!("removing default hand entity");
cmds.entity(e).despawn_recursive(); cmds.entity(e).despawn_recursive();
} }
} }

View File

@@ -23,7 +23,6 @@ use bevy_xr::session::BeginXrSession;
use bevy_xr::session::CreateXrSession; use bevy_xr::session::CreateXrSession;
use bevy_xr::session::DestroyXrSession; use bevy_xr::session::DestroyXrSession;
use bevy_xr::session::EndXrSession; use bevy_xr::session::EndXrSession;
use bevy_xr::session::XrRenderSessionEnding;
use bevy_xr::session::XrSessionExiting; use bevy_xr::session::XrSessionExiting;
use bevy_xr::session::XrSharedStatus; use bevy_xr::session::XrSharedStatus;
use bevy_xr::session::XrStatus; use bevy_xr::session::XrStatus;
@@ -167,7 +166,7 @@ impl Plugin for OxrInitPlugin {
Render, Render,
destroy_xr_session_render destroy_xr_session_render
.run_if(resource_equals(OxrCleanupSession(true))) .run_if(resource_equals(OxrCleanupSession(true)))
.after(RenderSet::ExtractCommands), .after(RenderSet::Cleanup),
) )
.add_systems( .add_systems(
ExtractSchedule, ExtractSchedule,
@@ -455,7 +454,6 @@ pub fn create_xr_session(
system_id: Res<OxrSystemId>, system_id: Res<OxrSystemId>,
mut commands: Commands, mut commands: Commands,
) { ) {
info!("creating session!");
match init_xr_session( match init_xr_session(
device.wgpu_device(), device.wgpu_device(),
&instance, &instance,
@@ -481,7 +479,6 @@ pub fn create_xr_session(
pub fn begin_xr_session(session: Res<OxrSession>, session_started: Res<OxrSessionStarted>) { pub fn begin_xr_session(session: Res<OxrSession>, session_started: Res<OxrSessionStarted>) {
let _span = info_span!("xr_begin_session"); let _span = info_span!("xr_begin_session");
info!("begining session!");
session session
.begin(openxr::ViewConfigurationType::PRIMARY_STEREO) .begin(openxr::ViewConfigurationType::PRIMARY_STEREO)
.expect("Failed to begin session"); .expect("Failed to begin session");
@@ -490,7 +487,6 @@ 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");
info!("ending session!");
session session
.request_exit() .request_exit()
.expect("Failed to request session exit"); .expect("Failed to request session exit");
@@ -583,17 +579,7 @@ pub fn destroy_xr_session_render(world: &mut World) {
world.remove_resource::<OxrFrameStream>(); world.remove_resource::<OxrFrameStream>();
world.remove_resource::<OxrSwapchainImages>(); world.remove_resource::<OxrSwapchainImages>();
world.remove_resource::<OxrGraphicsInfo>(); world.remove_resource::<OxrGraphicsInfo>();
world.run_schedule(XrRenderSessionEnding); world.run_schedule(XrSessionExiting);
world.run_system_once(apply_deferred); world.run_system_once(apply_deferred);
if let Some(sess) = world.remove_resource::<OxrSession>() { world.remove_resource::<OxrSession>();
// This is needed because there is one space that survives the session exit schedule and
// holds on to the session. this causes an error message but does not seem to cause any
// actuall issues.
unsafe {
(sess.instance().fp().destroy_session)(sess.as_raw());
}
// leaking the session so that it does not call destroy_session at a later point. might not
// actually be needed.
Box::leak(Box::new(sess));
}
} }

View File

@@ -2,11 +2,12 @@ use std::sync::Arc;
use bevy::{ use bevy::{
prelude::*, prelude::*,
render::extract_resource::{ExtractResource, ExtractResourcePlugin}, render::{
}; extract_resource::{ExtractResource, ExtractResourcePlugin},
use bevy_xr::session::{ RenderApp,
status_changed_to, XrRenderSessionEnding, XrSessionCreated, XrSessionExiting, XrStatus, },
}; };
use bevy_xr::session::{status_changed_to, XrSessionCreated, XrSessionExiting, XrStatus};
use crate::{init::OxrPreUpdateSet, session::OxrSession}; use crate::{init::OxrPreUpdateSet, session::OxrSession};
@@ -33,11 +34,14 @@ pub struct OxrReferenceSpace(pub openxr::Space);
impl Plugin for OxrReferenceSpacePlugin { impl Plugin for OxrReferenceSpacePlugin {
fn build(&self, app: &mut App) { fn build(&self, app: &mut App) {
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(XrSessionExiting, cleanup); app.add_systems(XrSessionExiting, cleanup);
app.add_systems(XrRenderSessionEnding, cleanup); app.sub_app_mut(RenderApp)
.add_systems(XrSessionExiting, cleanup);
} }
} }

View File

@@ -3,7 +3,6 @@ use std::sync::Arc;
use bevy::prelude::*; use bevy::prelude::*;
use bevy::render::extract_resource::ExtractResource; use bevy::render::extract_resource::ExtractResource;
use openxr::AnyGraphics;
use crate::error::OxrError; use crate::error::OxrError;
use crate::graphics::*; use crate::graphics::*;
@@ -217,11 +216,6 @@ 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>;

View File

@@ -3,13 +3,12 @@ use crate::resources::{
OxrCleanupSession, OxrPassthrough, OxrPassthroughLayer, OxrSessionStarted, OxrSwapchain, OxrCleanupSession, OxrPassthrough, OxrPassthroughLayer, OxrSessionStarted, OxrSwapchain,
}; };
use crate::types::{Result, SwapchainCreateInfo}; use crate::types::{Result, SwapchainCreateInfo};
use bevy::ecs::system::{RunSystemOnce, SystemState}; use bevy::ecs::event::ManualEventReader;
use bevy::ecs::system::RunSystemOnce;
use bevy::prelude::*; use bevy::prelude::*;
use bevy::render::extract_resource::ExtractResourcePlugin;
use bevy::render::RenderApp; use bevy::render::RenderApp;
use bevy_xr::session::{ use bevy_xr::session::{
status_changed_to, XrRenderSessionEnding, XrSessionCreated, XrSessionExiting, XrSharedStatus, status_changed_to, XrSessionCreated, XrSessionExiting, XrSharedStatus, XrStatus,
XrStatus,
}; };
use openxr::AnyGraphics; use openxr::AnyGraphics;
@@ -32,7 +31,7 @@ impl Plugin for OxrSessionPlugin {
); );
app.add_systems(XrSessionExiting, clean_session); app.add_systems(XrSessionExiting, clean_session);
app.sub_app_mut(RenderApp) app.sub_app_mut(RenderApp)
.add_systems(XrRenderSessionEnding, |mut cmds: Commands| { .add_systems(XrSessionExiting, |mut cmds: Commands| {
cmds.remove_resource::<OxrCleanupSession>(); cmds.remove_resource::<OxrCleanupSession>();
}); });
app.add_systems( app.add_systems(
@@ -56,10 +55,23 @@ fn clean_session(world: &mut World) {
.set(XrStatus::Available); .set(XrStatus::Available);
} }
#[derive(Resource, Default)]
struct SessionStatusReader(ManualEventReader<OxrSessionStatusEvent>);
fn run_session_status_schedules(world: &mut World) { fn run_session_status_schedules(world: &mut World) {
let mut state = SystemState::<EventReader<OxrSessionStatusEvent>>::new(world); let mut reader = world
let mut e = state.get_mut(world); .remove_resource::<SessionStatusReader>()
let events = e.read().copied().collect::<Vec<_>>(); .unwrap_or_default();
let events = reader
.0
.read(
world
.get_resource::<Events<OxrSessionStatusEvent>>()
.unwrap(),
)
.copied()
.collect::<Vec<_>>();
for e in events.iter() { for e in events.iter() {
match e { match e {
OxrSessionStatusEvent::Created => { OxrSessionStatusEvent::Created => {
@@ -73,6 +85,7 @@ fn run_session_status_schedules(world: &mut World) {
} }
} }
} }
world.insert_resource(reader);
} }
/// Graphics agnostic wrapper around [openxr::Session]. /// Graphics agnostic wrapper around [openxr::Session].
@@ -88,11 +101,6 @@ pub struct OxrSession(
/// This is so that we can still operate on functions that don't take [`AnyGraphics`] as the generic. /// This is so that we can still operate on functions that don't take [`AnyGraphics`] as the generic.
pub(crate) GraphicsWrap<Self>, pub(crate) GraphicsWrap<Self>,
); );
impl Drop for OxrSession {
fn drop(&mut self) {
info!("dropping session");
}
}
impl GraphicsType for OxrSession { impl GraphicsType for OxrSession {
type Inner<G: GraphicsExt> = openxr::Session<G>; type Inner<G: GraphicsExt> = openxr::Session<G>;

View File

@@ -23,7 +23,7 @@ impl Plugin for XrSessionPlugin {
// 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.get_sub_app_mut(RenderApp) app.get_sub_app_mut(RenderApp)
.unwrap() .unwrap()
.init_schedule(XrRenderSessionEnding); .init_schedule(XrSessionExiting);
} }
} }
@@ -44,9 +44,6 @@ pub struct XrSessionCreated;
#[derive(ScheduleLabel, Clone, Copy, PartialEq, Eq, Debug, Hash)] #[derive(ScheduleLabel, Clone, Copy, PartialEq, Eq, Debug, Hash)]
pub struct XrSessionExiting; pub struct XrSessionExiting;
#[derive(ScheduleLabel, Clone, Copy, PartialEq, Eq, Debug, Hash)]
pub struct XrRenderSessionEnding;
#[derive(Event, Clone, Copy, Deref)] #[derive(Event, Clone, Copy, Deref)]
pub struct XrStatusChanged(pub XrStatus); pub struct XrStatusChanged(pub XrStatus);