[w3c/gamepad] Should spec a buffering/refresh interval model of gamepad data? (#22)

Noticed that there has already been quite a bit of discussion of polling vs events model for the Gamepad API. The argument in favor of events over polling has been stated that polling can lose button presses (if they fall in between the polled snapshots) and events can not. I think this is not completely accurate, and being able to lose/miss button presses is somewhat orthogonal issue to events vs polling API.

It would be possible for a browser implementation not to lose any button presses if it accumulates those up internally from OS and buffers them to be returned on the next call to getGamepads(). From the spec viewpoint, it is unclear if this is mandated or prohibited. Even in the absence of browser buffering gamepad button events, there is a question about the granularity of when new live data is allowed to come in.

a) Are conforming implementations of the Gamepad API allowed to miss physical button presses? Or is that considered an implementation bug?

b) Are Gamepad API implementations allowed to buffer up button presses (it gets as events from OS) and return them on the next polled call to navigator.getGamepads() as to not miss any button presses that might otherwise fall in between the polls?

c) Consider the following code:

    function gameProcessUserInput() {
     var pads = navigator.getGamepads();
     for(var i = 0; i < pads.length; ++i) {
      var state = pads[i];
      if (!state) continue;
      for(var j = 0; j < state.axes.length) console.log(state.axes[j]);
      for(var j = 0; j < state.buttons.length) console.log(state.buttons[j].value);
     }
    }

versus the following code:

    function numGamepads() { return navigator.getGamepads().length; }
    function getGamepad(i) { return navigator.getGamepads()[i]; }

    function gameProcessUserInput() {
     var n = numGamepads();
     for(var i = 0; i < n; ++i) {
      var state = getGamepad(i);
      if (!state) continue;
      for(var j = 0; j < state.axes.length) console.log(state.axes[j]);
      for(var j = 0; j < state.buttons.length) console.log(state.buttons[j].value);
     }
    }

In a conforming implementation, are these two functions required to print out the exact same output? Or is it expected that the outputs can differ here? That is, does each call to navigator.getGamepads() (even in subsequent calls in a single function) possibly return new live data? Or is the data provided by the browser allowed to change only e.g. at each turn of requestAnimationFrame() or setTimeout() or setInterval()?

Solving the issue via an event API might be one try, although like it was noted, sending events for analog axes, which often have noise based jitter, might lead to a large constant volume of events being sent. Also games would often need to implement their own state registry buffering of these events in order to check if user pressed button X alone, or Left Trigger + button X, or what the exact value of an analog axis was at the time of a press.

It would be possible to fix the missing button presses trouble in the polling approach by specifying when fresh button state data is allowed to come in, e.g. at each rAF() turn or similar (after exiting any event handler in which getGamepads() was called(?)), which would both allow browsers to buffer up presses for the next poll, and make the above code samples identical.

What are the latest thoughts on this front?

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/w3c/gamepad/issues/22

Received on Monday, 2 May 2016 09:00:51 UTC