mirror of
https://github.com/servo/servo.git
synced 2025-08-05 21:50:18 +01:00
Handle erroring out when there are multiple immersive sessions
This commit is contained in:
parent
37872b8b9c
commit
c44b63f335
2 changed files with 59 additions and 9 deletions
|
@ -10,7 +10,7 @@ use crate::dom::bindings::codegen::Bindings::XRBinding::{XRMethods, XRSessionMod
|
|||
use crate::dom::bindings::error::Error;
|
||||
use crate::dom::bindings::inheritance::Castable;
|
||||
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject};
|
||||
use crate::dom::bindings::root::{Dom, DomRoot};
|
||||
use crate::dom::bindings::root::{Dom, DomRoot, MutNullableDom};
|
||||
use crate::dom::event::Event;
|
||||
use crate::dom::eventtarget::EventTarget;
|
||||
use crate::dom::gamepad::Gamepad;
|
||||
|
@ -23,6 +23,7 @@ use crate::dom::xrsession::XRSession;
|
|||
use dom_struct::dom_struct;
|
||||
use ipc_channel::ipc::IpcSender;
|
||||
use profile_traits::ipc;
|
||||
use std::cell::Cell;
|
||||
use std::rc::Rc;
|
||||
use webvr_traits::{WebVRDisplayData, WebVRDisplayEvent, WebVREvent, WebVRMsg};
|
||||
use webvr_traits::{WebVRGamepadData, WebVRGamepadEvent, WebVRGamepadState};
|
||||
|
@ -32,6 +33,8 @@ pub struct XR {
|
|||
eventtarget: EventTarget,
|
||||
displays: DomRefCell<Vec<Dom<VRDisplay>>>,
|
||||
gamepads: DomRefCell<Vec<Dom<Gamepad>>>,
|
||||
pending_immersive_session: Cell<bool>,
|
||||
active_immersive_session: MutNullableDom<VRDisplay>,
|
||||
}
|
||||
|
||||
impl XR {
|
||||
|
@ -40,6 +43,8 @@ impl XR {
|
|||
eventtarget: EventTarget::new_inherited(),
|
||||
displays: DomRefCell::new(Vec::new()),
|
||||
gamepads: DomRefCell::new(Vec::new()),
|
||||
pending_immersive_session: Cell::new(false),
|
||||
active_immersive_session: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -48,6 +53,26 @@ impl XR {
|
|||
root.register();
|
||||
root
|
||||
}
|
||||
|
||||
pub fn pending_or_active_session(&self) -> bool {
|
||||
self.pending_immersive_session.get() || self.active_immersive_session.get().is_some()
|
||||
}
|
||||
|
||||
pub fn set_pending(&self) {
|
||||
self.pending_immersive_session.set(true)
|
||||
}
|
||||
|
||||
pub fn set_active_immersive_session(&self, session: &VRDisplay) {
|
||||
// XXXManishearth when we support non-immersive (inline) sessions we should
|
||||
// ensure they never reach these codepaths
|
||||
self.pending_immersive_session.set(false);
|
||||
self.active_immersive_session.set(Some(session))
|
||||
}
|
||||
|
||||
pub fn deactivate_session(&self) {
|
||||
self.pending_immersive_session.set(false);
|
||||
self.active_immersive_session.set(None)
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for XR {
|
||||
|
@ -79,6 +104,13 @@ impl XRMethods for XR {
|
|||
return promise;
|
||||
}
|
||||
|
||||
if self.pending_or_active_session() {
|
||||
promise.reject_error(Error::InvalidState);
|
||||
return promise;
|
||||
}
|
||||
// we set pending immersive session to true further down
|
||||
// to handle rejections in a cleaner way
|
||||
|
||||
let displays = self.get_displays();
|
||||
|
||||
let displays = match displays {
|
||||
|
@ -94,6 +126,8 @@ impl XRMethods for XR {
|
|||
promise.reject_error(Error::Security);
|
||||
}
|
||||
|
||||
self.set_pending();
|
||||
|
||||
let session = XRSession::new(&self.global(), &displays[0]);
|
||||
session.xr_present(promise.clone());
|
||||
promise
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue