Re: [Gamepad] Liveness of Gamepad objects

2014-04-30 Thread Florian Bösch
There's two aspects that should not be overlooked.

   1. Some events only make sense in unison. For instance the input of a
   2-axis knob. On many OS implementations, change events for each axis arrive
   separately in short succession. However to an application programmer,
   getting first the X axis change, and then the Y axis change may not make
   sense. A common result of doing this would be that instead of getting a
   diagonal movement, a stepped movement is displayed. The technique employed
   by many native application programmers to this kind of problem is to
   coalesce events they deem to belong together into one event.
   2. Input - Output latency is a significant concern for input devices
   used to produce an output. One way to minimize the latency is called time
   warp in which most of the frames tasks that are not directly influenced by
   the input are completed. Then the program idles till nearly the end of the
   frame, polls the input (which should arrive fresh) and then completes the
   rest of the (ideally constant time) tasks just before the frame runs out.


Re: [Gamepad] Liveness of Gamepad objects

2014-04-30 Thread Ted Mielczarek
On 4/30/2014 12:21 AM, Glenn Maynard wrote:

 My original prototype provided the events mentioned above. The
 feedback I received was overwhelmingly in favor of a polling API
 instead[3]. I decided to go ahead with that (actually Scott beat
 me to the punch and implemented that in Chrome first), figuring we
 could always spec events in a future revision.


 (Please try to direct conversations here or to the whatwg list, so
 everyone has a chance to participate...)
If you note the dates you can see that this was well before
standardization work started. This was just feedback on a prototype.


 Supporting polling is a separate issue from whether the Gamepad
 interface is live or a snapshot.  You definitely want to be able to
 retrieve a snapshot of the current state, and as long as you can do
 that you automatically support polling.


Yes, it's true. In any event, this is going a bit afield. We're not
going to spec events for the first version of the spec. We have two
mostly-compatible implementations shipping in Firefox and Chrome
supporting polling, I'd just like to nail down the remaining uncertain
bits of the spec (like the topic at hand) so others can ship compatible
implementations. Once that's done we can certainly discuss features for
a next revision, there's already a wiki page[1] to gather ideas.

 (Aside: I'm not sure if the top one is correct.  Does
 getGamepads()[n].index == n, so that gamepadState[i] always
 corresponds to lastGamepadState[i]?  The spec suggests that with
 index of the gamepad in the Navigator, but I'm not sure.  If so,
 what is getGamepads()[1] if controller index 1 is disconnected, since
 you can't reorder the later items?  undefined?)
Yes, Gamepad.index is the index into the list returned by
navigator.getGamepads(), so that holds true. If the latter portion isn't
answered in the spec I can add some text to clarify: there are allowed
to be holes in the array where controllers were removed. I'm not sure
what they are in current practice, but null or undefined both seem like
legitimate values.

-Ted

1. https://www.w3.org/wiki/Webapps/GamepadFeatures



Re: [Gamepad] Liveness of Gamepad objects

2014-04-30 Thread Ted Mielczarek
On 4/29/2014 10:39 AM, Ted Mielczarek wrote:
 The only major issue that needs to be fixed in the Gamepad API spec
 currently is the liveness of Gamepad objects[1].
After reading through the discussion here I'm leaning towards specifying
the snapshot behavior that Chrome implements. Regardless of whether we
spec an event-based update mechanism in the future, being able to refer
to a snapshot of Gamepad state seems useful, and there's not much
overhead in calling navigator.getGamepads()[i] instead of referring
directly to a saved Gamepad object.

My only reservation is that if Gamepad becomes a snapshot instead of a
live object, it feels weird to suggest adding output methods to it (like
adding vibration support). Perhaps I'm overthinking it, though.

Any other thoughts here?

-Ted



Re: [Gamepad] Liveness of Gamepad objects

2014-04-30 Thread Glenn Maynard
On Wed, Apr 30, 2014 at 5:58 AM, Ted Mielczarek t...@mozilla.com wrote:

 Yes, it's true. In any event, this is going a bit afield. We're not going
 to spec events for the first version of the spec.


Examining the features that each design would make easier or harder isn't
afield.

On Wed, Apr 30, 2014 at 6:11 AM, Ted Mielczarek t...@mozilla.com wrote:

 My only reservation is that if Gamepad becomes a snapshot instead of a
 live object, it feels weird to suggest adding output methods to it (like
 adding vibration support). Perhaps I'm overthinking it, though.


I cut out a comment about that for length, actually.  It would be better to
have separate objects for the gamepad itself and where output methods live,
and another interface holding a snapshot of an input state.  Then, you'd
just call gamepad.getState() to read the state for that device.  It's also
a natural place for an event interface to live, and for input state that
doesn't change, like the device's ID.

I definitely wouldn't make Gamepad live just to avoid doing that, though.
 It could always be added later, by adding a GamepadDevice interface, eg:

gamepadDevices = navigator.getGamepadDevices();
gamepad = gamepads[0];
state = gamepad.getState();

equivalent to navigator.getGamepads()[0].

--
Glenn Maynard


Re: [Gamepad] Liveness of Gamepad objects

2014-04-30 Thread Rick Waldron
On Wed, Apr 30, 2014 at 12:21 AM, Glenn Maynard gl...@zewt.org wrote:

 On Tue, Apr 29, 2014 at 8:25 PM, Ted Mielczarek t...@mozilla.com wrote:

  On 4/29/2014 7:28 PM, Glenn Maynard wrote:

   Gamepad objects should definitely be a snapshot.  Otherwise, change
 events could only expose the most recent state of the gamepad.  For
 example, if the user presses a button and then releases it very quickly
 (before the down press gets handled by script), and you fire two change
 events, the script would never see the buttons as pressed.


 This is a good point--if we have live objects then if we do implement
 change events we'd need to store the state elsewhere. Firefox has
 gamepadbutton{press,release} events and gamepadaxismove events[1][2]
 (behind a pref), they actually do this already but it's not fantastic.


 There should simply be a change event, which is fired when any property
 changes.  (Some rate clamping might be needed for analog inputs, which
 could change very quickly, but that's an implementation detail.)

  My original prototype provided the events mentioned above. The feedback I
 received was overwhelmingly in favor of a polling API instead[3]. I decided
 to go ahead with that (actually Scott beat me to the punch and implemented
 that in Chrome first), figuring we could always spec events in a future
 revision.


 (Please try to direct conversations here or to the whatwg list, so
 everyone has a chance to participate...)

 Supporting polling is a separate issue from whether the Gamepad interface
 is live or a snapshot.  You definitely want to be able to retrieve a
 snapshot of the current state, and as long as you can do that you
 automatically support polling.

 That is, users can either use polling:

 onRequestAnimationFrame = function() {
 // Once we create this, it never changes, so we can compare it the
 next time around when it becomes lastGamepadState.
 var gamepadState = navigator.getGamepads();

 // Find differences between lastGamepadState and gamepadState and act
 on them:
 for(var i = 0; i  gamepadState.length; ++i)
 processInput(gamepadState[i], lastGamepadState[i]);

 // Save the current state, for comparison during the next frame.
 lastGamepadState = gamepadState;
 }

 or events:

 navigator.onGamepadChange = function(e) {
 var gamepadState = e.state;
 processInput(e.gamepadIndex, gamepadState, lastGamepadState);
 lastGamepadState[e.gamepadIndex] = gamepadState;
 }


This is exactly the semantics I described here
http://lists.w3.org/Archives/Public/public-webapps/2014AprJun/0266.html,
with the exception that the Gamepad object is live and the change event
states are snapshots.


Something else to consider: how does a Gamepad object behave with
Object.observe?

var gamepads = navigator.getGamepads();

Object.observe(gamepads[0], function(changeRecords) {
  ...
});


Presumably the live object design will work as expected, invoking the
observe handler at the end of each processing turn microtask
(changeRecords will always include the previous and current values), and
the snapshot does not.


Rick


RE: [Gamepad] Liveness of Gamepad objects

2014-04-29 Thread Domenic Denicola
From: Ted Mielczarek t...@mozilla.com

 Does anyone have any feedback on which of these seems more natural? Is there 
 any precedent in the web platform to prefer one approach over the other?

If the snapshot approach is chosen, I think it would be best to rename the 
Gamepad interface to GamepadSnapshot. Without that change, the live approach 
seems a lot more natural.


Re: [Gamepad] Liveness of Gamepad objects

2014-04-29 Thread Anne van Kesteren
On Tue, Apr 29, 2014 at 4:24 PM, Domenic Denicola
dome...@domenicdenicola.com wrote:
 If the snapshot approach is chosen, I think it would be best to rename the 
 Gamepad interface to GamepadSnapshot. Without that change, the live approach 
 seems a lot more natural.

DOM nodes are live. That is, you keep getting back the same copy, and
bits of such as attributes can change over time. I think that is
generally the pattern we follow throughout the platform. Notifications
API being an exception of sorts due to its cross-realm nature.

I think the main problem with making a Gamepad live is that the
lifetime of the object has to be lifetime of the associated global.
Otherwise GC can be observed through expandos.


-- 
http://annevankesteren.nl/



Re: [Gamepad] Liveness of Gamepad objects

2014-04-29 Thread Boris Zbarsky

On 4/29/14, 11:32 AM, Anne van Kesteren wrote:

I think the main problem with making a Gamepad live is that the
lifetime of the object has to be lifetime of the associated global.
Otherwise GC can be observed through expandos.


For what it's worth, the way Gecko implements this is by setting up that 
lifetime guarantee only when an expando is added to the object (or some 
other things, like use as a WeakMap key, happen).  Until then we allow 
it to be GCed.


-Boris




Re: [Gamepad] Liveness of Gamepad objects

2014-04-29 Thread Brendan Eich

Boris Zbarsky wrote:
For what it's worth, the way Gecko implements this is by setting up 
that lifetime guarantee only when an expando is added to the object 
(or some other things, like use as a WeakMap key, happen).  Until then 
we allow it to be GCed.


What do other engines do in general? Unobservable GC is a requirement, 
if you ask me and Mark Miller.


/be



Re: [Gamepad] Liveness of Gamepad objects

2014-04-29 Thread Mark S. Miller
I don't know anything about Gamepad. Could someone provide enough context
that I can understand the question? Thanks.

(Yes, I found https://dvcs.w3.org/hg/gamepad/raw-file/default/gamepad.htmlby
googling. It's not what I need.)


On Tue, Apr 29, 2014 at 10:16 AM, Brendan Eich bren...@secure.meer.netwrote:

 Boris Zbarsky wrote:

 For what it's worth, the way Gecko implements this is by setting up that
 lifetime guarantee only when an expando is added to the object (or some
 other things, like use as a WeakMap key, happen).  Until then we allow it
 to be GCed.


 What do other engines do in general? Unobservable GC is a requirement, if
 you ask me and Mark Miller.

 /be




-- 
Cheers,
--MarkM


Re: [Gamepad] Liveness of Gamepad objects

2014-04-29 Thread Brandon Jones
I don't think that API design should be driven by implementation details,
but it may be useful to provide some background on Chrome's Gamepad
implementation here:

The current polling-only API Chrome uses is largely due to practicality
with the multiprocess architecture. The gamepad data is acquired in the
central browser process, placed in shared memory, and then polled by the
tab processes when getGamepads() is called. This cuts down on a lot of IPC
overhead that would otherwise result from constant Hey, Gamepad N
changed! messages broadcast to all tabs.

Given that, if we decide that the gamepad objects should be live and not
snapshots I think that Chrome will probably put a system in place where the
first access of a gamepad object property does a behind-the-scenes poll and
then does not poll again until control has been given back to the browser.
(Which is probably not an issue since many games will be processing input
in a rAF loop.) I can't think of any scenario where a forced policy of one
update per frame would be detrimental, but I'm open to feedback on the
matter.

If it were my call I'd vote for gamepad objects being snapshots simply
because it will add some additional overhead to make them live and it avoid
concerns about observing GC, but I don't really object to either design.

--Brandon

On Tue Apr 29 2014 at 10:18:24 AM, Brendan Eich bren...@secure.meer.net
wrote:

 Boris Zbarsky wrote:
  For what it's worth, the way Gecko implements this is by setting up
  that lifetime guarantee only when an expando is added to the object
  (or some other things, like use as a WeakMap key, happen).  Until then
  we allow it to be GCed.

 What do other engines do in general? Unobservable GC is a requirement,
 if you ask me and Mark Miller.

 /be




Re: [Gamepad] Liveness of Gamepad objects

2014-04-29 Thread Brandon Jones
On Tue Apr 29 2014 at 10:24:48 AM, Mark S. Miller erig...@google.com
wrote:

 I don't know anything about Gamepad. Could someone provide enough context
 that I can understand the question? Thanks.


The Gamepad API returns an array of Gamepad state objects when you call
getGamepads(), like so:

requestAnimationFrame(function() {
var gamepads = navigator.getGamepads();
var playerGamepad = gamepads[0];
if (playerGamepad.buttons[0].pressed) {
player.jump();
}
}

That code currently would work in both Firefox and Chrome. The Liveness
question concerns the following code:

var gamepads = navigator.getGamepads();
var playerGamepad = gamepads[0];
requestAnimationFrame(function() {
if (playerGamepad.buttons[0].pressed) {
player.jump();
}
}

In Firefox this code will be functionally equivalent to the first code
snippet, since it continues to update the values Gamepad state object after
you've acquired it. AKA: The object is live.

In Chrome, however, the gamepad state returned is a snapshot and as such
the second code snippet will not observe changes to the gamepad input.

The spec is currently ambiguous on the matter, so we want to clarify
whether or not the second code snippet is valid or not and update the
browser implementations accordingly.

--Brandon


 On Tue, Apr 29, 2014 at 10:16 AM, Brendan Eich bren...@secure.meer.netwrote:

 Boris Zbarsky wrote:

 For what it's worth, the way Gecko implements this is by setting up that
 lifetime guarantee only when an expando is added to the object (or some
 other things, like use as a WeakMap key, happen).  Until then we allow it
 to be GCed.


 What do other engines do in general? Unobservable GC is a requirement, if
 you ask me and Mark Miller.

 /be




 --
 Cheers,
 --MarkM



Re: [Gamepad] Liveness of Gamepad objects

2014-04-29 Thread Mark S. Miller
How would either make GC observable?


On Tue, Apr 29, 2014 at 10:45 AM, Brandon Jones bajo...@google.com wrote:

 On Tue Apr 29 2014 at 10:24:48 AM, Mark S. Miller erig...@google.com
 wrote:

 I don't know anything about Gamepad. Could someone provide enough context
 that I can understand the question? Thanks.


 The Gamepad API returns an array of Gamepad state objects when you call
 getGamepads(), like so:

 requestAnimationFrame(function() {
 var gamepads = navigator.getGamepads();
 var playerGamepad = gamepads[0];
 if (playerGamepad.buttons[0].pressed) {
 player.jump();
 }
 }

 That code currently would work in both Firefox and Chrome. The Liveness
 question concerns the following code:

 var gamepads = navigator.getGamepads();
 var playerGamepad = gamepads[0];
 requestAnimationFrame(function() {
 if (playerGamepad.buttons[0].pressed) {
 player.jump();
 }
 }

 In Firefox this code will be functionally equivalent to the first code
 snippet, since it continues to update the values Gamepad state object after
 you've acquired it. AKA: The object is live.

 In Chrome, however, the gamepad state returned is a snapshot and as such
 the second code snippet will not observe changes to the gamepad input.

 The spec is currently ambiguous on the matter, so we want to clarify
 whether or not the second code snippet is valid or not and update the
 browser implementations accordingly.

 --Brandon


 On Tue, Apr 29, 2014 at 10:16 AM, Brendan Eich 
 bren...@secure.meer.netwrote:

 Boris Zbarsky wrote:

 For what it's worth, the way Gecko implements this is by setting up
 that lifetime guarantee only when an expando is added to the object (or
 some other things, like use as a WeakMap key, happen).  Until then we allow
 it to be GCed.


 What do other engines do in general? Unobservable GC is a requirement,
 if you ask me and Mark Miller.

 /be




 --
 Cheers,
 --MarkM




-- 
Cheers,
--MarkM


Re: [Gamepad] Liveness of Gamepad objects

2014-04-29 Thread Rick Waldron
On Tue, Apr 29, 2014 at 10:39 AM, Ted Mielczarek t...@mozilla.com wrote:

 The only major issue that needs to be fixed in the Gamepad API spec
 currently is the liveness of Gamepad objects[1].

 Currently this is implemented differently in Firefox and Chrome--Firefox
 uses live Gamepad objects, in that you can take the .gamepad property
 from a GamepadEvent or a Gamepad from navigator.getGamepads(), assign it
 to a variable, and check its state on every pass through the event loop
 to get the latest values of .buttons[]/.axes[]. Chrome uses snapshot
 Gamepad objects, so the Gamepad you get from navigator.getGamepads() is
 static, and you have to call getGamepads() on every pass through the
 event loop to get the latest state of the controller.

 I obviously have a bias towards what I've already implemented, but I can
 see the appeal of both approaches. With the live approach you can take
 a Gamepad object and assign it as a property of another object and use
 it that way, like player.input = gamepad, which makes it easy to
 manage Gamepad input as part of other code. With the snapshot approach
 you can easily save an old snapshot so that you can compare two
 snapshots and see what's changed. (Additionally as an implementation
 detail this maps very well to the Windows XInput API, which is a
 polling-based API.)

 Does anyone have any feedback on which of these seems more natural? Is
 there any precedent in the web platform to prefer one approach over the
 other?


We just implemented gamepad entity live-ness in the dualshock-controller
module for node. The discussion is here:
https://github.com/rdepena/node-dualshock-controller/issues/27



Rick


Re: [Gamepad] Liveness of Gamepad objects

2014-04-29 Thread Rick Waldron
On Tue, Apr 29, 2014 at 1:45 PM, Brandon Jones bajo...@google.com wrote:

 On Tue Apr 29 2014 at 10:24:48 AM, Mark S. Miller erig...@google.com
 wrote:

 I don't know anything about Gamepad. Could someone provide enough context
 that I can understand the question? Thanks.


 The Gamepad API returns an array of Gamepad state objects when you call
 getGamepads(), like so:

 requestAnimationFrame(function() {
 var gamepads = navigator.getGamepads();
 var playerGamepad = gamepads[0];
 if (playerGamepad.buttons[0].pressed) {
 player.jump();
 }
 }

 That code currently would work in both Firefox and Chrome. The Liveness
 question concerns the following code:

 var gamepads = navigator.getGamepads();
 var playerGamepad = gamepads[0];
 requestAnimationFrame(function() {
 if (playerGamepad.buttons[0].pressed) {
 player.jump();
 }
 }

 In Firefox this code will be functionally equivalent to the first code
 snippet, since it continues to update the values Gamepad state object after
 you've acquired it. AKA: The object is live.

 In Chrome, however, the gamepad state returned is a snapshot and as such
 the second code snippet will not observe changes to the gamepad input.


I'd prefer to be very wrong about this, but my immediate reaction to this
is that it would be expensive to allocate these snapshot objects. Tell me
where I'm misunderstanding:

SnapShot

1. For each rAF turn:
  a. Let gp be a snapshot of gamepad
  b. Do stuff with one or more values from gp

vs.

Live

1. Let gp be gamepad
2. For each rAF turn:
  a. Do stuff with one or more values from gp


The latter also follows the general model used in Node-based hardware
programming/communication API designs.


Rick





 The spec is currently ambiguous on the matter, so we want to clarify
 whether or not the second code snippet is valid or not and update the
 browser implementations accordingly.

 --Brandon


 On Tue, Apr 29, 2014 at 10:16 AM, Brendan Eich 
 bren...@secure.meer.netwrote:

 Boris Zbarsky wrote:

 For what it's worth, the way Gecko implements this is by setting up
 that lifetime guarantee only when an expando is added to the object (or
 some other things, like use as a WeakMap key, happen).  Until then we allow
 it to be GCed.


 What do other engines do in general? Unobservable GC is a requirement,
 if you ask me and Mark Miller.

 /be




 --
 Cheers,
 --MarkM




Re: [Gamepad] Liveness of Gamepad objects

2014-04-29 Thread Boris Zbarsky

On 4/29/14, 1:46 PM, Mark S. Miller wrote:

How would either make GC observable?


Consider the following code:

  navigator.getGamepads()[0].foo = 5;
  var intervals = 0;
  var id = setInterval(function() {
++intervals;
if (navigator.getGamepads()[0].foo != 5) {
  alert(What happened after  + intervals +  intervals?);
  clearInterval(id);
}
  }, 1000);

In Chrome's current implementation, where getGamepads() returns a new 
object each time getGamepads()[0] is a new object each time this will 
consistently alert What happened after 1 intervals?.


In Firefox's current implementation this will not alert at all unless 
the set of connected gamepads changes.


In an implementation which brokenly GCed and lazily recreated the JS 
reflections of Gamepad objects, the alert could happen after some random 
number of intervals, depending on GC timing.


Does that help?

-Boris



Re: [Gamepad] Liveness of Gamepad objects

2014-04-29 Thread Ted Mielczarek
On 4/29/2014 1:34 PM, Brandon Jones wrote:
 I don't think that API design should be driven by implementation
 details, but it may be useful to provide some background on Chrome's
 Gamepad implementation here:

 The current polling-only API Chrome uses is largely due to
 practicality with the multiprocess architecture. The gamepad data is
 acquired in the central browser process, placed in shared memory, and
 then polled by the tab processes when getGamepads() is called. This
 cuts down on a lot of IPC overhead that would otherwise result from
 constant Hey, Gamepad N changed! messages broadcast to all tabs.

 Given that, if we decide that the gamepad objects should be live and
 not snapshots I think that Chrome will probably put a system in place
 where the first access of a gamepad object property does a
 behind-the-scenes poll and then does not poll again until control has
 been given back to the browser. (Which is probably not an issue since
 many games will be processing input in a rAF loop.) I can't think of
 any scenario where a forced policy of one update per frame would be
 detrimental, but I'm open to feedback on the matter.
I think what I'll wind up writing in the spec will describe the liveness
in terms of tasks[1], which is how web specs talk about the event loop
nowadays. Something like changes in the state of the gamepad should
queue a task in the task queue to update the state of the Gamepad
object. So your proposed implementation would match that exactly, which
is nice. This is what we're already doing in Firefox, either by virtue
of simply handling input on the main thread, or posting events from a
background thread that's handling input.

Performance-wise, I think this will wind up being functionally
equivalent to your existing implementation anyway--assuming that content
is polling navigator.getGamepads() in a rAF loop, you're going to be
delivering one state update per frame anyway.


 If it were my call I'd vote for gamepad objects being snapshots simply
 because it will add some additional overhead to make them live and it
 avoid concerns about observing GC, but I don't really object to either
 design.

Anne mentioned the observable GC concern, he said the spec should state
that the lifetime of Gamepad objects is tied to the lifetime of the
global, which isn't too terrible. (There aren't going to be a ton of
them in play anyway.)

I agree that having to make an architectural change like this sucks, I
wish I had spec'ed it better from the beginning. I certainly don't want
to enforce the Firefox implementation as correct just because it's mine,
that's why I started this discussion.

-Ted

1.
http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#concept-task



Re: [Gamepad] Liveness of Gamepad objects

2014-04-29 Thread Mark S. Miller
On Tue, Apr 29, 2014 at 11:07 AM, Boris Zbarsky bzbar...@mit.edu wrote:

 On 4/29/14, 1:46 PM, Mark S. Miller wrote:

 How would either make GC observable?


 Consider the following code:

   navigator.getGamepads()[0].foo = 5;
   var intervals = 0;
   var id = setInterval(function() {
 ++intervals;
 if (navigator.getGamepads()[0].foo != 5) {
   alert(What happened after  + intervals +  intervals?);
   clearInterval(id);
 }
   }, 1000);

 In Chrome's current implementation, where getGamepads() returns a new
 object each time getGamepads()[0] is a new object each time this will
 consistently alert What happened after 1 intervals?.

 In Firefox's current implementation this will not alert at all unless the
 set of connected gamepads changes.

 In an implementation which brokenly GCed and lazily recreated the JS
 reflections of Gamepad objects, the alert could happen after some random
 number of intervals, depending on GC timing.


I see. Let's not do that then ;).




 Does that help?

 -Boris




-- 
Cheers,
--MarkM


Re: [Gamepad] Liveness of Gamepad objects

2014-04-29 Thread Florian Bösch
I think both semantics are workable. I'd likely prefer the gamepad state to
be immutable from JS, because assigning state there is smelly. I'd also
prefer the option that incurs less GC overhead if possible. Beyond that, I
just think the implementations should be semantically and symbolically
identical.


On Tue, Apr 29, 2014 at 9:19 PM, Mark S. Miller erig...@google.com wrote:




 On Tue, Apr 29, 2014 at 11:07 AM, Boris Zbarsky bzbar...@mit.edu wrote:

 On 4/29/14, 1:46 PM, Mark S. Miller wrote:

 How would either make GC observable?


 Consider the following code:

   navigator.getGamepads()[0].foo = 5;
   var intervals = 0;
   var id = setInterval(function() {
 ++intervals;
 if (navigator.getGamepads()[0].foo != 5) {
   alert(What happened after  + intervals +  intervals?);
   clearInterval(id);
 }
   }, 1000);

 In Chrome's current implementation, where getGamepads() returns a new
 object each time getGamepads()[0] is a new object each time this will
 consistently alert What happened after 1 intervals?.

 In Firefox's current implementation this will not alert at all unless the
 set of connected gamepads changes.

 In an implementation which brokenly GCed and lazily recreated the JS
 reflections of Gamepad objects, the alert could happen after some random
 number of intervals, depending on GC timing.


 I see. Let's not do that then ;).




 Does that help?

 -Boris




 --
 Cheers,
 --MarkM



Re: [Gamepad] Liveness of Gamepad objects

2014-04-29 Thread Rick Waldron
On Tue, Apr 29, 2014 at 3:27 PM, Florian Bösch pya...@gmail.com wrote:

 I think both semantics are workable. I'd likely prefer the gamepad state
 to be immutable from JS, because assigning state there is smelly.


Yes, there should be no way for user code to directly alter the value of
properties that represent the state of an entity in the physical world. A
firm capabilities limitation policy is used throughout the Johnny-Five
framework to enforce the immutability of such values (implemented as
get-only accessors).


Rick


Re: [Gamepad] Liveness of Gamepad objects

2014-04-29 Thread Glenn Maynard
Gamepad objects should definitely be a snapshot.  Otherwise, change events
could only expose the most recent state of the gamepad.  For example, if
the user presses a button and then releases it very quickly (before the
down press gets handled by script), and you fire two change events, the
script would never see the buttons as pressed.

(That said, I'm confused--where's the event to tell the user that the
gamepad has changed?  Surely this API doesn't require the developer to
poll, which would lose inputs at the slightest GC skip and could never give
high resolution timing.)

I'd also be very surprised if I received a Gamepad object and its values
were live--the interface looks like a snapshot.

On Tue, Apr 29, 2014 at 9:39 AM, Ted Mielczarek t...@mozilla.com wrote:

 snapshots and see what's changed. (Additionally as an implementation
 detail this maps very well to the Windows XInput API, which is a
 polling-based API.)


You can't just map a gamepad.xButton property to
NativeInputAPI.getCurrentXButton(), because you need to guarantee that if
you read the property twice in a row without returning to the event loop
the result is always the same, even if the button state changes while the
script is executing.  You could prevent this by caching the result and
clearing the cache when scripts aren't running, of course.

On Tue, Apr 29, 2014 at 2:27 PM, Florian Bösch pya...@gmail.com wrote:

 I think both semantics are workable. I'd likely prefer the gamepad state
 to be immutable from JS, because assigning state there is smelly. I'd also
 prefer the option that incurs less GC overhead if possible. Beyond that, I
 just think the implementations should be semantically and symbolically
 identical.


No, the object should be mutable, since most web API objects have mutable
properties.  If I want to do things like

gamepadState = getGamepads()[0]
// Run the input logic, but pretend the A button isn't pressed:
gamepadState.aButton = false;
checkInput(gamepadState);

then I should be allowed to.  There's nothing strange about this in a JS
API.

-- 
Glenn Maynard


RE: [Gamepad] Liveness of Gamepad objects

2014-04-29 Thread Oren Freiberg
 If it were my call I'd vote for gamepad objects being snapshots simply 
 because it will add some additional overhead to make them live and it 
 avoid concerns about observing GC, but I don't really object to either 
 design.


Anne mentioned the observable GC concern, he said the spec should state that 
the lifetime of Gamepad objects is tied to the lifetime of the global, which 
isn't too terrible. (There aren't going to be a ton of them in play anyway.)

Originally I was leaning towards live model but I am now leaning towards a 
snapshot model being the better option. We also found that there was added 
overhead with making the values live. Having had a few developers play around 
with both the idea of a snapshot vs live I observed it was much easier for them 
to add the snapshot approach to their already published games.  

It also seemed easier for them to conceptual grab the concept I guess because 
it seemed like a more natural model that fit with their games where at each 
frame they grab the snapshot to modify that frame then repeat. 




Re: [Gamepad] Liveness of Gamepad objects

2014-04-29 Thread Brandon Jones
On Tue Apr 29 2014 at 4:28:31 PM, Glenn Maynard gl...@zewt.org wrote:

 (That said, I'm confused--where's the event to tell the user that the
 gamepad has changed?  Surely this API doesn't require the developer to
 poll, which would lose inputs at the slightest GC skip and could never give
 high resolution timing.)


This is slightly off topic, but worth addressing. The spec does not, in
fact, have any change notifications. Firefox has some experimental ones you
can enable but they're not official. This does indeed provide an
opportunity for input loss, but I'm not aware of anyone who's actually
found it to be a problem. (Given the sparse number of apps using the API,
though, that doesn't say much.)

This is good feedback, though. It may be that snapshot + change events is
the most effective way to go?


 No, the object should be mutable, since most web API objects have mutable
 properties.  If I want to do things like

 gamepadState = getGamepads()[0]
 // Run the input logic, but pretend the A button isn't pressed:
 gamepadState.aButton = false;
 checkInput(gamepadState);

  then I should be allowed to.  There's nothing strange about this in a JS
 API.


No complaints here. A good use-case for mutable properties may be a JS
script that intercepts gamepad snapshots and re-maps them in-place to a
standard mapping if the browser has not already done so.


Re: [Gamepad] Liveness of Gamepad objects

2014-04-29 Thread Glenn Maynard
On Tue, Apr 29, 2014 at 6:42 PM, Brandon Jones bajo...@google.com wrote:

 On Tue Apr 29 2014 at 4:28:31 PM, Glenn Maynard gl...@zewt.org wrote:

 (That said, I'm confused--where's the event to tell the user that the
 gamepad has changed?  Surely this API doesn't require the developer to
 poll, which would lose inputs at the slightest GC skip and could never give
 high resolution timing.)


 This is slightly off topic, but worth addressing. The spec does not, in
 fact, have any change notifications. Firefox has some experimental ones you
 can enable but they're not official. This does indeed provide an
 opportunity for input loss, but I'm not aware of anyone who's actually
 found it to be a problem. (Given the sparse number of apps using the API,
 though, that doesn't say much.)


Using snapshots makes it easier to add this later, even if it's not done
right away, since you just stash a snapshot in each event when you create
it.

I think not having change events assumed that everyone using gamepads will
have a requestAnimationFrame loop running, but not everything that might
use gamepads is a game.  Regular web pages can also use gamepads, eg. for
navigating menus.

-- 
Glenn Maynard


Re: [Gamepad] Liveness of Gamepad objects

2014-04-29 Thread Ted Mielczarek
On 4/29/2014 7:28 PM, Glenn Maynard wrote:
 Gamepad objects should definitely be a snapshot.  Otherwise, change
 events could only expose the most recent state of the gamepad.  For
 example, if the user presses a button and then releases it very
 quickly (before the down press gets handled by script), and you fire
 two change events, the script would never see the buttons as pressed.

This is a good point--if we have live objects then if we do implement
change events we'd need to store the state elsewhere. Firefox has
gamepadbutton{press,release} events and gamepadaxismove events[1][2]
(behind a pref), they actually do this already but it's not fantastic.


 (That said, I'm confused--where's the event to tell the user that the
 gamepad has changed?  Surely this API doesn't require the developer to
 poll, which would lose inputs at the slightest GC skip and could never
 give high resolution timing.)

My original prototype provided the events mentioned above. The feedback
I received was overwhelmingly in favor of a polling API instead[3]. I
decided to go ahead with that (actually Scott beat me to the punch and
implemented that in Chrome first), figuring we could always spec events
in a future revision.


 I'd also be very surprised if I received a Gamepad object and its
 values were live--the interface looks like a snapshot.

The interface is...not incredibly consistent because I designed some of
it with the live object model in mind and Scott designed some of it with
the snapshot model in mind.


 On Tue, Apr 29, 2014 at 9:39 AM, Ted Mielczarek t...@mozilla.com
 mailto:t...@mozilla.com wrote:

 snapshots and see what's changed. (Additionally as an implementation
 detail this maps very well to the Windows XInput API, which is a
 polling-based API.)


 You can't just map a gamepad.xButton property to
 NativeInputAPI.getCurrentXButton(), because you need to guarantee
 that if you read the property twice in a row without returning to the
 event loop the result is always the same, even if the button state
 changes while the script is executing.  You could prevent this by
 caching the result and clearing the cache when scripts aren't running,
 of course.


I meant mapping navigator.getGamepads to a poll of XInput and
returning the result for each gamepad there, not polling on each access
of .buttons/.axes.

-Ted

1.
http://mxr.mozilla.org/mozilla-central/source/dom/webidl/GamepadButtonEvent.webidl
2.
http://mxr.mozilla.org/mozilla-central/source/dom/webidl/GamepadAxisMoveEvent.webidl
3. https://bugzilla.mozilla.org/show_bug.cgi?id=604039



Re: [Gamepad] Liveness of Gamepad objects

2014-04-29 Thread Ted Mielczarek
On 4/29/2014 7:35 PM, Oren Freiberg wrote:

 Originally I was leaning towards live model but I am now leaning towards a 
 snapshot model being the better option. We also found that there was added 
 overhead with making the values live. Having had a few developers play around 
 with both the idea of a snapshot vs live I observed it was much easier for 
 them to add the snapshot approach to their already published games.  

 It also seemed easier for them to conceptual grab the concept I guess because 
 it seemed like a more natural model that fit with their games where at each 
 frame they grab the snapshot to modify that frame then repeat. 


This is good feedback, thanks. Currently due to the implementation
difference users are forced to consume the API as if it was providing
snapshots anyway if they want their code to work in Chrome, so settling
on a snapshot model would simply codify that existing behavior. We risk
breaking content that has special-cased Firefox's behavior or only works
in Firefox, I suppose, but the API doesn't have much surface area and
hasn't been around that long so that doesn't actually seem all that bad.

-Ted




Re: [Gamepad] Liveness of Gamepad objects

2014-04-29 Thread Rick Waldron
On Tue, Apr 29, 2014 at 7:28 PM, Glenn Maynard gl...@zewt.org wrote:

 Gamepad objects should definitely be a snapshot.  Otherwise, change events
 could only expose the most recent state of the gamepad.  For example, if
 the user presses a button and then releases it very quickly (before the
 down press gets handled by script), and you fire two change events, the
 script would never see the buttons as pressed.


The previously node-dualshock-controller API, emits change events from
the live object. The change event delivers the state of the actual
change. A user might quickly press button A and the listener for A
does whatever updating it must do in the program and has access to both the
change state and the current live state of the object.

Rick


Re: [Gamepad] Liveness of Gamepad objects

2014-04-29 Thread Rick Waldron
On Tue, Apr 29, 2014 at 9:38 PM, Rick Waldron waldron.r...@gmail.comwrote:




 On Tue, Apr 29, 2014 at 7:28 PM, Glenn Maynard gl...@zewt.org wrote:

 Gamepad objects should definitely be a snapshot.  Otherwise, change
 events could only expose the most recent state of the gamepad.  For
 example, if the user presses a button and then releases it very quickly
 (before the down press gets handled by script), and you fire two change
 events, the script would never see the buttons as pressed.


 The previously node-dualshock-controller API, emits change events from
 the live object. The change event delivers the state of the actual
 change. A user might quickly press button A and the listener for A
 does whatever updating it must do in the program and has access to both the
 change state and the current live state of the object.



The node-xbox-controller module also follows this design.

Rick


Re: [Gamepad] Liveness of Gamepad objects

2014-04-29 Thread Glenn Maynard
On Tue, Apr 29, 2014 at 8:25 PM, Ted Mielczarek t...@mozilla.com wrote:

  On 4/29/2014 7:28 PM, Glenn Maynard wrote:

   Gamepad objects should definitely be a snapshot.  Otherwise, change
 events could only expose the most recent state of the gamepad.  For
 example, if the user presses a button and then releases it very quickly
 (before the down press gets handled by script), and you fire two change
 events, the script would never see the buttons as pressed.


 This is a good point--if we have live objects then if we do implement
 change events we'd need to store the state elsewhere. Firefox has
 gamepadbutton{press,release} events and gamepadaxismove events[1][2]
 (behind a pref), they actually do this already but it's not fantastic.


There should simply be a change event, which is fired when any property
changes.  (Some rate clamping might be needed for analog inputs, which
could change very quickly, but that's an implementation detail.)

My original prototype provided the events mentioned above. The feedback I
 received was overwhelmingly in favor of a polling API instead[3]. I decided
 to go ahead with that (actually Scott beat me to the punch and implemented
 that in Chrome first), figuring we could always spec events in a future
 revision.


(Please try to direct conversations here or to the whatwg list, so everyone
has a chance to participate...)

Supporting polling is a separate issue from whether the Gamepad interface
is live or a snapshot.  You definitely want to be able to retrieve a
snapshot of the current state, and as long as you can do that you
automatically support polling.

That is, users can either use polling:

onRequestAnimationFrame = function() {
// Once we create this, it never changes, so we can compare it the next
time around when it becomes lastGamepadState.
var gamepadState = navigator.getGamepads();

// Find differences between lastGamepadState and gamepadState and act
on them:
for(var i = 0; i  gamepadState.length; ++i)
processInput(gamepadState[i], lastGamepadState[i]);

// Save the current state, for comparison during the next frame.
lastGamepadState = gamepadState;
}

or events:

navigator.onGamepadChange = function(e) {
var gamepadState = e.state;
processInput(e.gamepadIndex, gamepadState, lastGamepadState);
lastGamepadState[e.gamepadIndex] = gamepadState;
}

In either case, gamepadState is a static snapshot.

(Aside: I'm not sure if the top one is correct.  Does
getGamepads()[n].index == n, so that gamepadState[i] always corresponds to
lastGamepadState[i]?  The spec suggests that with index of the gamepad in
the Navigator, but I'm not sure.  If so, what is getGamepads()[1] if
controller index 1 is disconnected, since you can't reorder the later
items?  undefined?)

-- 
Glenn Maynard