Merge pull request #1087 from jayfella/master
Add support for listening to joystick connection/disconnection.
This commit is contained in:
commit
33ade6b874
@ -42,6 +42,7 @@ import com.jme3.util.IntMap.Entry;
|
|||||||
import com.jme3.util.SafeArrayList;
|
import com.jme3.util.SafeArrayList;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
@ -106,6 +107,7 @@ public class InputManager implements RawInputListener {
|
|||||||
private final IntMap<Float> axisValues = new IntMap<Float>();
|
private final IntMap<Float> axisValues = new IntMap<Float>();
|
||||||
private final SafeArrayList<RawInputListener> rawListeners = new SafeArrayList<RawInputListener>(RawInputListener.class);
|
private final SafeArrayList<RawInputListener> rawListeners = new SafeArrayList<RawInputListener>(RawInputListener.class);
|
||||||
private final ArrayList<InputEvent> inputQueue = new ArrayList<InputEvent>();
|
private final ArrayList<InputEvent> inputQueue = new ArrayList<InputEvent>();
|
||||||
|
private final List<JoystickConnectionListener> joystickConnectionListeners = new ArrayList<>();
|
||||||
|
|
||||||
private static class Mapping {
|
private static class Mapping {
|
||||||
|
|
||||||
@ -953,4 +955,62 @@ public class InputManager implements RawInputListener {
|
|||||||
cursorPos.set(evt.getX(), evt.getY());
|
cursorPos.set(evt.getX(), evt.getY());
|
||||||
inputQueue.add(evt);
|
inputQueue.add(evt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Re-sets the joystick list when a joystick is added or removed.
|
||||||
|
* This should only be called internally.
|
||||||
|
*
|
||||||
|
* @param joysticks
|
||||||
|
*/
|
||||||
|
public void setJoysticks(Joystick[] joysticks) {
|
||||||
|
this.joysticks = joysticks;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a listener that reports when a joystick has been added or removed.
|
||||||
|
* Currently only implemented in LWJGL3
|
||||||
|
* @param listener the listner.
|
||||||
|
*/
|
||||||
|
public boolean addJoystickConnectionListener(JoystickConnectionListener listener) {
|
||||||
|
return joystickConnectionListeners.add(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove an existing listener.
|
||||||
|
* @param listener the listener to remove.
|
||||||
|
* @return true if this listener was removed, or false if it was not found.
|
||||||
|
*/
|
||||||
|
public boolean removeJoystickConnectionListener(JoystickConnectionListener listener) {
|
||||||
|
return joystickConnectionListeners.remove(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove all joystick connection listeners.
|
||||||
|
*/
|
||||||
|
public void clearJoystickConnectionListeners() {
|
||||||
|
joystickConnectionListeners.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when a joystick has been connected.
|
||||||
|
* This should only be called internally.
|
||||||
|
* @param joystick the joystick that has been connected.
|
||||||
|
*/
|
||||||
|
public void fireJoystickConnectedEvent(Joystick joystick) {
|
||||||
|
for (JoystickConnectionListener listener : joystickConnectionListeners) {
|
||||||
|
listener.onConnected(joystick);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when a joystick has been disconnected.
|
||||||
|
* This should only be called internally.
|
||||||
|
* @param joystick the joystick that has been disconnected.
|
||||||
|
*/
|
||||||
|
public void fireJoystickDisconnectedEvent(Joystick joystick) {
|
||||||
|
for (JoystickConnectionListener listener : joystickConnectionListeners) {
|
||||||
|
listener.onDisconnected(joystick);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,21 @@
|
|||||||
|
package com.jme3.input;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listens for the state of a joystick connection.
|
||||||
|
* @author jayfella
|
||||||
|
*/
|
||||||
|
public interface JoystickConnectionListener {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Occurs when a new joystick has been detected.
|
||||||
|
* @param joystick the joystick that has been detected.
|
||||||
|
*/
|
||||||
|
void onConnected(Joystick joystick);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Occurs when an existing joystick has been disconnected.
|
||||||
|
* @param joystick the joystick that has been disconnected.
|
||||||
|
*/
|
||||||
|
void onDisconnected(Joystick joystick);
|
||||||
|
|
||||||
|
}
|
@ -49,7 +49,7 @@ import static org.lwjgl.glfw.GLFW.*;
|
|||||||
*/
|
*/
|
||||||
public class GlfwJoystickInput implements JoyInput {
|
public class GlfwJoystickInput implements JoyInput {
|
||||||
|
|
||||||
private static final Logger LOGGER = Logger.getLogger(InputManager.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(GlfwJoystickInput.class.getName());
|
||||||
|
|
||||||
private RawInputListener listener;
|
private RawInputListener listener;
|
||||||
|
|
||||||
@ -66,8 +66,28 @@ public class GlfwJoystickInput implements JoyInput {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void fireJoystickConnectedEvent(int jid) {
|
||||||
|
Joystick joystick = joysticks.get(jid);
|
||||||
|
((InputManager)listener).fireJoystickConnectedEvent(joystick);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void fireJoystickDisconnectedEvent(int jid) {
|
||||||
|
Joystick joystick = joysticks.get(jid);
|
||||||
|
((InputManager)listener).fireJoystickDisconnectedEvent(joystick);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reloadJoysticks() {
|
||||||
|
joysticks.clear();
|
||||||
|
|
||||||
|
InputManager inputManager = (InputManager) listener;
|
||||||
|
|
||||||
|
Joystick[] joysticks = loadJoysticks(inputManager);
|
||||||
|
inputManager.setJoysticks(joysticks);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Joystick[] loadJoysticks(final InputManager inputManager) {
|
public Joystick[] loadJoysticks(final InputManager inputManager) {
|
||||||
|
|
||||||
for (int i = 0; i < GLFW_JOYSTICK_LAST; i++) {
|
for (int i = 0; i < GLFW_JOYSTICK_LAST; i++) {
|
||||||
if (glfwJoystickPresent(i)) {
|
if (glfwJoystickPresent(i)) {
|
||||||
final String name = glfwGetJoystickName(i);
|
final String name = glfwGetJoystickName(i);
|
||||||
@ -126,17 +146,26 @@ public class GlfwJoystickInput implements JoyInput {
|
|||||||
@Override
|
@Override
|
||||||
public void update() {
|
public void update() {
|
||||||
for (final Map.Entry<Integer, GlfwJoystick> entry : joysticks.entrySet()) {
|
for (final Map.Entry<Integer, GlfwJoystick> entry : joysticks.entrySet()) {
|
||||||
|
|
||||||
// Axes
|
// Axes
|
||||||
final FloatBuffer axisValues = glfwGetJoystickAxes(entry.getKey());
|
final FloatBuffer axisValues = glfwGetJoystickAxes(entry.getKey());
|
||||||
|
|
||||||
|
// if a joystick is added or removed, the callback reloads the joysticks.
|
||||||
|
// when the callback is called and reloads the joystick, this iterator may already have started iterating.
|
||||||
|
// To avoid a NullPointerException we null-check the axisValues and bytebuffer objects.
|
||||||
|
// If the joystick it's iterating over no-longer exists it will return null.
|
||||||
|
|
||||||
|
if (axisValues != null) {
|
||||||
for (final JoystickAxis axis : entry.getValue().getAxes()) {
|
for (final JoystickAxis axis : entry.getValue().getAxes()) {
|
||||||
final float value = axisValues.get(axis.getAxisId());
|
final float value = axisValues.get(axis.getAxisId());
|
||||||
listener.onJoyAxisEvent(new JoyAxisEvent(axis, value));
|
listener.onJoyAxisEvent(new JoyAxisEvent(axis, value));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Buttons
|
// Buttons
|
||||||
final ByteBuffer byteBuffer = glfwGetJoystickButtons(entry.getKey());
|
final ByteBuffer byteBuffer = glfwGetJoystickButtons(entry.getKey());
|
||||||
|
|
||||||
|
if (byteBuffer != null) {
|
||||||
for (final JoystickButton button : entry.getValue().getButtons()) {
|
for (final JoystickButton button : entry.getValue().getButtons()) {
|
||||||
final boolean pressed = byteBuffer.get(button.getButtonId()) == GLFW_PRESS;
|
final boolean pressed = byteBuffer.get(button.getButtonId()) == GLFW_PRESS;
|
||||||
|
|
||||||
@ -147,6 +176,7 @@ public class GlfwJoystickInput implements JoyInput {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void destroy() {
|
public void destroy() {
|
||||||
|
@ -37,6 +37,7 @@ import static java.util.stream.Collectors.toSet;
|
|||||||
import static org.lwjgl.opencl.CL10.CL_CONTEXT_PLATFORM;
|
import static org.lwjgl.opencl.CL10.CL_CONTEXT_PLATFORM;
|
||||||
import static org.lwjgl.opengl.GL.createCapabilities;
|
import static org.lwjgl.opengl.GL.createCapabilities;
|
||||||
import static org.lwjgl.opengl.GL11.glGetInteger;
|
import static org.lwjgl.opengl.GL11.glGetInteger;
|
||||||
|
|
||||||
import com.jme3.input.lwjgl.GlfwJoystickInput;
|
import com.jme3.input.lwjgl.GlfwJoystickInput;
|
||||||
import com.jme3.input.lwjgl.GlfwKeyInput;
|
import com.jme3.input.lwjgl.GlfwKeyInput;
|
||||||
import com.jme3.input.lwjgl.GlfwMouseInput;
|
import com.jme3.input.lwjgl.GlfwMouseInput;
|
||||||
@ -65,6 +66,7 @@ import com.jme3.util.LWJGLBufferAllocator.ConcurrentLWJGLBufferAllocator;
|
|||||||
import org.lwjgl.PointerBuffer;
|
import org.lwjgl.PointerBuffer;
|
||||||
import org.lwjgl.Version;
|
import org.lwjgl.Version;
|
||||||
import org.lwjgl.glfw.GLFW;
|
import org.lwjgl.glfw.GLFW;
|
||||||
|
import org.lwjgl.glfw.GLFWJoystickCallback;
|
||||||
import org.lwjgl.opencl.APPLEGLSharing;
|
import org.lwjgl.opencl.APPLEGLSharing;
|
||||||
import org.lwjgl.opencl.CL10;
|
import org.lwjgl.opencl.CL10;
|
||||||
import org.lwjgl.opencl.KHRGLSharing;
|
import org.lwjgl.opencl.KHRGLSharing;
|
||||||
@ -233,6 +235,24 @@ public abstract class LwjglContext implements JmeContext {
|
|||||||
joyInput.initialize();
|
joyInput.initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GLFW.glfwSetJoystickCallback(new GLFWJoystickCallback() {
|
||||||
|
@Override
|
||||||
|
public void invoke(int jid, int event) {
|
||||||
|
|
||||||
|
// Invoke the disconnected event before we reload the joysticks or we lose the reference to it.
|
||||||
|
// Invoke the connected event after we reload the joysticks to obtain the reference to it.
|
||||||
|
|
||||||
|
if ( event == GLFW.GLFW_CONNECTED ) {
|
||||||
|
joyInput.reloadJoysticks();
|
||||||
|
joyInput.fireJoystickConnectedEvent(jid);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
joyInput.fireJoystickDisconnectedEvent(jid);
|
||||||
|
joyInput.reloadJoysticks();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
renderable.set(true);
|
renderable.set(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user