Simulator emits button events in wrong order when "rolling" right-to-left or down-to-up

,

Edit :point_right: save some time and jump to this comment below for a summary of the actual bug. Come back here if you want repro steps.


I'm experiencing a couple of unexpected behaviors with respect to button input handler events. Consider this trivial example:

function pd.leftButtonDown() print("LEFT DOWN") end
function pd.leftButtonUp() print("LEFT UP") end
function pd.rightButtonDown() print("RIGHT DOWN") end
function pd.rightButtonUp() print("RIGHT UP") end

This works fine for discrete button presses. Pressing either button results in a corresponding down event for that button. One may then hold that button as long as desired (say, a few seconds), then release it resulting in a corresponding up event. Following these steps results in the following console output (actions interleaved as "comments"):

-- press left button
LEFT DOWN
-- wait 3 seconds
-- release left button
LEFT UP
-- press right button
RIGHT DOWN
-- wait 3 seconds
-- release right button
RIGHT UP

Easy. However, consider the case when one presses the right button before releasing the left. That yields the following:

-- press left button
LEFT DOWN
-- wait 1 second
-- press right button
LEFT UP
RIGHT DOWN
-- wait 1 second
-- release left button
-- wait 1 second
-- press left button
LEFT DOWN
RIGHT UP
-- wait 1 second
-- release right button
-- wait 1 second
-- release left button
LEFT UP

Two things about this run counter to my expectation:

  1. First, the system appears to synthesize up events for the held button when a second button is pressed before the first is released, rather than waiting for the actual release of the first button (which produces no event at at all). Note that what I'm calling a "synthesized" event does not appear to come immediately with the down event for the pressed button, but a very short time thereafter (maybe the "button held" threshold, even though it isn't supported for D-pad?).
  2. Second, even if this is expected behavior, the relative order of the down event for the newly pressed button and the synthesized up event for the already pressed one are inconsistent. Pressing the right button while holding left produces the synthesized up event for the left button before the down event for the right. Doing the inverse produces the down event for the left before the synthesized up event for the right. Another way of saying this is that the left button reports before the right, regardless.

Is this expected behavior?

Just to be extra explicit, here's the output I expected to get, following the same steps from above:

--press left button
LEFT DOWN
-- wait 1 second
-- press right button
RIGHT DOWN
-- wait 1 second
-- release left button
LEFT UP
-- wait 1 second
-- press left button
LEFT DOWN
-- wait 1 second
-- release right button
RIGHT UP
-- wait 1 second
-- release left button
LEFT UP

Upon further reflection, I’ve come to realize that item 1 — synthesized events — is probably an intentional feature of the simulator to enforce an invariant that opposing D-pad buttons can’t be pressed at the same time. However, if that’s true it reinforces my expectation that the synthesized up event should always come first.

When I’m back at my laptop I’ll try this on hardware to test the result there, and also try the same steps shown above but with left/down instead of left/right, as those should be possible to press at the same time even on hardware, and I hope will yield the expected event ordering I outlined above.

Here's the bug :point_right: After further testing, I believe the only issue here is a small bug in the simulator (I'm on Mac OS running simulator version 2.3.1) which causes the synthesized "up" event to come out of order when going from right to left, or down to up, with interleaved press/release (left to right and up to down both work fine). I'll update the title of this thread accordingly.

It might also be worth a little callout explaining the constraints of the d-pad in the docs, since this wasn't obvious at first when simulating inputs with keyboard keys. For details on the tests I did to conclude this, read on…


I tested the same sequence outlined above in the simulator using left/down instead of left/right, and I can confirm that I get the expected results shown above. Press and release of each button corresponds with the physical key press regardless of interleaving and duration of press. So: the synthesized events are simulating the d-pad hardware constraint that prevents opposing buttons from being pressed at the same time.

I also tested using the left/right buttons on hardware, which produces the expected results:

-- press left on d-pad
LEFT DOWN
-- wait 1 second
-- press right on d-pad
LEFT UP
RIGHT DOWN
-- wait 1 second
-- press left on d-pad
RIGHT UP
LEFT DOWN
-- wait 1 second
-- release left button
LEFT UP

Note that the currently pressed button reports its up event before the opposing button reports a down event. This makes sense given the physical constraint, but is not what the simulator produces for left-right and down-up button transitions.