works but destroys the session manually because one space somewhere survives session exit
Signed-off-by: Schmarni <marnistromer@gmail.com>
This commit is contained in:
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
use bevy_openxr::add_xr_plugins;
|
use bevy_openxr::add_xr_plugins;
|
||||||
|
use bevy_xr::session::{XrSharedStatus, XrStatus};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
App::new()
|
App::new()
|
||||||
@@ -18,6 +19,7 @@ fn handle_input(
|
|||||||
mut destroy: EventWriter<bevy_xr::session::DestroyXrSession>,
|
mut destroy: EventWriter<bevy_xr::session::DestroyXrSession>,
|
||||||
mut begin: EventWriter<bevy_xr::session::BeginXrSession>,
|
mut begin: EventWriter<bevy_xr::session::BeginXrSession>,
|
||||||
mut create: EventWriter<bevy_xr::session::CreateXrSession>,
|
mut create: EventWriter<bevy_xr::session::CreateXrSession>,
|
||||||
|
state: Res<XrSharedStatus>,
|
||||||
) {
|
) {
|
||||||
if keys.just_pressed(KeyCode::KeyE) {
|
if keys.just_pressed(KeyCode::KeyE) {
|
||||||
info!("sending end");
|
info!("sending end");
|
||||||
@@ -35,6 +37,9 @@ fn handle_input(
|
|||||||
info!("sending create");
|
info!("sending create");
|
||||||
create.send_default();
|
create.send_default();
|
||||||
}
|
}
|
||||||
|
if keys.just_pressed(KeyCode::KeyI) {
|
||||||
|
info!("current state: {:?}", state.get());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// set up a simple 3D scene
|
/// set up a simple 3D scene
|
||||||
|
|||||||
@@ -115,7 +115,8 @@ fn clean_up_default_hands(
|
|||||||
query: Query<Entity, Or<(With<DefaultHandTracker>, With<DefaultHandBones>)>>,
|
query: Query<Entity, Or<(With<DefaultHandTracker>, With<DefaultHandBones>)>>,
|
||||||
) {
|
) {
|
||||||
for e in &query {
|
for e in &query {
|
||||||
cmds.entity(e).despawn();
|
info!("removing_hand_entity");
|
||||||
|
cmds.entity(e).despawn_recursive();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ 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::XrRenderSessionEnding;
|
||||||
|
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;
|
||||||
use bevy_xr::session::XrStatusChanged;
|
use bevy_xr::session::XrStatusChanged;
|
||||||
@@ -132,13 +133,11 @@ impl Plugin for OxrInitPlugin {
|
|||||||
end_xr_session
|
end_xr_session
|
||||||
.run_if(on_event::<EndXrSession>())
|
.run_if(on_event::<EndXrSession>())
|
||||||
.run_if(status_equals(XrStatus::Running)),
|
.run_if(status_equals(XrStatus::Running)),
|
||||||
destroy_xr_session
|
|
||||||
.run_if(on_event::<DestroyXrSession>())
|
|
||||||
.run_if(status_equals(XrStatus::Exiting)),
|
|
||||||
)
|
)
|
||||||
.in_set(OxrPreUpdateSet::HandleEvents),
|
.in_set(OxrPreUpdateSet::HandleEvents),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
.add_systems(XrSessionExiting, destroy_xr_session)
|
||||||
.add_systems(
|
.add_systems(
|
||||||
PostUpdate,
|
PostUpdate,
|
||||||
update_root_transform.after(TransformSystem::TransformPropagate),
|
update_root_transform.after(TransformSystem::TransformPropagate),
|
||||||
@@ -456,6 +455,7 @@ 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,6 +481,7 @@ 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");
|
||||||
@@ -489,6 +490,7 @@ 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");
|
||||||
@@ -542,6 +544,7 @@ pub fn poll_events(
|
|||||||
SessionState::IDLE => {
|
SessionState::IDLE => {
|
||||||
if status.get() == XrStatus::Available {
|
if status.get() == XrStatus::Available {
|
||||||
session_status_events.send(OxrSessionStatusEvent::Created);
|
session_status_events.send(OxrSessionStatusEvent::Created);
|
||||||
|
info!("sending create info");
|
||||||
}
|
}
|
||||||
XrStatus::Idle
|
XrStatus::Idle
|
||||||
}
|
}
|
||||||
@@ -552,6 +555,7 @@ pub fn poll_events(
|
|||||||
SessionState::STOPPING => XrStatus::Stopping,
|
SessionState::STOPPING => XrStatus::Stopping,
|
||||||
SessionState::EXITING | SessionState::LOSS_PENDING => {
|
SessionState::EXITING | SessionState::LOSS_PENDING => {
|
||||||
session_status_events.send(OxrSessionStatusEvent::AboutToBeDestroyed);
|
session_status_events.send(OxrSessionStatusEvent::AboutToBeDestroyed);
|
||||||
|
info!("sending destroy info");
|
||||||
XrStatus::Exiting
|
XrStatus::Exiting
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
@@ -583,4 +587,10 @@ pub fn destroy_xr_session_render(world: &mut World) {
|
|||||||
world.remove_resource::<OxrGraphicsInfo>();
|
world.remove_resource::<OxrGraphicsInfo>();
|
||||||
world.run_schedule(XrRenderSessionEnding);
|
world.run_schedule(XrRenderSessionEnding);
|
||||||
world.run_system_once(apply_deferred);
|
world.run_system_once(apply_deferred);
|
||||||
|
if let Some(sess) = world.remove_resource::<OxrSession>() {
|
||||||
|
unsafe {
|
||||||
|
(sess.instance().fp().destroy_session)(sess.as_raw());
|
||||||
|
}
|
||||||
|
Box::leak(Box::new(sess));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -148,7 +148,6 @@ impl OxrInstance {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Graphics agnostic wrapper around [openxr::FrameStream]
|
/// Graphics agnostic wrapper around [openxr::FrameStream]
|
||||||
#[derive(Resource)]
|
#[derive(Resource)]
|
||||||
pub struct OxrFrameStream(pub GraphicsWrap<Self>);
|
pub struct OxrFrameStream(pub GraphicsWrap<Self>);
|
||||||
@@ -283,20 +282,15 @@ impl OxrSwapchain {
|
|||||||
images.push(Api::to_wgpu_img(image, device, format, resolution)?);
|
images.push(Api::to_wgpu_img(image, device, format, resolution)?);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(OxrSwapchainImages(images.into()))
|
Ok(OxrSwapchainImages(images.leak()))
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Stores the generated swapchain images.
|
/// Stores the generated swapchain images.
|
||||||
#[derive(Debug, Deref, Resource, Clone)]
|
#[derive(Debug, Deref, Resource, Clone, Copy)]
|
||||||
pub struct OxrSwapchainImages(pub Arc<Vec<wgpu::Texture>>);
|
pub struct OxrSwapchainImages(pub &'static [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)]
|
||||||
|
|||||||
@@ -5,8 +5,11 @@ use crate::resources::{
|
|||||||
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::render::extract_resource::ExtractResourcePlugin;
|
||||||
|
use bevy::render::RenderApp;
|
||||||
use bevy_xr::session::{
|
use bevy_xr::session::{
|
||||||
status_changed_to, XrRenderSessionEnding, XrSessionCreated, XrSessionExiting, XrStatus,
|
status_changed_to, XrRenderSessionEnding, XrSessionCreated, XrSessionExiting, XrSharedStatus,
|
||||||
|
XrStatus,
|
||||||
};
|
};
|
||||||
use openxr::AnyGraphics;
|
use openxr::AnyGraphics;
|
||||||
|
|
||||||
@@ -28,10 +31,11 @@ impl Plugin for OxrSessionPlugin {
|
|||||||
run_session_status_schedules.in_set(OxrPreUpdateSet::HandleEvents),
|
run_session_status_schedules.in_set(OxrPreUpdateSet::HandleEvents),
|
||||||
);
|
);
|
||||||
app.add_systems(XrSessionExiting, clean_session);
|
app.add_systems(XrSessionExiting, clean_session);
|
||||||
app.add_systems(XrRenderSessionEnding, |mut cmds: Commands| {
|
app.sub_app_mut(RenderApp)
|
||||||
cmds.remove_resource::<OxrSession>();
|
.add_systems(XrRenderSessionEnding, |mut cmds: Commands| {
|
||||||
cmds.remove_resource::<OxrCleanupSession>();
|
// cmds.remove_resource::<OxrSession>();
|
||||||
});
|
cmds.remove_resource::<OxrCleanupSession>();
|
||||||
|
});
|
||||||
app.add_systems(
|
app.add_systems(
|
||||||
PreUpdate,
|
PreUpdate,
|
||||||
handle_stopping_state.run_if(status_changed_to(XrStatus::Stopping)),
|
handle_stopping_state.run_if(status_changed_to(XrStatus::Stopping)),
|
||||||
@@ -44,9 +48,13 @@ fn handle_stopping_state(session: Res<OxrSession>, session_started: Res<OxrSessi
|
|||||||
session_started.set(false);
|
session_started.set(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clean_session(mut cmds: Commands) {
|
fn clean_session(world: &mut World) {
|
||||||
cmds.remove_resource::<OxrSession>();
|
world.insert_resource(OxrCleanupSession(true));
|
||||||
cmds.insert_resource(OxrCleanupSession(true));
|
// It should be impossible to call this if the session is Unavailable
|
||||||
|
world
|
||||||
|
.get_resource::<XrSharedStatus>()
|
||||||
|
.unwrap()
|
||||||
|
.set(XrStatus::Available);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_session_status_schedules(world: &mut World) {
|
fn run_session_status_schedules(world: &mut World) {
|
||||||
@@ -62,6 +70,11 @@ fn run_session_status_schedules(world: &mut World) {
|
|||||||
OxrSessionStatusEvent::AboutToBeDestroyed => {
|
OxrSessionStatusEvent::AboutToBeDestroyed => {
|
||||||
world.run_schedule(XrSessionExiting);
|
world.run_schedule(XrSessionExiting);
|
||||||
world.run_system_once(apply_deferred);
|
world.run_system_once(apply_deferred);
|
||||||
|
if let Some(sess) = world.remove_resource::<OxrSession>() {
|
||||||
|
// 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.
|
/// 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>;
|
||||||
|
|||||||
@@ -13,10 +13,10 @@ impl Plugin for XrSessionPlugin {
|
|||||||
.add_event::<BeginXrSession>()
|
.add_event::<BeginXrSession>()
|
||||||
.add_event::<EndXrSession>()
|
.add_event::<EndXrSession>()
|
||||||
.add_event::<XrStatusChanged>()
|
.add_event::<XrStatusChanged>()
|
||||||
.add_systems(
|
// .add_systems(
|
||||||
PreUpdate,
|
// PreUpdate,
|
||||||
handle_session.run_if(resource_exists::<XrSharedStatus>),
|
// handle_session.run_if(resource_exists::<XrSharedStatus>),
|
||||||
);
|
/* ) */;
|
||||||
}
|
}
|
||||||
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.
|
||||||
|
|||||||
Reference in New Issue
Block a user