Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gamepad API implementation #16260

Merged
merged 1 commit into from Apr 13, 2017
Merged

Gamepad API implementation #16260

merged 1 commit into from Apr 13, 2017

Conversation

@MortimerGoro
Copy link
Contributor

MortimerGoro commented Apr 4, 2017

Gamepad API implementation. Tested with HTC Vive and Daydream controllers ;)


  • ./mach build -d does not report any errors
  • ./mach test-tidy does not report any errors
  • These changes fix #10977

This change is Reviewable

@highfive
Copy link

highfive commented Apr 4, 2017

Heads up! This PR modifies the following files:

  • @asajeffrey: components/constellation/constellation.rs
  • @wafflespeanut: python/tidy/servo_tidy/tidy.py
  • @fitzgen: components/script/dom/gamepadbutton.rs, components/script/dom/navigator.rs, components/script/dom/gamepadbuttonlist.rs, components/script/dom/mod.rs, components/script/dom/vr.rs, components/script/dom/gamepad.rs, components/script_traits/lib.rs, components/script_traits/lib.rs, components/script/dom/webidls/GamepadEvent.webidl, components/script/dom/webidls/GamepadList.webidl, components/script/dom/gamepadlist.rs, components/script/dom/vrpose.rs, components/script/dom/webidls/Navigator.webidl, components/script/dom/webidls/GamepadButton.webidl, components/script/dom/webidls/GamepadButtonList.webidl, components/script/dom/gamepadevent.rs, components/script/dom/webidls/Gamepad.webidl, components/script/script_thread.rs
  • @KiChjang: components/script/dom/gamepadbutton.rs, components/script/dom/navigator.rs, components/script/dom/gamepadbuttonlist.rs, components/script/dom/mod.rs, components/script/dom/vr.rs, components/script/dom/gamepad.rs, components/script_traits/lib.rs, components/script_traits/lib.rs, components/script/dom/webidls/GamepadEvent.webidl, components/script/dom/webidls/GamepadList.webidl, components/script/dom/gamepadlist.rs, components/script/dom/vrpose.rs, components/script/dom/webidls/Navigator.webidl, components/script/dom/webidls/GamepadButton.webidl, components/script/dom/webidls/GamepadButtonList.webidl, components/script/dom/gamepadevent.rs, components/script/dom/webidls/Gamepad.webidl, components/script/script_thread.rs
@highfive
Copy link

highfive commented Apr 4, 2017

warning Warning warning

  • These commits modify unsafe code. Please review it carefully!
  • These commits modify script code, but no tests are modified. Please consider adding a test!
@nox nox assigned nox and unassigned asajeffrey Apr 5, 2017
Copy link
Member

nox left a comment

First review pass.

#[dom_struct]
pub struct Gamepad {
reflector_: Reflector,
gamepad_id: Cell<u64>,

This comment has been minimized.

Copy link
@nox

nox Apr 5, 2017

Member

This field does not appear to need to be mutable, use a bare u64 instead.

pub struct Gamepad {
reflector_: Reflector,
gamepad_id: Cell<u64>,
id: DOMRefCell<String>,

This comment has been minimized.

Copy link
@nox

nox Apr 5, 2017

Member

This field does not appear to need to be mutable, use a bare String instead.

reflector_: Reflector,
gamepad_id: Cell<u64>,
id: DOMRefCell<String>,
index: Cell<u32>,

This comment has been minimized.

Copy link
@nox

nox Apr 5, 2017

Member

This field does not appear to need to be mutable, use a bare u32 instead.

This comment has been minimized.

Copy link
@MortimerGoro

MortimerGoro Apr 6, 2017

Author Contributor

Now it's mutable to ensure that the index is correct if more Gamepad providers are added in the future.

This comment has been minimized.

Copy link
@nox

nox Apr 6, 2017

Member

If more gamepad providers are added, why would the index of this particular gamepad change?

This comment has been minimized.

Copy link
@MortimerGoro

MortimerGoro Apr 6, 2017

Author Contributor

I'm talking about not WebVR related gamepad providers. The index is unkown until it is added to the global gamepad array here: 42f8a81#diff-4ca88ffda625c3517cee6640aac60b99R140 The index must match the final position in the array.

This comment has been minimized.

Copy link
@nox

nox Apr 6, 2017

Member

I guess I don't understand why this field is needed then. Could you document it?

This comment has been minimized.

Copy link
@nox

nox Apr 6, 2017

Member

Oh I understand now. Could you find a different design for this? I'm pretty sure we don't even need the index at all for now, it would matter only if you had hundreds of gamepads. No need to keep the index in the list in mind, just linearly search for it in the GamepadList object.

This comment has been minimized.

Copy link
@MortimerGoro

MortimerGoro Apr 6, 2017

Author Contributor

In order to do the dynamic search I would need to add a reference to the Gamepadlist in a Gamepad object (Gamepads are unaware of the container) which seems worse than a plain i32 automatically updated by the gamepadlist. Another way would be to get the gamepadlist from window->navigator->gamepadlist. Not too fond on both ideas, but I prefer the second solution. What do you think?

id: DOMRefCell<String>,
index: Cell<u32>,
connected: Cell<bool>,
timestamp: Cell<f64>,

This comment has been minimized.

Copy link
@nox

nox Apr 5, 2017

Member

This field does not appear to need to be mutable, use a bare f64 instead.

index: Cell<u32>,
connected: Cell<bool>,
timestamp: Cell<f64>,
mapping_type: DOMRefCell<String>,

This comment has been minimized.

Copy link
@nox

nox Apr 5, 2017

Member

This field does not appear to need to be mutable, use a bare String instead.

.map(|g| Root::from_ref(&**g))
}

fn sync_gamepad(&self, data: Option<WebVRGamepadData>, state: &WebVRGamepadState) {

This comment has been minimized.

Copy link
@nox

nox Apr 5, 2017

Member

Take a Option<&WebVRGamepadData> here, this avoids a cloning operation when handling WebVRGamepadEvent::Connect above.

This comment has been minimized.

Copy link
@MortimerGoro

MortimerGoro Apr 6, 2017

Author Contributor

Changed to use move semantics, so the clone above is not required either

/// Notifies the script thread of a WebVR device event
WebVREvent(PipelineId, WebVREventMsg)
/// Notifies the script thread of WebVR events.
WebVREvent(PipelineId, Vec<WebVREventMsg>)

This comment has been minimized.

Copy link
@nox

nox Apr 5, 2017

Member

Rename this WebVREvents.

/// Dispatch a WebVR event to the subscribed script threads.
WebVREvent(Vec<PipelineId>, WebVREventMsg),
/// Dispatch WebVR events to the subscribed script threads.
WebVREvent(Vec<PipelineId>, Vec<WebVREventMsg>),

This comment has been minimized.

Copy link
@nox

nox Apr 5, 2017

Member

Rename this WebVREvents.

match ev {
VREvent::Display(ev) => WebVREventMsg::DisplayEvent(ev),
VREvent::Gamepad(ev) => WebVREventMsg::GamepadEvent(ev),
}

This comment has been minimized.

Copy link
@nox

nox Apr 5, 2017

Member

Why do we even have a WebVREventMsg type if VREvent is exactly the same?

This comment has been minimized.

Copy link
@MortimerGoro

MortimerGoro Apr 6, 2017

Author Contributor

I did that to have the possibility to add some internal events in the future. But it's not needed now, so I unified the event and will only change that if required in the future.

@@ -74,6 +74,7 @@
"//url.spec.whatwg.org",
"//xhr.spec.whatwg.org",
"//w3c.github.io",
"//www.w3.org",

This comment has been minimized.

Copy link
@nox

nox Apr 5, 2017

Member

No, change the spec links.

@MortimerGoro MortimerGoro force-pushed the MortimerGoro:gamepad branch 2 times, most recently from dd6acf8 to 42f8a81 Apr 6, 2017
@nox
Copy link
Member

nox commented Apr 6, 2017

@MortimerGoro
Copy link
Contributor Author

MortimerGoro commented Apr 6, 2017

The GamepadList object has 2 main purposes:

  • It's used as a fast & GC friendly container to share the gamepad list between rust and javascript, without creating/updating JS arrays every frame.
  • Allows to implement the IndexGetter which will be used to hide gamepads according to privacy rules. The gamepad draft allows things like [null, [object Gamepad]]

In the prev comment I meant that Gamepad objects don't have a "parent" equivalent reference now, So I need to add the reference or go throught window.navigator to perform the linear search for the index property.

@nox
Copy link
Member

nox commented Apr 6, 2017

Sorry, I still don't understand why you need this index. I feel like this lacks a lot of documentation.

@nox
Copy link
Member

nox commented Apr 6, 2017

OOOH, disregard everything I just said, only now I realise the index is actually exposed to the Web and it is a concept defined in the spec. I guess storing the index isn't a bad idea then. Will review the rest of the changes you made.

@MortimerGoro
Copy link
Contributor Author

MortimerGoro commented Apr 6, 2017

Ok, I'll store it as i32 field then. I was confused when reading the spec too, it feels weird to expose the index of an external array inside the gamepad object, but it's defined that way: https://w3c.github.io/gamepad/#dom-gamepad-index

unsafe_no_jsmanaged_fields!(WebVRGamepadHand);

impl Gamepad {
pub fn new_inherited(gamepad_id: u32,

This comment has been minimized.

Copy link
@nox

nox Apr 7, 2017

Member

Doesn't need to be public.

display_id: u32
}

unsafe_no_jsmanaged_fields!(WebVRGamepadHand);

This comment has been minimized.

Copy link
@nox

nox Apr 7, 2017

Member

Put that in the trace module, not here in the middle of nowhere.

use dom_struct::dom_struct;
use webvr_traits::WebVRGamepadButton;

// https://www.w3.org/TR/GamepadButton/

This comment has been minimized.

Copy link
@nox

nox Apr 7, 2017

Member

This spec link is wrong.


impl GamepadButtonList {
#[allow(unrooted_must_root)]
fn new_inherited(list: Vec<JS<GamepadButton>>) -> GamepadButtonList {

This comment has been minimized.

Copy link
@nox

nox Apr 7, 2017

Member

Pass &[&GamepadButton] here (see the r method on [JS<T>]).

This comment has been minimized.

Copy link
@MortimerGoro

MortimerGoro Apr 7, 2017

Author Contributor

Thanks, the r() method is very useful for this ;)

}

fn add(&self, gamepad: &Gamepad) {
self.list.borrow_mut().push(JS::from_ref(&*gamepad));

This comment has been minimized.

Copy link
@nox

nox Apr 7, 2017

Member

What happens if the gamepad was already in the list?

This comment has been minimized.

Copy link
@MortimerGoro

MortimerGoro Apr 7, 2017

Author Contributor

This method was only called internally by add_if_not_exists. I have removed it to avoid confusions with the add_if_not_exists method.


pub fn add_if_not_exists(&self, gamepads: &[Root<Gamepad>]) {
for gamepad in gamepads {
if self.list.borrow().iter().any(|g| g.gamepad_id() == gamepad.gamepad_id()) {

This comment has been minimized.

Copy link
@nox

nox Apr 7, 2017

Member

This will add the gamepad only if it is already in the list.

// https://w3c.github.io/gamepad/#dom-navigator-getgamepads
fn Item(&self, index: u32) -> Option<Root<Gamepad>> {
if (index as usize) < self.list.borrow().len() {
Some(Root::from_ref(&*(self.list.borrow()[index as usize])))

This comment has been minimized.

Copy link
@nox

nox Apr 7, 2017

Member

Do the same thing as in GamepadButtonList::Item here.

@nox
Copy link
Member

nox commented Apr 7, 2017

Cc @larsbergstrom or anyone else with a VR kit that want to manually test this branch.

@MortimerGoro MortimerGoro force-pushed the MortimerGoro:gamepad branch from 56976e3 to 50a5c7c Apr 7, 2017
@nox
Copy link
Member

nox commented Apr 11, 2017

This needs a squash, and I would like @larsbergstrom to take a quick look. LGTM otherwise.

@nox
nox approved these changes Apr 11, 2017
@MortimerGoro MortimerGoro force-pushed the MortimerGoro:gamepad branch from 50a5c7c to fc92e9d Apr 11, 2017
.gitignore Outdated
@@ -27,3 +27,5 @@ Servo.app

# VSCode
.vscode

*.iml

This comment has been minimized.

Copy link
@nox

nox Apr 12, 2017

Member

What is this file extension btw?

This comment has been minimized.

Copy link
@MortimerGoro

MortimerGoro Apr 12, 2017

Author Contributor

It's a file automatically created by Android Studio (I use it to test on Android).

I'll remove it from here because that change belongs more to #15773, which is about to be merged

@MortimerGoro MortimerGoro force-pushed the MortimerGoro:gamepad branch from fc92e9d to 0158b5b Apr 12, 2017
@MortimerGoro
Copy link
Contributor Author

MortimerGoro commented Apr 12, 2017

Squash ready ;)

@larsbergstrom
Copy link
Contributor

larsbergstrom commented Apr 13, 2017

@bors-servo r=nox,larsbergstrom

I've tested the gamekit stuff and can confirm controllers work :-)

@bors-servo
Copy link
Contributor

bors-servo commented Apr 13, 2017

📌 Commit 0158b5b has been approved by nox,larsbergstrom

@bors-servo
Copy link
Contributor

bors-servo commented Apr 13, 2017

Testing commit 0158b5b with merge 26c4527...

bors-servo added a commit that referenced this pull request Apr 13, 2017
Gamepad API implementation

<!-- Please describe your changes on the following line: -->

Gamepad API implementation. Tested with HTC Vive and Daydream controllers ;)

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: -->
- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy` does not report any errors
- [x] These changes fix #10977

<!-- Either: -->
- [ ] There are tests for these changes OR
- [X] These changes do not require tests because : current gamepad tests are manual (https://github.com/w3c/web-platform-tests/tree/master/gamepad). There is a  open issue about the best way to test WebVR/Gamepad without real devices immersive-web/webxr#187. We'll work on the testing suite & mock devices/data on a separate issue.

<!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.-->

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/16260)
<!-- Reviewable:end -->
@bors-servo
Copy link
Contributor

bors-servo commented Apr 13, 2017

☀️ Test successful - android, arm32, arm64, linux-dev, linux-rel-css, linux-rel-wpt, mac-dev-unit, mac-rel-css, mac-rel-wpt1, mac-rel-wpt2, windows-msvc-dev
Approved by: nox,larsbergstrom
Pushing 26c4527 to master...

@bors-servo bors-servo merged commit 0158b5b into servo:master Apr 13, 2017
3 checks passed
3 checks passed
continuous-integration/appveyor/pr AppVeyor build succeeded
Details
continuous-integration/travis-ci/pr The Travis CI build passed
Details
homu Test successful
Details
@bors-servo bors-servo mentioned this pull request Apr 13, 2017
8 of 11 tasks complete
@danShumway
Copy link

danShumway commented Jan 10, 2019

Did this ever make its way into master?

I'm still getting navigator.getGamepads is not a function. Looking around, I don't see a build flag mentioned anywhere. Any chance there's something obvious I'm missing?

@jdm
Copy link
Member

jdm commented Jan 10, 2019

It's prefed off via the dom.gamepad.enabled preference. That can be controlled from prefs.json or running with --pref dom.gamepad.enabled.

@danShumway
Copy link

danShumway commented Jan 10, 2019

Thanks! Just for future reference so I don't need to bother people as much, I assume this is the list of existing preferences?

@jdm
Copy link
Member

jdm commented Jan 10, 2019

Generally yes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked issues

Successfully merging this pull request may close these issues.

8 participants
You can’t perform that action at this time.