diff options
author | Manish Goregaokar <manishsmail@gmail.com> | 2019-07-05 14:01:36 -0700 |
---|---|---|
committer | Manish Goregaokar <manishsmail@gmail.com> | 2019-07-11 11:12:59 -0700 |
commit | fb105d9ff206528b257977cdf3bf5ca45a0f5f6f (patch) | |
tree | 1dd28aa6e6ff1fad659af027f53e96784657edee | |
parent | b7eacebd1022251c9ed7a35c5d9871280b1c3549 (diff) | |
download | servo-fb105d9ff206528b257977cdf3bf5ca45a0f5f6f.tar.gz servo-fb105d9ff206528b257977cdf3bf5ca45a0f5f6f.zip |
Hook supportsSession() into new xr crate
-rw-r--r-- | Cargo.lock | 1 | ||||
-rw-r--r-- | components/script/Cargo.toml | 1 | ||||
-rw-r--r-- | components/script/dom/window.rs | 4 | ||||
-rw-r--r-- | components/script/dom/xr.rs | 66 |
4 files changed, 64 insertions, 8 deletions
diff --git a/Cargo.lock b/Cargo.lock index a81a8913639..80530592427 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3923,6 +3923,7 @@ dependencies = [ "tendril 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", "tinyfiledialogs 3.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "typetag 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-segmentation 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "utf-8 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/components/script/Cargo.toml b/components/script/Cargo.toml index e0f11c85434..902a4031947 100644 --- a/components/script/Cargo.toml +++ b/components/script/Cargo.toml @@ -105,6 +105,7 @@ style_traits = {path = "../style_traits"} swapper = "0.1" tendril = {version = "0.4.1", features = ["encoding_rs"]} time = "0.1.12" +typetag = "0.1" unicode-segmentation = "1.1.0" url = "1.6" utf-8 = "0.7" diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index b978d819dea..e670098ce48 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -439,8 +439,8 @@ impl Window { self.webvr_chan.clone() } - pub fn webxr_registry(&self) -> &webxr_api::Registry { - &self.webxr_registry + pub fn webxr_registry(&self) -> webxr_api::Registry { + self.webxr_registry.clone() } fn new_paint_worklet(&self) -> DomRoot<Worklet> { diff --git a/components/script/dom/xr.rs b/components/script/dom/xr.rs index 1baa640e03f..ee7033aa239 100644 --- a/components/script/dom/xr.rs +++ b/components/script/dom/xr.rs @@ -10,6 +10,7 @@ use crate::dom::bindings::codegen::Bindings::XRBinding::XRSessionCreationOptions use crate::dom::bindings::codegen::Bindings::XRBinding::{XRMethods, XRSessionMode}; use crate::dom::bindings::error::Error; use crate::dom::bindings::inheritance::Castable; +use crate::dom::bindings::refcounted::TrustedPromise; use crate::dom::bindings::reflector::{reflect_dom_object, DomObject}; use crate::dom::bindings::root::{Dom, DomRoot, MutNullableDom}; use crate::dom::event::Event; @@ -22,13 +23,16 @@ use crate::dom::vrdisplay::VRDisplay; use crate::dom::vrdisplayevent::VRDisplayEvent; use crate::dom::xrsession::XRSession; use crate::dom::xrtest::XRTest; +use crate::task_source::TaskSource; use dom_struct::dom_struct; use ipc_channel::ipc::IpcSender; +use ipc_channel::router::ROUTER; 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}; +use webxr_api::{Error as XRError, SessionMode}; #[dom_struct] pub struct XR { @@ -85,17 +89,67 @@ impl Drop for XR { } } +impl Into<SessionMode> for XRSessionMode { + fn into(self) -> SessionMode { + match self { + XRSessionMode::Immersive_vr => SessionMode::ImmersiveVR, + XRSessionMode::Immersive_ar => SessionMode::ImmersiveAR, + XRSessionMode::Inline => SessionMode::Inline, + } + } +} + impl XRMethods for XR { /// https://immersive-web.github.io/webxr/#dom-xr-supportssessionmode fn SupportsSessionMode(&self, mode: XRSessionMode, comp: InCompartment) -> Rc<Promise> { + #[derive(serde::Serialize, serde::Deserialize)] + pub struct SupportsSession { + sender: IpcSender<bool>, + } + + #[typetag::serde] + impl webxr_api::SessionSupportCallback for SupportsSession { + fn callback(&mut self, result: Result<(), XRError>) { + let _ = self.sender.send(result.is_ok()); + } + } + // XXXManishearth this should select an XR device first let promise = Promise::new_in_current_compartment(&self.global(), comp); - if mode == XRSessionMode::Immersive_vr { - promise.resolve_native(&()); - } else { - // XXXManishearth support other modes - promise.reject_error(Error::NotSupported); - } + let mut trusted = Some(TrustedPromise::new(promise.clone())); + let global = self.global(); + let window = global.as_window(); + let (task_source, canceller) = window + .task_manager() + .dom_manipulation_task_source_with_canceller(); + let (sender, receiver) = ipc::channel(global.time_profiler_chan().clone()).unwrap(); + ROUTER.add_route( + receiver.to_opaque(), + Box::new(move |message| { + // router doesn't know this is only called once + let trusted = if let Some(trusted) = trusted.take() { + trusted + } else { + error!("supportsSession callback called twice!"); + return; + }; + let message = if let Ok(message) = message.to() { + message + } else { + error!("supportsSession callback given incorrect payload"); + return; + }; + if message { + let _ = task_source.queue_with_canceller(trusted.resolve_task(()), &canceller); + } else { + let _ = task_source + .queue_with_canceller(trusted.reject_task(Error::NotSupported), &canceller); + }; + }), + ); + window + .webxr_registry() + .supports_session(mode.into(), SupportsSession { sender }); promise } |