Skip to content

Commit eef69a0

Browse files
authored
Add low-level hook for SDL3 input events (#2867)
* Add low-level hook for SDL3 input events. Resolves #2864 * Apply code review suggestion
1 parent cbfcb8b commit eef69a0

5 files changed

Lines changed: 80 additions & 9 deletions

File tree

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
* Copyright (c) 2009-2026 jMonkeyEngine
3+
* All rights reserved.
4+
*
5+
* Redistribution and use in source and binary forms, with or without
6+
* modification, are permitted provided that the following conditions are
7+
* met:
8+
*
9+
* * Redistributions of source code must retain the above copyright
10+
* notice, this list of conditions and the following disclaimer.
11+
*
12+
* * Redistributions in binary form must reproduce the above copyright
13+
* notice, this list of conditions and the following disclaimer in the
14+
* documentation and/or other materials provided with the distribution.
15+
*
16+
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
17+
* may be used to endorse or promote products derived from this software
18+
* without specific prior written permission.
19+
*
20+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21+
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22+
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23+
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24+
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25+
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26+
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27+
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28+
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29+
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31+
*/
32+
package com.jme3.input.lwjgl;
33+
34+
import com.jme3.system.lwjgl.LwjglWindow;
35+
import org.lwjgl.sdl.SDL_Event;
36+
37+
/**
38+
* Listen to raw SDL events.
39+
*
40+
* @author Ivan1pl
41+
*/
42+
public interface SdlEventListener {
43+
44+
/**
45+
* When registered by {@link LwjglWindow#registerSdlEventListener(SdlEventListener)},
46+
* it gets invoked on each polled SDL event before it is passed to jME inputs.
47+
*
48+
* @param event SDL event to handle
49+
*/
50+
void onSDLEvent(SDL_Event event);
51+
}

jme3-lwjgl3/src/main/java/com/jme3/input/lwjgl/SdlJoystickInput.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
*
2929
* @author Riccardo Balbo
3030
*/
31-
public class SdlJoystickInput implements JoyInput {
31+
public class SdlJoystickInput implements JoyInput, SdlEventListener {
3232

3333
private static final Logger LOGGER = Logger.getLogger(SdlJoystickInput.class.getName());
3434
private final AppSettings settings;
@@ -290,6 +290,7 @@ public boolean onPointerUp(int pointerId, float x, float y, long time) {
290290
return joystick != null && joystick.onPointerUp(pointerId, x, y, time);
291291
}
292292

293+
@Override
293294
public void onSDLEvent(SDL_Event evt) {
294295
int type = evt.type();
295296
if (!(listener instanceof InputManager)) {

jme3-lwjgl3/src/main/java/com/jme3/input/lwjgl/SdlKeyInput.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
/**
5050
* SDL implementation of {@link KeyInput}.
5151
*/
52-
public class SdlKeyInput implements KeyInput {
52+
public class SdlKeyInput implements KeyInput, SdlEventListener {
5353

5454
private static final Logger LOGGER = Logger.getLogger(SdlKeyInput.class.getName());
5555

@@ -80,6 +80,7 @@ public void resetContext() {
8080

8181
}
8282

83+
@Override
8384
public void onSDLEvent(SDL_Event event) {
8485
final int type = event.type();
8586
if (type == SDL_EVENT_KEY_DOWN || type == SDL_EVENT_KEY_UP) {

jme3-lwjgl3/src/main/java/com/jme3/input/lwjgl/SdlMouseInput.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@
6565
/**
6666
* SDL implementation of {@link MouseInput}.
6767
*/
68-
public class SdlMouseInput implements MouseInput {
68+
public class SdlMouseInput implements MouseInput, SdlEventListener {
6969

7070
private static final Logger LOGGER = Logger.getLogger(SdlMouseInput.class.getName());
7171
private static final int WHEEL_SCALE = 120;
@@ -127,6 +127,7 @@ public void resetContext() {
127127
setCursorVisible(cursorVisible);
128128
}
129129

130+
@Override
130131
public void onSDLEvent(SDL_Event event) {
131132
final int type = event.type();
132133

jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglWindow.java

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import com.jme3.input.KeyInput;
3838
import com.jme3.input.MouseInput;
3939
import com.jme3.input.TouchInput;
40+
import com.jme3.input.lwjgl.SdlEventListener;
4041
import com.jme3.input.lwjgl.SdlJoystickInput;
4142
import com.jme3.input.lwjgl.SdlKeyInput;
4243
import com.jme3.input.lwjgl.SdlMouseInput;
@@ -204,6 +205,7 @@ public abstract class LwjglWindow extends LwjglContext implements Runnable {
204205

205206
private final JmeContext.Type type;
206207
private final SafeArrayList<WindowSizeListener> windowSizeListeners = new SafeArrayList<>(WindowSizeListener.class);
208+
private final SafeArrayList<SdlEventListener> sdlEventListeners = new SafeArrayList<>(SdlEventListener.class);
207209
private final AtomicBoolean windowCloseRequested = new AtomicBoolean(false);
208210

209211
private Thread mainThread;
@@ -255,6 +257,14 @@ public void removeWindowSizeListener(WindowSizeListener listener) {
255257
windowSizeListeners.remove(listener);
256258
}
257259

260+
public void registerSdlEventListener(SdlEventListener listener) {
261+
sdlEventListeners.add(listener);
262+
}
263+
264+
public void removeSdlEventListener(SdlEventListener listener) {
265+
sdlEventListeners.remove(listener);
266+
}
267+
258268
private static void disableNvidiaThreadedOptimizations() {
259269
if (SDL_setenv_unsafe("__GL_THREADED_OPTIMIZATIONS", "0", 1) != 0) {
260270
throw new IllegalStateException("Unable to disable NVIDIA OpenGL threaded optimizations: "
@@ -1111,14 +1121,21 @@ private void handleWindowEvent(SDL_Event event) {
11111121
}
11121122

11131123
private void dispatchSDLEvent(SDL_Event event) {
1114-
if (keyInput instanceof SdlKeyInput) {
1115-
((SdlKeyInput) keyInput).onSDLEvent(event);
1124+
for (SdlEventListener listener : sdlEventListeners.getArray()) {
1125+
try {
1126+
listener.onSDLEvent(event);
1127+
} catch (Exception e) {
1128+
LOGGER.log(Level.SEVERE, "Error handling SDL event", e);
1129+
}
1130+
}
1131+
if (keyInput instanceof SdlEventListener) {
1132+
((SdlEventListener) keyInput).onSDLEvent(event);
11161133
}
1117-
if (mouseInput instanceof SdlMouseInput) {
1118-
((SdlMouseInput) mouseInput).onSDLEvent(event);
1134+
if (mouseInput instanceof SdlEventListener) {
1135+
((SdlEventListener) mouseInput).onSDLEvent(event);
11191136
}
1120-
if (joyInput instanceof SdlJoystickInput) {
1121-
((SdlJoystickInput) joyInput).onSDLEvent(event);
1137+
if (joyInput instanceof SdlEventListener) {
1138+
((SdlEventListener) joyInput).onSDLEvent(event);
11221139
}
11231140
}
11241141

0 commit comments

Comments
 (0)