Some other odd behavior of KeyInputActions when pressed simultaneously

Hy there,



I got a very simple setup, but already odd behavior when using two keys. At least I interpret it like that.



To the code below and its outcome I have the following questions:

  • Why is it such a big difference in speed when using either Commands or KeyTriggers. -> somehow related to the last post…
  • Why does a Command action interrupt a KeyTrigger action ? And why does it work fine the other way around ?
  • Here too, is there something I should know about not mixing these two kind of triggers, or do I just use them wrong ?



    I am using the latest SVN Revision 4483 from http://jmonkeyengine.googlecode.com/svn/trunk/



    Thank you for any answers,

    maxx_981



import com.jme.app.SimpleGame;
import com.jme.input.InputHandler;
import com.jme.input.KeyInput;
import com.jme.input.KeyBindingManager;
import com.jme.input.action.InputActionEvent;
import com.jme.input.action.KeyInputAction;
/*
 * Copyright (c) 2003-2009 jMonkeyEngine
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 * * Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 *
 * * Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the distribution.
 *
 * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
 *   may be used to endorse or promote products derived from this software
 *   without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/**
 * maxx_981, TestInputHandlerTwoButtons
 *


 * Tested on:
 * - Intel Core Duo E8200, 32-bit Vista
 * - Genuine Intel CPU T2500, 32-bit XP
 * -> same behavior
 * <p/>
 * Don't think the graphics setup is of any importance here ...
 * <p/>
 * Strange behavior with just two actions defined.
 * The target of the test is, to have a key with repeating trigger and evt information about triggerPressed,
 * and to have another key, which does not need the triggerPeessed information and is also repeating.
 * <p/>
 * So the setup below is my try to achieve this ;-) which fails terribly ....
 * <p/>
 * If you press button 1 you will notice how slow the updates are, and there are some initial hangers.
 * But it is repeating the action even though it's set to false; -> related to my last post
 * <p/>
 * If you press button 2 additionally, certainly button 1 stops getting updates, also after releasing the button 2 again.
 * <p/>
 * So this scenario outpus:
 * ...
 * Performing Key-Trigger-Action Key1
 * Performing Key-Trigger-Action Key1
 * Performing Comman-Action Key 2
 * Performing Comman-Action Key 2
 * Performing Comman-Action Key 2
 * ...
 * <p/>
 * If you first press button 2 and then button 1, you see a behavior I would call correct, as both are repeating its
 * actions. But the Key-Trigger-Action is so much slower ... this looks like:
 * <p/>
 * ...
 * Performing Comman-Action Key 2
 * Performing Key-Trigger-Action Key1
 * Performing Comman-Action Key 2
 * Performing Comman-Action Key 2
 * Performing Comman-Action Key 2
 * Performing Comman-Action Key 2
 * Performing Comman-Action Key 2
 * Performing Comman-Action Key 2
 * Performing Comman-Action Key 2
 * Performing Key-Trigger-Action Key1
 * Performing Comman-Action Key 2
 * ...
 */
public class TestInputHandlerTwoButtons extends SimpleGame
{
    private boolean triggerPressed = false;

    private InputHandler input1;

    protected void simpleInitGame()
    {
        input1 = new InputHandler();


        // setting up KEY_1
        input1.addAction(new MyKeyInputActionKeyTrigger(), InputHandler.DEVICE_KEYBOARD, KeyInput.KEY_1, InputHandler.AXIS_NONE, false);

        // setting up KEY_2
        {
            KeyBindingManager keyboard = KeyBindingManager.getKeyBindingManager();
            keyboard.set("press2", KeyInput.KEY_2);
            MyKeyInputActionCommand pressS = new MyKeyInputActionCommand();
            input1.addAction(pressS, "press2", true);
        }

    }

    @Override
    protected void simpleUpdate()
    {
        input1.update(tpf);
    }

    public static void main(String[] args)
    {
        TestInputHandlerTwoButtons app = new TestInputHandlerTwoButtons();

        app.setConfigShowMode(ConfigShowMode.AlwaysShow);
        app.start();
    }


    /**
     * A KeyInputAction, evt values should be present
     */
    public class MyKeyInputActionKeyTrigger extends KeyInputAction
    {
        public MyKeyInputActionKeyTrigger()
        {
        }

        public void performAction(InputActionEvent evt)
        {
            triggerPressed = evt.getTriggerPressed();
            System.out.println("Performing Key-Trigger-Action Key1");

        }
    }

    /**
     * A KeyInputAction, no evt values expected
     */
    public class MyKeyInputActionCommand extends KeyInputAction
    {
        public MyKeyInputActionCommand()
        {
        }

        public void performAction(InputActionEvent evt)
        {
            System.out.println("Performing Comman-Action Key 2");
        }
    }

}


Hy there,



I don't know why no one knows an answer for that problem. It seems to me very

basic, as most useful applications will use key-inputs in some way :wink:



But is the problem at least reproduceable for anyone ?



How do you handle these issues in a simple game ? You just make your way with

what it already delivers (ie. don't care about updating speed when using Commands,

not needing event-information when using LWJGL and allowRepeat to true) ?



Thank you for helping …

maxx_981

Not sure I totally understand the problem, or maybe I just don't experience the same trouble, so I'll just say what I see with your test example.


  • Tested on AMD dual core - Asus mobo/Nvidia chipset - bluetooth keyboard - Vista 32bit - JME svn(4490) 12/July/09



    If I press 1, it doesn't repeat (expected behaviour as the example has false for the repeat parameter).

    You get a single action on press (evt.getTriggerPressed() = true) , and a single action on release (evt.getTriggerPressed() = false).

    If I press 2, it repeats rapidly.



    With 1 held, it fires the single pressed event then nothing - holding 2 repeats the second action rapidly - releasing 1 fires the single release action and 2 continues repeating.

    With 1 held, it fires the single pressed event then nothing - holding 2 repeats the second action rapidly - release 2 - release 1 fires the single release action.



    With 2 held, it repeats rapidly.  Pressing 1 fires the single pressed event, 2 continues repeating without pause. Releasing 1 fires the single released event, 2 continues repeating without pause.





    Changed the code to make the 1 event repeat.





    Hold 1, it repeats rapidly. Hold 2, both repeat rapidly interleaved one after the other (sample output below). Release either key - the other continues rapidly. Reversing the process and starting with the other key has exactly the same results.



    Performing Key-Trigger-Action Key1

    Performing Comman-Action Key 2

    Performing Key-Trigger-Action Key1

    Performing Comman-Action Key 2










I see, I forgot to mention that this problem is only existent on JOGL.



Thank you for reproducing.



But in the other Thread (ActionTriggers, strange behavior), Core-Dump mentioned:



>> The jogl implementation still has a few problems, but its being worked on recently by a few people.



So, thats maybe the reaseon then.



On LWJGL the only issue is, that when repeating there is no triggerPressed information available. Otherwise I see the same behavior that you describe, which is (nearly) expected.



If you change the MyKeyInputActionKeyTrigger like below, you'll see that triggerPressed is always true:





Performing Key-Trigger-Action Key1 , triggerPressed: true

Performing Key-Trigger-Action Key1 , triggerPressed: true







To solve the problem for now, I need to restrict to LWJGL and I had to implemented my own

InputHandler, which will repeat actions and give me the triggerPressed value.



To achieve this I have to call the performAction(InputActionEvent evt) of any actions that need

this behavior in the update(float time) method of the InputHandler, and I use allowRepeat = false,

which gives me the triggerPressed information correctly …



Cheers







 /**
     * A KeyInputAction, evt values should be present
     */
    public class MyKeyInputActionKeyTrigger extends KeyInputAction
    {
        public MyKeyInputActionKeyTrigger()
        {
        }

        public void performAction(InputActionEvent evt)
        {
            triggerPressed = evt.getTriggerPressed();
            System.out.println("Performing Key-Trigger-Action Key1 , triggerPressed: "+triggerPressed);

        }
    }

DOH !!