Is there any way on jME to detect when a gamepad is disconnected so we can take an action like pausing the game or something?
As an exercise I tried the following simple code using both LWJGL 2 and 3, starting with a gamepad connected to my computer and suddenly disconnecting it. The behavior was different with each version of LWJGL. On version 2 the logger repeatedly shows an info that won’t stop when the controller is re-connected. On version 3, it fails miserably with a NullPointerException.
What should I do? Is there some sort of listener or something that I can use? I don’t think I should catch NullPointerException because it could be anything, not only gamepad disconnection. Besides it would work only on LWJGL 3.
If there is nothing available, don’t you guys think we should create a JoystickDisconnectedException or something in jME? Or maybe something like a listener to detect disconnection/re-connection of gamepads?
Code:
import com.jme3.app.SimpleApplication;
import com.jme3.system.AppSettings;
public class Main extends SimpleApplication {
public static void main(String... args) {
AppSettings settings = new AppSettings(true);
settings.setUseJoysticks(true);
Main app = new Main();
app.setSettings(settings);
app.start();
}
@Override
public void simpleInitApp() {
}
}
Result when joystick is disconnected (LWJGL 2):
May 09, 2019 4:41:03 PM net.java.games.input.ControllerEnvironment log
INFO: Failed to poll device: Failed to get device key states (19)
May 09, 2019 4:41:03 PM net.java.games.input.ControllerEnvironment log
INFO: Failed to poll device: Failed to get device key states (19)
May 09, 2019 4:41:03 PM net.java.games.input.ControllerEnvironment log
INFO: Failed to poll device: Failed to get device key states (19)
Result when joystick is disconnected (LWJGL 3):
May 09, 2019 4:42:46 PM com.jme3.app.LegacyApplication handleError
SEVERE: Uncaught exception thrown in Thread[main,5,main]
java.lang.NullPointerException
at com.jme3.input.lwjgl.GlfwJoystickInput.update(GlfwJoystickInput.java:133)
at com.jme3.input.InputManager.update(InputManager.java:906)
at com.jme3.app.LegacyApplication.update(LegacyApplication.java:724)
at com.jme3.app.SimpleApplication.update(SimpleApplication.java:244)
at com.jme3.system.lwjgl.LwjglWindow.runLoop(LwjglWindow.java:499)
at com.jme3.system.lwjgl.LwjglWindow.run(LwjglWindow.java:581)
at com.jme3.system.lwjgl.LwjglWindow.create(LwjglWindow.java:423)
at com.jme3.app.LegacyApplication.start(LegacyApplication.java:463)
at com.jme3.app.LegacyApplication.start(LegacyApplication.java:424)
at com.jme3.app.SimpleApplication.start(SimpleApplication.java:125)
at Main.main(Main.java:14)
This is pretty ugly, but aside from this everything works. I’m not sure how I can get around this because many contexts use the same interface, and the only context I want is the LWJGL3 one
Ok. I think I’m done here. I’ve moved the callback to the inputManager. The event is only fired from the LWJGL3 context, so adding a listener using any other context just wont fire any event to the listeners. It will be up to the other contexts to fire the event if/when they get support.