WhiteMagic / JoystickGremlin

A tool for configuring and managing joystick devices.
http://whitemagic.github.io/JoystickGremlin/
GNU General Public License v3.0
313 stars 46 forks source link

Temp Mode Switch Causes Errors in Subsequent Mode Switches #412

Open TheGoodIdeaFairy opened 2 years ago

TheGoodIdeaFairy commented 2 years ago

How to reproduce:

Set up a Temporary Mode Switch (A) in Mode-1 which points to Mode-2 On other buttons, set up a Temporary Mode Switch (B) and a Mode Switch (C) in Mode-2 which point to Mode-3 // case #1 While holding (A), press (B) then release both. You will go from 1 to 2 to 3 (release) to 2 (release) to 3 (the intent was to return to Mode-1) ... Restart JG // case #2 While holding (A), press (C) then release both. You will go from 1 to 2 to 3 then back to 2 (the intent was to stay in Mode-3)

Case #1 has a workaround... create two macros for (A): press to switch to Mode-2, release to switch to Mode-1 Case #2 has no workaround without clunky and convoluted additional logic (purging the Prev-Mode buffer by leaving Mode-3 and using the Switch-to-Prev phase of (A) to return to 3) and has no way of functioning alongside the workaround for Case #1 afaik.

Considering Case #1 is probably the expected behavior of Temporary Mode Switch, I recommend changing this actions default logic to the workaround. The layer where the temp switch was pressed being overwritten seems like unintended behavior here. Intuitively, chains of temp switches should return to the initial layer.

Because there is simply no good way of mode switching from a temporary mode switch, I have two possible recommendations. 1) Add logic to Mode Switch which, when a Temp Mode Switch is currently pressed, will first overwrite the Prev-Mode buffer with the target Mode then executes the Mode Switch. When the Temp Switch button is released, the Return to Previous will harmlessly fire leaving you at your target. 2) Add logic to Mode Switch which, when a Temp Mode Switch is currently pressed, cancels or blocks the release action of the Temp Mode Switch(s). When released, no Return to Previous is fired.

WhiteMagic commented 2 years ago

I can't actually tell what actions are defined where from the description, also knowing what relation the modes have to each other is important to know for these cases. Though the logic of the temporary mode switch is very simple:

  1. upon pressing the associated physical button switch to the desired mode
  2. upon release of the associated physical button return to the initial triggering mode

There is no complicated logic in it that attempts to figure out what someone might want to achieve. It is a simple reactive system, trigger mode switch, and hook a reaction to the release event. Actions in Gremlin are always independent of any other action by design, as such the suggested changes won't actually work. It also seems that for the desired behavior the temporary mode switch is simply the wrong action and a collection of switch to mode actions with conditions would be the actual solution.

TheGoodIdeaFairy commented 2 years ago

Sorry for the lack of clarity. I was hoping the example would help illustrate my point, but it seems to have confused it instead.

The two steps you describe are what intuitively comes to mind as the expected behavior. However, when an additional layer switch (of any variety) is called while still holding the initial temporary mode switch, the release event behaves in unexpected ways. The action to return to the initial triggering mode seems to be replaced or altered. The release action to switch layers isn't lost, but the targeted mode is lost. It behaves in a way that suggests there is maybe a global variable intended to hold the "previous layer", and subsequent switch actions are overwriting this variable before the initial temporary switch has the chance to use the value stored there.*

*I haven't yet confirmed whether there is or is not such a variable, but from several hours of testing over the weeks this is the only explanation I could come up with that really "groks" with my observations.

PS. I'm now aware that there is an upcoming full rework of the codebase, and I fully expect many or all of my observations, bugs, and/or suggestions will not end up in the codebase... certainly not in the current major version. I am hoping that the brain dump might still help in avoiding similar issues or provide inspiration toward improvements in the next version. I look forward to fleshing out some (hopefully useful) plugins for the community, and perhaps eventually helping to maintain this beast of a utility.

WhiteMagic commented 2 years ago

I just looked through the code and yeah the mode switch has a previous mode stored away in an entirely different class. I had thought I used a different mechanism to implement the switch back using something that'd be more suitable. So the code will actively overwrite whatever the previous mode was on a mode switch and there isn't a real way around the way this is done.

When I get around to reimplementing that action it's likely it will simply not use that approach at all but rather just remember where it has to jump back to independent of whatever else happens, as that's more in line with Gremlin's philosophy for actions.

And ideas are always welcome just that oftentimes they either end up being something that's neat but will take a backseat to a bunch of other work, doesn't fit the general behavior of Gremlin, or needs to be tackled in an entirely different manner. Though they always influence things just maybe not in a directly visible manner.