InputHandler conflict

Hello people,



I’ve built a small proof-of-concept simulation with jME and I’m having a bit of trouble with the input system.



I’ve been following the tutorial InputSystem and InputHandler guide  at http://www.jmonkeyengine.com/wiki/doku.php?id=inputsystem_and_inputhandler_guide.



What I’m trying to achieve is a game state oriented inputsystem. This is, separate input handling for each state (console, spectator, airplane, tank…). I already have different game states (currently GameStateNodes) arranged in a tree, and I would like to associate gamesates and inputhandlers so that I can activate each game state and get the input system to act acordly.



I’m doing the following:



   /**
    * Switchs the console (on/off)
    */
   public void switchConsole() {
      
      logger.info("Opening/closing console");
      
      if (consoleState.isActive()) {
         // Deactivate console
         input.getConsoleInputHandler().setEnabled(false);
         input.getSpectatorInputHandler().getKeyboardLookHandler().setEnabled(true)
         consoleState.setActive(false);
      } else {
         // Activate console
         input.getConsoleInputHandler().setEnabled(true);
         input.getSpectatorInputHandler().getKeyboardLookHandler().setEnabled(false);
         consoleState.setActive(true);
      }
      
   }



The problem is that the KeyboardLookHandler contained in my SpectatorInputHandler is correctly disabled with the call to .setEnabled(false). However, when I disable my self-made ConsoleInputHandler it still processes the input events.

The ConsoleInputHandler is really simple but I guess that the problem comes from the way I've implemented the whole thing:


/**
 * The ConsoleInputHandler handles console keys.
 */
public class ConsoleInputHandler extends InputHandler {

   private final static Logger logger = Logger.getLogger(ConsoleInputHandler.class.toString());
   
   /**
    * Console key action code
    */
   public class ConsoleKeyAction extends InputAction {
   
      public void performAction(InputActionEvent evt) {

// THIS IS WHAT I'M USING TO WORKAROUND THE PROBLEM:
if (!System.getMainState().getClientState().getConsoleState().isActive()) return;

         logger.fine("Key pressed in console mode: triggerIndex=" + evt.getTriggerIndex());
         if (evt.getTriggerPressed() == true) {
            System.getConsole().processKey(evt.getTriggerCharacter());            
         }
      }

   }

   /**
    * Constructor
    */
   public ConsoleInputHandler() {

      addAction(new ConsoleKeyAction(), InputHandler.DEVICE_KEYBOARD, InputHandler.BUTTON_ALL, InputHandler.AXIS_ALL, false);

   }

}



I've tried debugging inside jME input system (InputHandler, FirstPersonHandler (which is already a composition handler), KeyboardLookHandler...) but I think that maybe I'm misunderstanding the input system.

To avoid ConsoleInputHandler processing all keypresses I'm checking if console is activated by hand, but I think that disabling the InputHandler should work.

Thank you for your suggestions,

J



I would not recommend to subclass InputHandler but that's not the problem here.



If you disable an InputHandler and have your action only registered with that single InputHandler it should not be invoked any more. Double check that your InputHandler is really disabled when you receive the action event (put a breakpoint there and check the field). If it's still getting called this a probably a bug.



As the disabling of InputHandlers seems functional here, please post a short app to reproduce the problem.

Good advice, interesting result:



The InputHandler is activated when the action is called. But, really annoying, the action is not called until I activate the console, and when activated all the past keypresses are processed. It seems like the key presses (triggers?) are being buffered somewhere.



The KeyboardLookHandler does not suffer from this problem, though it works in a different way (seems like it binds single keys, not all).



Should I "flush" the triggers somehow when entering console mode and thus activating my ConsoleInputHandler?



Thanks again.

hmm, I thought I fixed that a while ago… do you use nightly/cvs version?


I'm developing upon the CVS version of jME. I updated yesterday.

The behaviour is strange: I'm quite sure that when my InputHandler (the one my action is added to) is disabled, it buffers and receives all keypresses when re-enabled.

Where should I look for buffered triggers? I can debug it and check if they are being stored somewhere.

On the other hand, I'm thinking on using one InputHandler for all devices and manage the bindings on my own, which would also avoid the problem. Would this fit correctly with jME architecture?


Really thought I fixed that but the problem still existed :expressionless:



Fixed in CVS now.

Thanks!



I was curious so I reviewed the change. I see in the cvs the added line to SyntheticTrigger and

in KeyboardInputHandlerDevice, but in the other hand it doesn't seem to be a similar one in JoystickInputHandlerDevice.





if ( !inputHandler.isEnabled() ) return;



Is there a document on the Input System architecture? I couldn't find one, and think it would be very useful or people will end up routing the input events theirselves :(.


jjmontes said:
but in the other hand it doesn't seem to be a similar one in JoystickInputHandlerDevice.

It is not necessary there because joystick triggers don't queue multiple events per trigger.


Is there a document on the Input System architecture? I couldn't find one, and think it would be very useful or people will end up routing the input events theirselves :(.

No there is no such document :(. I know it would be very good to have it, but I don't have the time to write it.