diff options
author | Manish Goregaokar <manishsmail@gmail.com> | 2019-02-19 17:45:44 +0530 |
---|---|---|
committer | Manish Goregaokar <manishsmail@gmail.com> | 2019-02-19 17:50:46 +0530 |
commit | c44b63f335dacc26f68655c417a9edd1b9bb2706 (patch) | |
tree | 4a95d6ff5cf44a782a3237066c74dacd8f6ec84b /components/script/dom/xr.rs | |
parent | 37872b8b9c57ab6d08ef32721cf653835b8e6a9a (diff) | |
download | servo-c44b63f335dacc26f68655c417a9edd1b9bb2706.tar.gz servo-c44b63f335dacc26f68655c417a9edd1b9bb2706.zip |
Handle erroring out when there are multiple immersive sessions
Diffstat (limited to 'components/script/dom/xr.rs')
-rw-r--r-- | components/script/dom/xr.rs | 36 |
1 files changed, 35 insertions, 1 deletions
diff --git a/components/script/dom/xr.rs b/components/script/dom/xr.rs index 3e18ee0d279..13838ac2b20 100644 --- a/components/script/dom/xr.rs +++ b/components/script/dom/xr.rs @@ -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 |