diff options
Diffstat (limited to 'components/script')
-rw-r--r-- | components/script/dom/fakexrdevice.rs | 12 | ||||
-rw-r--r-- | components/script/dom/fakexrinputcontroller.rs | 61 | ||||
-rw-r--r-- | components/script/dom/webidls/FakeXRInputController.webidl | 4 | ||||
-rw-r--r-- | components/script/dom/xrinputsource.rs | 4 | ||||
-rw-r--r-- | components/script/dom/xrinputsourcearray.rs | 2 | ||||
-rw-r--r-- | components/script/dom/xrsession.rs | 6 |
6 files changed, 80 insertions, 9 deletions
diff --git a/components/script/dom/fakexrdevice.rs b/components/script/dom/fakexrdevice.rs index f1c7f4180c6..0c37b7a1e2c 100644 --- a/components/script/dom/fakexrdevice.rs +++ b/components/script/dom/fakexrdevice.rs @@ -11,8 +11,8 @@ use ipc_channel::ipc::IpcSender; use ipc_channel::router::ROUTER; use profile_traits::ipc; use webxr_api::{ - EntityType, Handedness, InputId, InputSource, MockDeviceMsg, MockInputInit, MockRegion, - MockViewInit, MockViewsInit, MockWorld, TargetRayMode, Triangle, Visibility, + EntityType, Handedness, InputId, InputSource, MockButton, MockDeviceMsg, MockInputInit, + MockRegion, MockViewInit, MockViewsInit, MockWorld, TargetRayMode, Triangle, Visibility, }; use crate::dom::bindings::codegen::Bindings::DOMPointBinding::DOMPointInit; @@ -30,7 +30,7 @@ use crate::dom::bindings::error::{Error, Fallible}; use crate::dom::bindings::refcounted::TrustedPromise; use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector}; use crate::dom::bindings::root::DomRoot; -use crate::dom::fakexrinputcontroller::FakeXRInputController; +use crate::dom::fakexrinputcontroller::{init_to_mock_buttons, FakeXRInputController}; use crate::dom::globalscope::GlobalScope; use crate::dom::promise::Promise; use crate::task_source::TaskSource; @@ -267,7 +267,10 @@ impl FakeXRDeviceMethods for FakeXRDevice { let profiles = init.profiles.iter().cloned().map(String::from).collect(); - // XXXManishearth deal with supportedButtons and selection* + let mut supported_buttons = vec![]; + if let Some(ref buttons) = init.supportedButtons { + supported_buttons.extend(init_to_mock_buttons(buttons)); + } let source = InputSource { handedness, @@ -282,6 +285,7 @@ impl FakeXRDeviceMethods for FakeXRDevice { source, pointer_origin, grip_origin, + supported_buttons, }; let global = self.global(); diff --git a/components/script/dom/fakexrinputcontroller.rs b/components/script/dom/fakexrinputcontroller.rs index 785d6f7debd..7f620639e16 100644 --- a/components/script/dom/fakexrinputcontroller.rs +++ b/components/script/dom/fakexrinputcontroller.rs @@ -5,15 +5,18 @@ use dom_struct::dom_struct; use ipc_channel::ipc::IpcSender; use webxr_api::{ - Handedness, InputId, MockDeviceMsg, MockInputMsg, SelectEvent, SelectKind, TargetRayMode, + Handedness, InputId, MockButton, MockButtonType, MockDeviceMsg, MockInputMsg, SelectEvent, + SelectKind, TargetRayMode, }; use crate::dom::bindings::codegen::Bindings::FakeXRDeviceBinding::FakeXRRigidTransformInit; -use crate::dom::bindings::codegen::Bindings::FakeXRInputControllerBinding::FakeXRInputControllerMethods; +use crate::dom::bindings::codegen::Bindings::FakeXRInputControllerBinding::{ + FakeXRButtonStateInit, FakeXRButtonType, FakeXRInputControllerMethods, +}; use crate::dom::bindings::codegen::Bindings::XRInputSourceBinding::{ XRHandedness, XRTargetRayMode, }; -use crate::dom::bindings::error::Fallible; +use crate::dom::bindings::error::{Error, Fallible}; use crate::dom::bindings::reflector::{reflect_dom_object, Reflector}; use crate::dom::bindings::root::DomRoot; use crate::dom::bindings::str::DOMString; @@ -136,4 +139,56 @@ impl FakeXRInputControllerMethods for FakeXRInputController { let t = profiles.into_iter().map(String::from).collect(); self.send_message(MockInputMsg::SetProfiles(t)); } + + /// <https://immersive-web.github.io/webxr-test-api/#dom-fakexrinputcontroller-setsupportedbuttons> + fn SetSupportedButtons(&self, supported_buttons: Vec<FakeXRButtonStateInit>) { + let supported = init_to_mock_buttons(&supported_buttons); + self.send_message(MockInputMsg::SetSupportedButtons(supported)); + } + + /// <https://immersive-web.github.io/webxr-test-api/#dom-fakexrinputcontroller-updatebuttonstate> + fn UpdateButtonState(&self, button_state: &FakeXRButtonStateInit) -> Fallible<()> { + // https://immersive-web.github.io/webxr-test-api/#validate-a-button-state + if (button_state.pressed || *button_state.pressedValue > 0.0) && !button_state.touched { + return Err(Error::Type("Pressed button must also be touched".into())); + } + if *button_state.pressedValue < 0.0 { + return Err(Error::Type("Pressed value must be non-negative".into())); + } + + // TODO: Steps 3-5 of updateButtonState + // Passing the one WPT test that utilizes this will require additional work + // to specify gamepad button/axes list lengths, as well as passing that info + // to the constructor of XRInputSource + + Ok(()) + } +} + +impl From<FakeXRButtonType> for MockButtonType { + fn from(b: FakeXRButtonType) -> Self { + match b { + FakeXRButtonType::Grip => MockButtonType::Grip, + FakeXRButtonType::Touchpad => MockButtonType::Touchpad, + FakeXRButtonType::Thumbstick => MockButtonType::Thumbstick, + FakeXRButtonType::Optional_button => MockButtonType::OptionalButton, + FakeXRButtonType::Optional_thumbstick => MockButtonType::OptionalThumbstick, + } + } +} + +/// <https://immersive-web.github.io/webxr-test-api/#parse-supported-buttons> +pub fn init_to_mock_buttons(buttons: &[FakeXRButtonStateInit]) -> Vec<MockButton> { + let supported: Vec<MockButton> = buttons + .iter() + .map(|b| MockButton { + button_type: b.buttonType.into(), + pressed: b.pressed, + touched: b.touched, + pressed_value: *b.pressedValue, + x_value: *b.xValue, + y_value: *b.yValue, + }) + .collect(); + supported } diff --git a/components/script/dom/webidls/FakeXRInputController.webidl b/components/script/dom/webidls/FakeXRInputController.webidl index 3fa4e2e02b2..94f5e5666f8 100644 --- a/components/script/dom/webidls/FakeXRInputController.webidl +++ b/components/script/dom/webidls/FakeXRInputController.webidl @@ -23,8 +23,8 @@ interface FakeXRInputController { undefined endSelection(); undefined simulateSelect(); - // void setSupportedButtons(sequence<FakeXRButtonStateInit> supportedButtons); - // void updateButtonState(FakeXRButtonStateInit buttonState); + undefined setSupportedButtons(sequence<FakeXRButtonStateInit> supportedButtons); + [Throws] undefined updateButtonState(FakeXRButtonStateInit buttonState); }; dictionary FakeXRInputSourceInit { diff --git a/components/script/dom/xrinputsource.rs b/components/script/dom/xrinputsource.rs index 8db4fb5dae3..1f4509e37d8 100644 --- a/components/script/dom/xrinputsource.rs +++ b/components/script/dom/xrinputsource.rs @@ -110,6 +110,10 @@ impl XRInputSource { self.gamepad.map_and_normalize_axes(i, *value as f64); }); } + + pub fn gamepad(&self) -> &DomRoot<Gamepad> { + &self.gamepad + } } impl XRInputSourceMethods for XRInputSource { diff --git a/components/script/dom/xrinputsourcearray.rs b/components/script/dom/xrinputsourcearray.rs index c2f15361738..0dd800336f5 100644 --- a/components/script/dom/xrinputsourcearray.rs +++ b/components/script/dom/xrinputsourcearray.rs @@ -69,6 +69,7 @@ impl XRInputSourceArray { let mut input_sources = self.input_sources.borrow_mut(); let global = self.global(); let removed = if let Some(i) = input_sources.iter().find(|i| i.id() == id) { + i.gamepad().update_connected(false, false); [DomRoot::from_ref(&**i)] } else { return; @@ -94,6 +95,7 @@ impl XRInputSourceArray { let global = self.global(); let root; let removed = if let Some(i) = input_sources.iter().find(|i| i.id() == id) { + i.gamepad().update_connected(false, false); root = [DomRoot::from_ref(&**i)]; &root as &[_] } else { diff --git a/components/script/dom/xrsession.rs b/components/script/dom/xrsession.rs index f4d3836f60b..9c81013d3a3 100644 --- a/components/script/dom/xrsession.rs +++ b/components/script/dom/xrsession.rs @@ -33,6 +33,7 @@ use crate::dom::bindings::codegen::Bindings::WindowBinding::Window_Binding::Wind use crate::dom::bindings::codegen::Bindings::XRHitTestSourceBinding::{ XRHitTestOptionsInit, XRHitTestTrackableType, }; +use crate::dom::bindings::codegen::Bindings::XRInputSourceArrayBinding::XRInputSourceArray_Binding::XRInputSourceArrayMethods; use crate::dom::bindings::codegen::Bindings::XRReferenceSpaceBinding::XRReferenceSpaceType; use crate::dom::bindings::codegen::Bindings::XRRenderStateBinding::{ XRRenderStateInit, XRRenderStateMethods, @@ -867,6 +868,11 @@ impl XRSessionMethods for XRSession { self.ended.set(true); global.as_window().Navigator().Xr().end_session(self); self.session.borrow_mut().end_session(); + // Disconnect any still-attached XRInputSources + for source in 0..self.input_sources.Length() { + self.input_sources + .remove_input_source(self, InputId(source)); + } p } |