-
Notifications
You must be signed in to change notification settings - Fork 232
Event-Driven Gamepad Input API #1000
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
base: main
Are you sure you want to change the base?
Event-Driven Gamepad Input API #1000
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi Gabriel,
Thank you for reviewing!
I have addressed your comments. I am currently iterating on the explainer and removing some content related to the threshold logic for the scope of this doc, so I have left out some comments on purpose.
Thanks
|
||
2) **Frame-Based Consolidated Event**: | ||
|
||
This approach consolidates all state changes that occur within a single frame into one event, reducing the number of events fired and preventing event spam. This is especially important for analog inputs and buttons that may change frequently within a single frame. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Input frame refers to the cycle in which the browser collects input data, which could refresh at least once per animation frame
|
||
- Consolidate button state changes within a single event structure: Instead of firing a separate event for each button state change (pressed/released, touched, value), all these changes will be consolidated into one gamepadchange event per frame. This prevents event spam and improves the efficiency of event handling. | ||
|
||
- This will also reduce CPU overhead, as the browser will fire fewer events overall, and game developers will get all necessary button information in a single event. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I’m aware that this is the current situation. This comment refers to firing frequent events (as the explainer also proposes) for button up/down, changes, and axis movements. Some users may prefer a single snapshot event to reduce the frequency of individual events being fired, which could help alleviate strain on the JavaScript main thread. There are events for individual button presses and axis changes, as well as the gamepadchange event, which captures the entire gamepad state within an input frame.
Co-authored-by: Gabriel Brito <80070607+gabrielsanbrito@users.noreply.github.com>
Co-authored-by: Gabriel Brito <80070607+gabrielsanbrito@users.noreply.github.com>
@@ -0,0 +1,201 @@ | |||
# Gamepad Button and Axis Events |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please also update the root readme.md in MSEdgeExplainers to include this explainer in the active section.
https://github.com/MicrosoftEdge/MSEdgeExplainers?tab=readme-ov-file#active-explainers-
…ithub.com/snehagarwal1/MSEdgeExplainers into user/snehagarwal/gamepad-events-explainer
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Open question:
Should we consider adding rawgamepadinputchanged.getCoalescedEvents() when { coalesce = false } ?
This would be similar in semantics and pattern to rawpointerupdate which is part of Pointer Events, see:
Co-authored-by: Gabriel Brito <80070607+gabrielsanbrito@users.noreply.github.com>
Co-authored-by: Gabriel Brito <80070607+gabrielsanbrito@users.noreply.github.com>
Co-authored-by: Gabriel Brito <80070607+gabrielsanbrito@users.noreply.github.com>
…ithub.com/snehagarwal1/MSEdgeExplainers into user/snehagarwal/gamepad-events-explainer
|
||
## User-Facing Problem | ||
|
||
The Gamepad API lacks event-driven input handling, forcing applications to rely on continuous polling to query for changes in gamepad input. The continuous polling introduces input latency, as scripts cannot synchronize with new input fast enough. If the script increases the polling frequency to mitigate input latency, it increases CPU usage, impacting efficiency and battery life of the device. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure about the CPU usage argument for the event-based API. Generating a lot of events for raw input changes can also consume a lot of CPU. In particular, analog inputs like the sticks and triggers might generate a lot of events as their value change continuously.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I also think that we should refrain from mentioning these "hardware performance" points. Also the one in the paragraph below where we claim that it will improve battery usage.
``` | ||
#### Key Points: | ||
- navigator.getGamepads() returns a snapshot of all connected gamepads. | ||
- The polling loop is driven by `requestAnimationFrame`, typically around 60Hz (matching display refresh rate), which is much lower than the internal OS poll rate (eg., 250Hz). This mismatch can result in missed input updates, making the 60Hz rate insufficient for latency-critical applications like cloud gaming. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: multiple spaces.
- The polling loop is driven by `requestAnimationFrame`, typically around 60Hz (matching display refresh rate), which is much lower than the internal OS poll rate (eg., 250Hz). This mismatch can result in missed input updates, making the 60Hz rate insufficient for latency-critical applications like cloud gaming. | |
- The polling loop is driven by `requestAnimationFrame`, typically around 60Hz (matching display refresh rate), which is much lower than the internal OS poll rate (eg., 250Hz). This mismatch can result in missed input updates, making the 60Hz rate insufficient for latency-critical applications like cloud gaming. |
|
||
## User-Facing Problem | ||
|
||
The Gamepad API lacks event-driven input handling, forcing applications to rely on continuous polling to query for changes in gamepad input. The continuous polling introduces input latency, as scripts cannot synchronize with new input fast enough. If the script increases the polling frequency to mitigate input latency, it increases CPU usage, impacting efficiency and battery life of the device. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I also think that we should refrain from mentioning these "hardware performance" points. Also the one in the paragraph below where we claim that it will improve battery usage.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks Gabriel,
Resolving the comments
``` | ||
[Exposed=Window, SecureContent] | ||
interface RawGamepadInputChangeEvent : Event { | ||
constructor(DOMString type, optional RawGamepadInputChangeEventInit eventInitDict = {}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just realized that you didn't add a definition for RawGamepadInputChangeEventInit
. We should add it too.
The current Gamepad API relies on constant polling to detect input changes, which can introduce input latency and increase CPU usage. This proposal adopts a hybrid approach that combines event-driven input handling with frame-based state consolidation, reducing unnecessary polling while maintaining responsiveness.