fixed jitter
This commit is contained in:
@@ -1,9 +1,6 @@
|
||||
use bevy::app::{App, First, Plugin};
|
||||
use bevy::ecs::event::{Event, EventWriter};
|
||||
use bevy::ecs::schedule::common_conditions::resource_exists_and_changed;
|
||||
use bevy::ecs::schedule::IntoSystemConfigs;
|
||||
use bevy::ecs::system::{Res, Resource};
|
||||
use bevy::render::extract_resource::ExtractResource;
|
||||
use std::sync::{Arc, RwLock};
|
||||
|
||||
use bevy::prelude::*;
|
||||
|
||||
pub struct XrSessionPlugin;
|
||||
|
||||
@@ -14,13 +11,31 @@ impl Plugin for XrSessionPlugin {
|
||||
.add_event::<BeginXrSession>()
|
||||
.add_event::<EndXrSession>()
|
||||
.add_systems(
|
||||
First,
|
||||
handle_session.run_if(resource_exists_and_changed::<XrStatus>),
|
||||
PreUpdate,
|
||||
handle_session.run_if(resource_exists::<XrSharedStatus>),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Resource, ExtractResource, Clone, Copy, Debug, PartialEq, Eq)]
|
||||
#[derive(Resource, Clone)]
|
||||
pub struct XrSharedStatus(Arc<RwLock<XrStatus>>);
|
||||
|
||||
impl XrSharedStatus {
|
||||
pub fn new(status: XrStatus) -> Self {
|
||||
Self(Arc::new(RwLock::new(status)))
|
||||
}
|
||||
|
||||
pub fn get(&self) -> XrStatus {
|
||||
*self.0.read().unwrap()
|
||||
}
|
||||
|
||||
pub fn set(&self, status: XrStatus) {
|
||||
*self.0.write().unwrap() = status;
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
#[repr(u8)]
|
||||
pub enum XrStatus {
|
||||
/// An XR session is not available here
|
||||
Unavailable,
|
||||
@@ -39,44 +54,55 @@ pub enum XrStatus {
|
||||
}
|
||||
|
||||
pub fn handle_session(
|
||||
status: Res<XrStatus>,
|
||||
status: Res<XrSharedStatus>,
|
||||
mut previous_status: Local<Option<XrStatus>>,
|
||||
mut create_session: EventWriter<CreateXrSession>,
|
||||
mut begin_session: EventWriter<BeginXrSession>,
|
||||
mut end_session: EventWriter<EndXrSession>,
|
||||
mut _end_session: EventWriter<EndXrSession>,
|
||||
) {
|
||||
match *status {
|
||||
XrStatus::Unavailable => {}
|
||||
XrStatus::Available => {
|
||||
create_session.send_default();
|
||||
let current_status = status.get();
|
||||
if *previous_status != Some(current_status) {
|
||||
match current_status {
|
||||
XrStatus::Unavailable => {}
|
||||
XrStatus::Available => {
|
||||
create_session.send_default();
|
||||
}
|
||||
XrStatus::Idle => {}
|
||||
XrStatus::Ready => {
|
||||
begin_session.send_default();
|
||||
}
|
||||
XrStatus::Running => {}
|
||||
XrStatus::Stopping => {}
|
||||
XrStatus::Exiting => {}
|
||||
}
|
||||
XrStatus::Idle => {}
|
||||
XrStatus::Ready => {
|
||||
begin_session.send_default();
|
||||
}
|
||||
XrStatus::Running => {}
|
||||
XrStatus::Stopping => {}
|
||||
XrStatus::Exiting => {}
|
||||
}
|
||||
*previous_status = Some(current_status);
|
||||
}
|
||||
|
||||
/// A [`Condition`](bevy::ecs::schedule::Condition) system that says if the XR session is available. Returns true as long as [`XrStatus`] exists and isn't [`Unavailable`](XrStatus::Unavailable).
|
||||
pub fn session_available(status: Option<Res<XrStatus>>) -> bool {
|
||||
status.is_some_and(|s| *s != XrStatus::Unavailable)
|
||||
pub fn session_available(status: Option<Res<XrSharedStatus>>) -> bool {
|
||||
status.is_some_and(|s| s.get() != XrStatus::Unavailable)
|
||||
}
|
||||
|
||||
/// A [`Condition`](bevy::ecs::schedule::Condition) system that says if the XR session is ready or running
|
||||
pub fn session_created(status: Option<Res<XrStatus>>) -> bool {
|
||||
matches!(status.as_deref(), Some(XrStatus::Ready | XrStatus::Running))
|
||||
pub fn session_created(status: Option<Res<XrSharedStatus>>) -> bool {
|
||||
matches!(
|
||||
status.as_deref().map(XrSharedStatus::get),
|
||||
Some(XrStatus::Ready | XrStatus::Running)
|
||||
)
|
||||
}
|
||||
|
||||
/// A [`Condition`](bevy::ecs::schedule::Condition) system that says if the XR session is running
|
||||
pub fn session_running(status: Option<Res<XrStatus>>) -> bool {
|
||||
matches!(status.as_deref(), Some(XrStatus::Running))
|
||||
pub fn session_running(status: Option<Res<XrSharedStatus>>) -> bool {
|
||||
matches!(
|
||||
status.as_deref().map(XrSharedStatus::get),
|
||||
Some(XrStatus::Running)
|
||||
)
|
||||
}
|
||||
|
||||
/// A function that returns a [`Condition`](bevy::ecs::schedule::Condition) system that says if an the [`XrStatus`] is in a specific state
|
||||
pub fn status_equals(status: XrStatus) -> impl FnMut(Option<Res<XrStatus>>) -> bool {
|
||||
move |state: Option<Res<XrStatus>>| state.is_some_and(|s| *s == status)
|
||||
pub fn status_equals(status: XrStatus) -> impl FnMut(Option<Res<XrSharedStatus>>) -> bool {
|
||||
move |state: Option<Res<XrSharedStatus>>| state.is_some_and(|s| s.get() == status)
|
||||
}
|
||||
|
||||
/// Event sent to backends to create an XR session. Should only be called in the [`XrStatus::Available`] state.
|
||||
|
||||
Reference in New Issue
Block a user