mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
Add support for requesting features
This commit is contained in:
parent
e0135fe783
commit
d33d21ce72
6 changed files with 66 additions and 15 deletions
|
@ -25,8 +25,8 @@ enum XRSessionMode {
|
||||||
};
|
};
|
||||||
|
|
||||||
dictionary XRSessionInit {
|
dictionary XRSessionInit {
|
||||||
sequence<DOMString> requiredFeatures;
|
sequence<any> requiredFeatures;
|
||||||
sequence<DOMString> optionalFeatures;
|
sequence<any> optionalFeatures;
|
||||||
};
|
};
|
||||||
|
|
||||||
partial interface XR {
|
partial interface XR {
|
||||||
|
|
|
@ -23,6 +23,9 @@ dictionary FakeXRDeviceInit {
|
||||||
required boolean supportsImmersive;
|
required boolean supportsImmersive;
|
||||||
required sequence<FakeXRViewInit> views;
|
required sequence<FakeXRViewInit> views;
|
||||||
|
|
||||||
|
// this is actually sequence<any>, but we don't support
|
||||||
|
// non-string features anyway
|
||||||
|
sequence<DOMString> supportedFeatures;
|
||||||
boolean supportsUnbounded = false;
|
boolean supportsUnbounded = false;
|
||||||
// Whether the space supports tracking in inline sessions
|
// Whether the space supports tracking in inline sessions
|
||||||
boolean supportsTrackingInInline = true;
|
boolean supportsTrackingInInline = true;
|
||||||
|
|
|
@ -8,11 +8,13 @@ use crate::dom::bindings::codegen::Bindings::VRDisplayBinding::VRDisplayMethods;
|
||||||
use crate::dom::bindings::codegen::Bindings::XRBinding;
|
use crate::dom::bindings::codegen::Bindings::XRBinding;
|
||||||
use crate::dom::bindings::codegen::Bindings::XRBinding::XRSessionInit;
|
use crate::dom::bindings::codegen::Bindings::XRBinding::XRSessionInit;
|
||||||
use crate::dom::bindings::codegen::Bindings::XRBinding::{XRMethods, XRSessionMode};
|
use crate::dom::bindings::codegen::Bindings::XRBinding::{XRMethods, XRSessionMode};
|
||||||
|
use crate::dom::bindings::conversions::{ConversionResult, FromJSValConvertible};
|
||||||
use crate::dom::bindings::error::Error;
|
use crate::dom::bindings::error::Error;
|
||||||
use crate::dom::bindings::inheritance::Castable;
|
use crate::dom::bindings::inheritance::Castable;
|
||||||
use crate::dom::bindings::refcounted::{Trusted, TrustedPromise};
|
use crate::dom::bindings::refcounted::{Trusted, TrustedPromise};
|
||||||
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject};
|
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject};
|
||||||
use crate::dom::bindings::root::{Dom, DomRoot, MutNullableDom};
|
use crate::dom::bindings::root::{Dom, DomRoot, MutNullableDom};
|
||||||
|
use crate::dom::bindings::trace::RootedTraceableBox;
|
||||||
use crate::dom::event::Event;
|
use crate::dom::event::Event;
|
||||||
use crate::dom::eventtarget::EventTarget;
|
use crate::dom::eventtarget::EventTarget;
|
||||||
use crate::dom::gamepad::Gamepad;
|
use crate::dom::gamepad::Gamepad;
|
||||||
|
@ -33,7 +35,7 @@ use std::cell::Cell;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use webvr_traits::{WebVRDisplayData, WebVRDisplayEvent, WebVREvent, WebVRMsg};
|
use webvr_traits::{WebVRDisplayData, WebVRDisplayEvent, WebVREvent, WebVRMsg};
|
||||||
use webvr_traits::{WebVRGamepadData, WebVRGamepadEvent, WebVRGamepadState};
|
use webvr_traits::{WebVRGamepadData, WebVRGamepadEvent, WebVRGamepadState};
|
||||||
use webxr_api::{Error as XRError, Frame, Session, SessionMode};
|
use webxr_api::{Error as XRError, Frame, Session, SessionInit, SessionMode};
|
||||||
|
|
||||||
#[dom_struct]
|
#[dom_struct]
|
||||||
pub struct XR {
|
pub struct XR {
|
||||||
|
@ -154,13 +156,16 @@ impl XRMethods for XR {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://immersive-web.github.io/webxr/#dom-xr-requestsession
|
/// https://immersive-web.github.io/webxr/#dom-xr-requestsession
|
||||||
|
#[allow(unsafe_code)]
|
||||||
fn RequestSession(
|
fn RequestSession(
|
||||||
&self,
|
&self,
|
||||||
mode: XRSessionMode,
|
mode: XRSessionMode,
|
||||||
_: &XRSessionInit,
|
init: RootedTraceableBox<XRSessionInit>,
|
||||||
comp: InCompartment,
|
comp: InCompartment,
|
||||||
) -> Rc<Promise> {
|
) -> Rc<Promise> {
|
||||||
let promise = Promise::new_in_current_compartment(&self.global(), comp);
|
let global = self.global();
|
||||||
|
let window = global.as_window();
|
||||||
|
let promise = Promise::new_in_current_compartment(&global, comp);
|
||||||
|
|
||||||
if mode != XRSessionMode::Inline {
|
if mode != XRSessionMode::Inline {
|
||||||
if !ScriptThread::is_user_interacting() {
|
if !ScriptThread::is_user_interacting() {
|
||||||
|
@ -176,11 +181,48 @@ impl XRMethods for XR {
|
||||||
self.set_pending();
|
self.set_pending();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut required_features = vec![];
|
||||||
|
let mut optional_features = vec![];
|
||||||
|
let cx = global.get_cx();
|
||||||
|
|
||||||
|
if let Some(ref r) = init.requiredFeatures {
|
||||||
|
for feature in r {
|
||||||
|
unsafe {
|
||||||
|
if let Ok(ConversionResult::Success(s)) =
|
||||||
|
String::from_jsval(*cx, feature.handle(), ())
|
||||||
|
{
|
||||||
|
required_features.push(s)
|
||||||
|
} else {
|
||||||
|
warn!("Unable to convert required feature to string");
|
||||||
|
promise.reject_error(Error::NotSupported);
|
||||||
|
return promise;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(ref o) = init.optionalFeatures {
|
||||||
|
for feature in o {
|
||||||
|
unsafe {
|
||||||
|
if let Ok(ConversionResult::Success(s)) =
|
||||||
|
String::from_jsval(*cx, feature.handle(), ())
|
||||||
|
{
|
||||||
|
optional_features.push(s)
|
||||||
|
} else {
|
||||||
|
warn!("Unable to convert optional feature to string");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let init = SessionInit {
|
||||||
|
required_features,
|
||||||
|
optional_features,
|
||||||
|
};
|
||||||
|
|
||||||
let promise = Promise::new_in_current_compartment(&self.global(), comp);
|
let promise = Promise::new_in_current_compartment(&self.global(), comp);
|
||||||
let mut trusted = Some(TrustedPromise::new(promise.clone()));
|
let mut trusted = Some(TrustedPromise::new(promise.clone()));
|
||||||
let this = Trusted::new(self);
|
let this = Trusted::new(self);
|
||||||
let global = self.global();
|
|
||||||
let window = global.as_window();
|
|
||||||
let (task_source, canceller) = window
|
let (task_source, canceller) = window
|
||||||
.task_manager()
|
.task_manager()
|
||||||
.dom_manipulation_task_source_with_canceller();
|
.dom_manipulation_task_source_with_canceller();
|
||||||
|
@ -210,7 +252,7 @@ impl XRMethods for XR {
|
||||||
);
|
);
|
||||||
window
|
window
|
||||||
.webxr_registry()
|
.webxr_registry()
|
||||||
.request_session(mode.into(), sender, frame_sender);
|
.request_session(mode.into(), init, sender, frame_sender);
|
||||||
|
|
||||||
promise
|
promise
|
||||||
}
|
}
|
||||||
|
@ -232,7 +274,7 @@ impl XR {
|
||||||
let session = match response {
|
let session = match response {
|
||||||
Ok(session) => session,
|
Ok(session) => session,
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
promise.reject_native(&());
|
promise.reject_error(Error::NotSupported);
|
||||||
return;
|
return;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -69,8 +69,10 @@ impl XRTest {
|
||||||
|
|
||||||
impl XRTestMethods for XRTest {
|
impl XRTestMethods for XRTest {
|
||||||
/// https://github.com/immersive-web/webxr-test-api/blob/master/explainer.md
|
/// https://github.com/immersive-web/webxr-test-api/blob/master/explainer.md
|
||||||
|
#[allow(unsafe_code)]
|
||||||
fn SimulateDeviceConnection(&self, init: &FakeXRDeviceInit) -> Rc<Promise> {
|
fn SimulateDeviceConnection(&self, init: &FakeXRDeviceInit) -> Rc<Promise> {
|
||||||
let p = Promise::new(&self.global());
|
let global = self.global();
|
||||||
|
let p = Promise::new(&global);
|
||||||
|
|
||||||
let origin = if let Some(ref o) = init.viewerOrigin {
|
let origin = if let Some(ref o) = init.viewerOrigin {
|
||||||
match get_origin(&o) {
|
match get_origin(&o) {
|
||||||
|
@ -104,12 +106,19 @@ impl XRTestMethods for XRTest {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let supported_features = if let Some(ref s) = init.supportedFeatures {
|
||||||
|
s.iter().cloned().map(String::from).collect()
|
||||||
|
} else {
|
||||||
|
vec![]
|
||||||
|
};
|
||||||
|
|
||||||
let init = MockDeviceInit {
|
let init = MockDeviceInit {
|
||||||
viewer_origin: origin,
|
viewer_origin: origin,
|
||||||
views,
|
views,
|
||||||
supports_immersive: init.supportsImmersive,
|
supports_immersive: init.supportsImmersive,
|
||||||
supports_unbounded: init.supportsUnbounded,
|
supports_unbounded: init.supportsUnbounded,
|
||||||
floor_origin,
|
floor_origin,
|
||||||
|
supported_features,
|
||||||
};
|
};
|
||||||
|
|
||||||
let global = self.global();
|
let global = self.global();
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
[xrDevice_requestSession_immersive_unsupported.https.html]
|
|
||||||
[Requesting an immersive session when unsupported rejects]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
[xrSession_features_deviceSupport.https.html]
|
[xrSession_features_deviceSupport.https.html]
|
||||||
|
expected: ERROR
|
||||||
[Immersive XRSession requests with no supported device should reject]
|
[Immersive XRSession requests with no supported device should reject]
|
||||||
expected: FAIL
|
expected: TIMEOUT
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue