From 5cb9e9fb75f6d6ee140c4a15bcaef470847be225 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Przemys=C5=82aw=20Pluta?= Date: Sat, 13 Mar 2021 10:39:27 +0100 Subject: [PATCH] Remove InputManager --- .../base/api/game/context/Context.java | 3 + .../base/api/game/input/Input.java | 6 + .../base/api/game/input/InputEvent.java | 7 + .../base/api/game/input/KeyAction.java | 7 + .../base/api/game/input/KeyEvent.java | 7 + .../base/api/game/screen/Screen.java | 6 +- .../engine/context/model/DefaultContext.java | 6 + .../engine/core/engine/DefaultGameEngine.java | 7 +- .../base/engine/logic/DefaultGameLogic.java | 19 +- .../base/engine/logic/GameLogic.java | 3 +- .../base/engine/ui/event/GLFWKeyEvent.java | 291 ++++++++++++++++++ .../base/engine/ui/manager/InputManager.java | 36 --- .../base/engine/ui/manager/ScreenManager.java | 5 +- .../base/engine/ui/model/GLFWInput.java | 52 +++- .../base/engine/ui/model/GLFWScreen.java | 140 +-------- 15 files changed, 403 insertions(+), 192 deletions(-) create mode 100644 api/src/main/java/com/bartlomiejpluta/base/api/game/input/InputEvent.java create mode 100644 api/src/main/java/com/bartlomiejpluta/base/api/game/input/KeyAction.java create mode 100644 api/src/main/java/com/bartlomiejpluta/base/api/game/input/KeyEvent.java create mode 100644 engine/src/main/java/com/bartlomiejpluta/base/engine/ui/event/GLFWKeyEvent.java delete mode 100644 engine/src/main/java/com/bartlomiejpluta/base/engine/ui/manager/InputManager.java diff --git a/api/src/main/java/com/bartlomiejpluta/base/api/game/context/Context.java b/api/src/main/java/com/bartlomiejpluta/base/api/game/context/Context.java index 1d448db2..36c15375 100644 --- a/api/src/main/java/com/bartlomiejpluta/base/api/game/context/Context.java +++ b/api/src/main/java/com/bartlomiejpluta/base/api/game/context/Context.java @@ -5,6 +5,7 @@ import com.bartlomiejpluta.base.api.game.entity.Entity; import com.bartlomiejpluta.base.api.game.gui.base.GUI; import com.bartlomiejpluta.base.api.game.image.Image; import com.bartlomiejpluta.base.api.game.input.Input; +import com.bartlomiejpluta.base.api.game.input.KeyEvent; import com.bartlomiejpluta.base.api.game.runner.GameRunner; import com.bartlomiejpluta.base.api.game.screen.Screen; import com.bartlomiejpluta.base.api.internal.gc.Disposable; @@ -45,4 +46,6 @@ public interface Context extends Updatable, Renderable, Disposable { void init(Screen screen, Input input, Camera camera); void input(Input input); + + void handleKeyEvent(KeyEvent event); } diff --git a/api/src/main/java/com/bartlomiejpluta/base/api/game/input/Input.java b/api/src/main/java/com/bartlomiejpluta/base/api/game/input/Input.java index 2059cbd8..192729dd 100644 --- a/api/src/main/java/com/bartlomiejpluta/base/api/game/input/Input.java +++ b/api/src/main/java/com/bartlomiejpluta/base/api/game/input/Input.java @@ -1,5 +1,11 @@ package com.bartlomiejpluta.base.api.game.input; +import java.util.function.Consumer; + public interface Input { boolean isKeyPressed(Key key); + + void addKeyEventHandler(Consumer handler); + + void removeKeyEventHandler(Consumer handler); } diff --git a/api/src/main/java/com/bartlomiejpluta/base/api/game/input/InputEvent.java b/api/src/main/java/com/bartlomiejpluta/base/api/game/input/InputEvent.java new file mode 100644 index 00000000..5d9c7e49 --- /dev/null +++ b/api/src/main/java/com/bartlomiejpluta/base/api/game/input/InputEvent.java @@ -0,0 +1,7 @@ +package com.bartlomiejpluta.base.api.game.input; + +public interface InputEvent { + boolean isConsumed(); + + void consume(); +} diff --git a/api/src/main/java/com/bartlomiejpluta/base/api/game/input/KeyAction.java b/api/src/main/java/com/bartlomiejpluta/base/api/game/input/KeyAction.java new file mode 100644 index 00000000..7a2e816c --- /dev/null +++ b/api/src/main/java/com/bartlomiejpluta/base/api/game/input/KeyAction.java @@ -0,0 +1,7 @@ +package com.bartlomiejpluta.base.api.game.input; + +public enum KeyAction { + PRESS, + RELEASE, + REPEAT +} diff --git a/api/src/main/java/com/bartlomiejpluta/base/api/game/input/KeyEvent.java b/api/src/main/java/com/bartlomiejpluta/base/api/game/input/KeyEvent.java new file mode 100644 index 00000000..2378dc81 --- /dev/null +++ b/api/src/main/java/com/bartlomiejpluta/base/api/game/input/KeyEvent.java @@ -0,0 +1,7 @@ +package com.bartlomiejpluta.base.api.game.input; + +public interface KeyEvent extends InputEvent { + Key getKey(); + + KeyAction getAction(); +} diff --git a/api/src/main/java/com/bartlomiejpluta/base/api/game/screen/Screen.java b/api/src/main/java/com/bartlomiejpluta/base/api/game/screen/Screen.java index 4c9b1b6e..710fb2fb 100644 --- a/api/src/main/java/com/bartlomiejpluta/base/api/game/screen/Screen.java +++ b/api/src/main/java/com/bartlomiejpluta/base/api/game/screen/Screen.java @@ -3,8 +3,6 @@ package com.bartlomiejpluta.base.api.game.screen; import org.joml.Vector2fc; public interface Screen { - void init(); - int getWidth(); int getHeight(); @@ -22,4 +20,8 @@ public interface Screen { void clear(float r, float g, float b, float alpha); void restoreState(); + + void init(); + + long getID(); } diff --git a/engine/src/main/java/com/bartlomiejpluta/base/engine/context/model/DefaultContext.java b/engine/src/main/java/com/bartlomiejpluta/base/engine/context/model/DefaultContext.java index e9847d8d..4b856ce5 100644 --- a/engine/src/main/java/com/bartlomiejpluta/base/engine/context/model/DefaultContext.java +++ b/engine/src/main/java/com/bartlomiejpluta/base/engine/context/model/DefaultContext.java @@ -6,6 +6,7 @@ import com.bartlomiejpluta.base.api.game.entity.Entity; import com.bartlomiejpluta.base.api.game.gui.base.GUI; import com.bartlomiejpluta.base.api.game.image.Image; import com.bartlomiejpluta.base.api.game.input.Input; +import com.bartlomiejpluta.base.api.game.input.KeyEvent; import com.bartlomiejpluta.base.api.game.map.handler.MapHandler; import com.bartlomiejpluta.base.api.game.runner.GameRunner; import com.bartlomiejpluta.base.api.game.screen.Screen; @@ -136,6 +137,11 @@ public class DefaultContext implements Context { return engine.togglePaused(); } + @Override + public void handleKeyEvent(KeyEvent event) { + // TODO + } + @Override public void input(Input input) { gameRunner.input(input); diff --git a/engine/src/main/java/com/bartlomiejpluta/base/engine/core/engine/DefaultGameEngine.java b/engine/src/main/java/com/bartlomiejpluta/base/engine/core/engine/DefaultGameEngine.java index 1e314a86..a08418ff 100644 --- a/engine/src/main/java/com/bartlomiejpluta/base/engine/core/engine/DefaultGameEngine.java +++ b/engine/src/main/java/com/bartlomiejpluta/base/engine/core/engine/DefaultGameEngine.java @@ -1,13 +1,11 @@ package com.bartlomiejpluta.base.engine.core.engine; import com.bartlomiejpluta.base.api.game.context.Context; -import com.bartlomiejpluta.base.api.game.input.Input; import com.bartlomiejpluta.base.api.game.screen.Screen; import com.bartlomiejpluta.base.engine.gc.OffHeapGarbageCollector; import com.bartlomiejpluta.base.engine.logic.GameLogic; import com.bartlomiejpluta.base.engine.thread.ThreadManager; import com.bartlomiejpluta.base.engine.time.ChronoMeter; -import com.bartlomiejpluta.base.engine.ui.manager.InputManager; import com.bartlomiejpluta.base.engine.ui.manager.ScreenManager; import lombok.Getter; import lombok.RequiredArgsConstructor; @@ -22,7 +20,6 @@ public class DefaultGameEngine implements GameEngine { private static final String THREAD_NAME = "engine"; private final ScreenManager screenManager; - private final InputManager inputManager; private final ThreadManager threadManager; private final GameLogic logic; private final OffHeapGarbageCollector garbageCollector; @@ -31,7 +28,6 @@ public class DefaultGameEngine implements GameEngine { private Thread thread; private Screen screen; - private Input input; private int targetUps; private Context context; @@ -85,7 +81,7 @@ public class DefaultGameEngine implements GameEngine { } private void input() { - logic.input(input); + logic.input(); } private void update(float dt) { @@ -111,7 +107,6 @@ public class DefaultGameEngine implements GameEngine { this.screen = screenManager.createScreen(context.getProjectName(), WINDOW_WIDTH, WINDOW_HEIGHT); this.thread = threadManager.createThread(THREAD_NAME, this::run); - this.input = inputManager.getInput(); this.targetUps = TARGET_UPS; diff --git a/engine/src/main/java/com/bartlomiejpluta/base/engine/logic/DefaultGameLogic.java b/engine/src/main/java/com/bartlomiejpluta/base/engine/logic/DefaultGameLogic.java index 4ad86d5c..20445278 100644 --- a/engine/src/main/java/com/bartlomiejpluta/base/engine/logic/DefaultGameLogic.java +++ b/engine/src/main/java/com/bartlomiejpluta/base/engine/logic/DefaultGameLogic.java @@ -5,7 +5,7 @@ import com.bartlomiejpluta.base.api.game.context.Context; import com.bartlomiejpluta.base.api.game.input.Input; import com.bartlomiejpluta.base.api.game.screen.Screen; import com.bartlomiejpluta.base.engine.core.gl.render.Renderer; -import com.bartlomiejpluta.base.engine.ui.manager.InputManager; +import com.bartlomiejpluta.base.engine.ui.model.GLFWInput; import com.bartlomiejpluta.base.engine.world.camera.DefaultCamera; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -17,8 +17,8 @@ import org.springframework.stereotype.Component; @RequiredArgsConstructor(onConstructor = @__(@Autowired)) public class DefaultGameLogic implements GameLogic { private final Renderer renderer; - private final InputManager inputManager; - private final Camera camera = new DefaultCamera(); + private Camera camera; + private Input input; private Context context; @@ -29,12 +29,21 @@ public class DefaultGameLogic implements GameLogic { log.info("Initializing game logic"); renderer.init(); + log.info("Creating camera model"); + camera = new DefaultCamera(); + + log.info("Initializing input model"); + var input = new GLFWInput(screen); + input.init(context); + log.info("Initializing game context"); - context.init(screen, inputManager.getInput(), camera); + context.init(screen, input, camera); + + this.input = input; } @Override - public void input(Input input) { + public void input() { context.input(input); } diff --git a/engine/src/main/java/com/bartlomiejpluta/base/engine/logic/GameLogic.java b/engine/src/main/java/com/bartlomiejpluta/base/engine/logic/GameLogic.java index 6d3cd957..00173671 100644 --- a/engine/src/main/java/com/bartlomiejpluta/base/engine/logic/GameLogic.java +++ b/engine/src/main/java/com/bartlomiejpluta/base/engine/logic/GameLogic.java @@ -1,14 +1,13 @@ package com.bartlomiejpluta.base.engine.logic; import com.bartlomiejpluta.base.api.game.context.Context; -import com.bartlomiejpluta.base.api.game.input.Input; import com.bartlomiejpluta.base.api.game.screen.Screen; import com.bartlomiejpluta.base.api.internal.gc.Cleanable; public interface GameLogic extends Cleanable { void init(Screen screen, Context context); - void input(Input input); + void input(); void update(float dt); diff --git a/engine/src/main/java/com/bartlomiejpluta/base/engine/ui/event/GLFWKeyEvent.java b/engine/src/main/java/com/bartlomiejpluta/base/engine/ui/event/GLFWKeyEvent.java new file mode 100644 index 00000000..daaed8c6 --- /dev/null +++ b/engine/src/main/java/com/bartlomiejpluta/base/engine/ui/event/GLFWKeyEvent.java @@ -0,0 +1,291 @@ +package com.bartlomiejpluta.base.engine.ui.event; + +import com.bartlomiejpluta.base.api.game.input.Key; +import com.bartlomiejpluta.base.api.game.input.KeyAction; +import com.bartlomiejpluta.base.api.game.input.KeyEvent; +import com.bartlomiejpluta.base.engine.error.AppException; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import lombok.ToString; + +import static org.lwjgl.glfw.GLFW.*; + +@Getter +@ToString +@EqualsAndHashCode +@RequiredArgsConstructor +public class GLFWKeyEvent implements KeyEvent { + private final Key key; + private final KeyAction action; + private boolean consumed; + + @Override + public void consume() { + consumed = true; + } + + public static KeyEvent of(int key, int action) { + return new GLFWKeyEvent(parseKey(key), parseAction(action)); + } + + public static int glfwCode(Key key) { + return switch (key) { + case KEY_SPACE -> GLFW_KEY_SPACE; + case KEY_APOSTROPHE -> GLFW_KEY_APOSTROPHE; + case KEY_COMMA -> GLFW_KEY_COMMA; + case KEY_MINUS -> GLFW_KEY_MINUS; + case KEY_PERIOD -> GLFW_KEY_PERIOD; + case KEY_SLASH -> GLFW_KEY_SLASH; + case KEY_0 -> GLFW_KEY_0; + case KEY_1 -> GLFW_KEY_1; + case KEY_2 -> GLFW_KEY_2; + case KEY_3 -> GLFW_KEY_3; + case KEY_4 -> GLFW_KEY_4; + case KEY_5 -> GLFW_KEY_5; + case KEY_6 -> GLFW_KEY_6; + case KEY_7 -> GLFW_KEY_7; + case KEY_8 -> GLFW_KEY_8; + case KEY_9 -> GLFW_KEY_9; + case KEY_SEMICOLON -> GLFW_KEY_SEMICOLON; + case KEY_EQUAL -> GLFW_KEY_EQUAL; + case KEY_A -> GLFW_KEY_A; + case KEY_B -> GLFW_KEY_B; + case KEY_C -> GLFW_KEY_C; + case KEY_D -> GLFW_KEY_D; + case KEY_E -> GLFW_KEY_E; + case KEY_F -> GLFW_KEY_F; + case KEY_G -> GLFW_KEY_G; + case KEY_H -> GLFW_KEY_H; + case KEY_I -> GLFW_KEY_I; + case KEY_J -> GLFW_KEY_J; + case KEY_K -> GLFW_KEY_K; + case KEY_L -> GLFW_KEY_L; + case KEY_M -> GLFW_KEY_M; + case KEY_N -> GLFW_KEY_N; + case KEY_O -> GLFW_KEY_O; + case KEY_P -> GLFW_KEY_P; + case KEY_Q -> GLFW_KEY_Q; + case KEY_R -> GLFW_KEY_R; + case KEY_S -> GLFW_KEY_S; + case KEY_T -> GLFW_KEY_T; + case KEY_U -> GLFW_KEY_U; + case KEY_V -> GLFW_KEY_V; + case KEY_W -> GLFW_KEY_W; + case KEY_X -> GLFW_KEY_X; + case KEY_Y -> GLFW_KEY_Y; + case KEY_Z -> GLFW_KEY_Z; + case KEY_LEFT_BRACKET -> GLFW_KEY_LEFT_BRACKET; + case KEY_BACKSLASH -> GLFW_KEY_BACKSLASH; + case KEY_RIGHT_BRACKET -> GLFW_KEY_RIGHT_BRACKET; + case KEY_GRAVE_ACCENT -> GLFW_KEY_GRAVE_ACCENT; + case KEY_WORLD_1 -> GLFW_KEY_WORLD_1; + case KEY_WORLD_2 -> GLFW_KEY_WORLD_2; + case KEY_ESCAPE -> GLFW_KEY_ESCAPE; + case KEY_ENTER -> GLFW_KEY_ENTER; + case KEY_TAB -> GLFW_KEY_TAB; + case KEY_BACKSPACE -> GLFW_KEY_BACKSPACE; + case KEY_INSERT -> GLFW_KEY_INSERT; + case KEY_DELETE -> GLFW_KEY_DELETE; + case KEY_RIGHT -> GLFW_KEY_RIGHT; + case KEY_LEFT -> GLFW_KEY_LEFT; + case KEY_DOWN -> GLFW_KEY_DOWN; + case KEY_UP -> GLFW_KEY_UP; + case KEY_PAGE_UP -> GLFW_KEY_PAGE_UP; + case KEY_PAGE_DOWN -> GLFW_KEY_PAGE_DOWN; + case KEY_HOME -> GLFW_KEY_HOME; + case KEY_END -> GLFW_KEY_END; + case KEY_CAPS_LOCK -> GLFW_KEY_CAPS_LOCK; + case KEY_SCROLL_LOCK -> GLFW_KEY_SCROLL_LOCK; + case KEY_NUM_LOCK -> GLFW_KEY_NUM_LOCK; + case KEY_PRINT_SCREEN -> GLFW_KEY_PRINT_SCREEN; + case KEY_PAUSE -> GLFW_KEY_PAUSE; + case KEY_F1 -> GLFW_KEY_F1; + case KEY_F2 -> GLFW_KEY_F2; + case KEY_F3 -> GLFW_KEY_F3; + case KEY_F4 -> GLFW_KEY_F4; + case KEY_F5 -> GLFW_KEY_F5; + case KEY_F6 -> GLFW_KEY_F6; + case KEY_F7 -> GLFW_KEY_F7; + case KEY_F8 -> GLFW_KEY_F8; + case KEY_F9 -> GLFW_KEY_F9; + case KEY_F10 -> GLFW_KEY_F10; + case KEY_F11 -> GLFW_KEY_F11; + case KEY_F12 -> GLFW_KEY_F12; + case KEY_F13 -> GLFW_KEY_F13; + case KEY_F14 -> GLFW_KEY_F14; + case KEY_F15 -> GLFW_KEY_F15; + case KEY_F16 -> GLFW_KEY_F16; + case KEY_F17 -> GLFW_KEY_F17; + case KEY_F18 -> GLFW_KEY_F18; + case KEY_F19 -> GLFW_KEY_F19; + case KEY_F20 -> GLFW_KEY_F20; + case KEY_F21 -> GLFW_KEY_F21; + case KEY_F22 -> GLFW_KEY_F22; + case KEY_F23 -> GLFW_KEY_F23; + case KEY_F24 -> GLFW_KEY_F24; + case KEY_F25 -> GLFW_KEY_F25; + case KEY_KP_0 -> GLFW_KEY_KP_0; + case KEY_KP_1 -> GLFW_KEY_KP_1; + case KEY_KP_2 -> GLFW_KEY_KP_2; + case KEY_KP_3 -> GLFW_KEY_KP_3; + case KEY_KP_4 -> GLFW_KEY_KP_4; + case KEY_KP_5 -> GLFW_KEY_KP_5; + case KEY_KP_6 -> GLFW_KEY_KP_6; + case KEY_KP_7 -> GLFW_KEY_KP_7; + case KEY_KP_8 -> GLFW_KEY_KP_8; + case KEY_KP_9 -> GLFW_KEY_KP_9; + case KEY_KP_DECIMAL -> GLFW_KEY_KP_DECIMAL; + case KEY_KP_DIVIDE -> GLFW_KEY_KP_DIVIDE; + case KEY_KP_MULTIPLY -> GLFW_KEY_KP_MULTIPLY; + case KEY_KP_SUBTRACT -> GLFW_KEY_KP_SUBTRACT; + case KEY_KP_ADD -> GLFW_KEY_KP_ADD; + case KEY_KP_ENTER -> GLFW_KEY_KP_ENTER; + case KEY_KP_EQUAL -> GLFW_KEY_KP_EQUAL; + case KEY_LEFT_SHIFT -> GLFW_KEY_LEFT_SHIFT; + case KEY_LEFT_CONTROL -> GLFW_KEY_LEFT_CONTROL; + case KEY_LEFT_ALT -> GLFW_KEY_LEFT_ALT; + case KEY_LEFT_SUPER -> GLFW_KEY_LEFT_SUPER; + case KEY_RIGHT_SHIFT -> GLFW_KEY_RIGHT_SHIFT; + case KEY_RIGHT_CONTROL -> GLFW_KEY_RIGHT_CONTROL; + case KEY_RIGHT_ALT -> GLFW_KEY_RIGHT_ALT; + case KEY_RIGHT_SUPER -> GLFW_KEY_RIGHT_SUPER; + case KEY_MENU -> GLFW_KEY_MENU; + case KEY_LAST -> GLFW_KEY_LAST; + }; + } + + public static Key parseKey(int code) { + return switch (code) { + case GLFW_KEY_SPACE -> Key.KEY_SPACE; + case GLFW_KEY_APOSTROPHE -> Key.KEY_APOSTROPHE; + case GLFW_KEY_COMMA -> Key.KEY_COMMA; + case GLFW_KEY_MINUS -> Key.KEY_MINUS; + case GLFW_KEY_PERIOD -> Key.KEY_PERIOD; + case GLFW_KEY_SLASH -> Key.KEY_SLASH; + case GLFW_KEY_0 -> Key.KEY_0; + case GLFW_KEY_1 -> Key.KEY_1; + case GLFW_KEY_2 -> Key.KEY_2; + case GLFW_KEY_3 -> Key.KEY_3; + case GLFW_KEY_4 -> Key.KEY_4; + case GLFW_KEY_5 -> Key.KEY_5; + case GLFW_KEY_6 -> Key.KEY_6; + case GLFW_KEY_7 -> Key.KEY_7; + case GLFW_KEY_8 -> Key.KEY_8; + case GLFW_KEY_9 -> Key.KEY_9; + case GLFW_KEY_SEMICOLON -> Key.KEY_SEMICOLON; + case GLFW_KEY_EQUAL -> Key.KEY_EQUAL; + case GLFW_KEY_A -> Key.KEY_A; + case GLFW_KEY_B -> Key.KEY_B; + case GLFW_KEY_C -> Key.KEY_C; + case GLFW_KEY_D -> Key.KEY_D; + case GLFW_KEY_E -> Key.KEY_E; + case GLFW_KEY_F -> Key.KEY_F; + case GLFW_KEY_G -> Key.KEY_G; + case GLFW_KEY_H -> Key.KEY_H; + case GLFW_KEY_I -> Key.KEY_I; + case GLFW_KEY_J -> Key.KEY_J; + case GLFW_KEY_K -> Key.KEY_K; + case GLFW_KEY_L -> Key.KEY_L; + case GLFW_KEY_M -> Key.KEY_M; + case GLFW_KEY_N -> Key.KEY_N; + case GLFW_KEY_O -> Key.KEY_O; + case GLFW_KEY_P -> Key.KEY_P; + case GLFW_KEY_Q -> Key.KEY_Q; + case GLFW_KEY_R -> Key.KEY_R; + case GLFW_KEY_S -> Key.KEY_S; + case GLFW_KEY_T -> Key.KEY_T; + case GLFW_KEY_U -> Key.KEY_U; + case GLFW_KEY_V -> Key.KEY_V; + case GLFW_KEY_W -> Key.KEY_W; + case GLFW_KEY_X -> Key.KEY_X; + case GLFW_KEY_Y -> Key.KEY_Y; + case GLFW_KEY_Z -> Key.KEY_Z; + case GLFW_KEY_LEFT_BRACKET -> Key.KEY_LEFT_BRACKET; + case GLFW_KEY_BACKSLASH -> Key.KEY_BACKSLASH; + case GLFW_KEY_RIGHT_BRACKET -> Key.KEY_RIGHT_BRACKET; + case GLFW_KEY_GRAVE_ACCENT -> Key.KEY_GRAVE_ACCENT; + case GLFW_KEY_WORLD_1 -> Key.KEY_WORLD_1; + case GLFW_KEY_WORLD_2 -> Key.KEY_WORLD_2; + case GLFW_KEY_ESCAPE -> Key.KEY_ESCAPE; + case GLFW_KEY_ENTER -> Key.KEY_ENTER; + case GLFW_KEY_TAB -> Key.KEY_TAB; + case GLFW_KEY_BACKSPACE -> Key.KEY_BACKSPACE; + case GLFW_KEY_INSERT -> Key.KEY_INSERT; + case GLFW_KEY_DELETE -> Key.KEY_DELETE; + case GLFW_KEY_RIGHT -> Key.KEY_RIGHT; + case GLFW_KEY_LEFT -> Key.KEY_LEFT; + case GLFW_KEY_DOWN -> Key.KEY_DOWN; + case GLFW_KEY_UP -> Key.KEY_UP; + case GLFW_KEY_PAGE_UP -> Key.KEY_PAGE_UP; + case GLFW_KEY_PAGE_DOWN -> Key.KEY_PAGE_DOWN; + case GLFW_KEY_HOME -> Key.KEY_HOME; + case GLFW_KEY_END -> Key.KEY_END; + case GLFW_KEY_CAPS_LOCK -> Key.KEY_CAPS_LOCK; + case GLFW_KEY_SCROLL_LOCK -> Key.KEY_SCROLL_LOCK; + case GLFW_KEY_NUM_LOCK -> Key.KEY_NUM_LOCK; + case GLFW_KEY_PRINT_SCREEN -> Key.KEY_PRINT_SCREEN; + case GLFW_KEY_PAUSE -> Key.KEY_PAUSE; + case GLFW_KEY_F1 -> Key.KEY_F1; + case GLFW_KEY_F2 -> Key.KEY_F2; + case GLFW_KEY_F3 -> Key.KEY_F3; + case GLFW_KEY_F4 -> Key.KEY_F4; + case GLFW_KEY_F5 -> Key.KEY_F5; + case GLFW_KEY_F6 -> Key.KEY_F6; + case GLFW_KEY_F7 -> Key.KEY_F7; + case GLFW_KEY_F8 -> Key.KEY_F8; + case GLFW_KEY_F9 -> Key.KEY_F9; + case GLFW_KEY_F10 -> Key.KEY_F10; + case GLFW_KEY_F11 -> Key.KEY_F11; + case GLFW_KEY_F12 -> Key.KEY_F12; + case GLFW_KEY_F13 -> Key.KEY_F13; + case GLFW_KEY_F14 -> Key.KEY_F14; + case GLFW_KEY_F15 -> Key.KEY_F15; + case GLFW_KEY_F16 -> Key.KEY_F16; + case GLFW_KEY_F17 -> Key.KEY_F17; + case GLFW_KEY_F18 -> Key.KEY_F18; + case GLFW_KEY_F19 -> Key.KEY_F19; + case GLFW_KEY_F20 -> Key.KEY_F20; + case GLFW_KEY_F21 -> Key.KEY_F21; + case GLFW_KEY_F22 -> Key.KEY_F22; + case GLFW_KEY_F23 -> Key.KEY_F23; + case GLFW_KEY_F24 -> Key.KEY_F24; + case GLFW_KEY_F25 -> Key.KEY_F25; + case GLFW_KEY_KP_0 -> Key.KEY_KP_0; + case GLFW_KEY_KP_1 -> Key.KEY_KP_1; + case GLFW_KEY_KP_2 -> Key.KEY_KP_2; + case GLFW_KEY_KP_3 -> Key.KEY_KP_3; + case GLFW_KEY_KP_4 -> Key.KEY_KP_4; + case GLFW_KEY_KP_5 -> Key.KEY_KP_5; + case GLFW_KEY_KP_6 -> Key.KEY_KP_6; + case GLFW_KEY_KP_7 -> Key.KEY_KP_7; + case GLFW_KEY_KP_8 -> Key.KEY_KP_8; + case GLFW_KEY_KP_9 -> Key.KEY_KP_9; + case GLFW_KEY_KP_DECIMAL -> Key.KEY_KP_DECIMAL; + case GLFW_KEY_KP_DIVIDE -> Key.KEY_KP_DIVIDE; + case GLFW_KEY_KP_MULTIPLY -> Key.KEY_KP_MULTIPLY; + case GLFW_KEY_KP_SUBTRACT -> Key.KEY_KP_SUBTRACT; + case GLFW_KEY_KP_ADD -> Key.KEY_KP_ADD; + case GLFW_KEY_KP_ENTER -> Key.KEY_KP_ENTER; + case GLFW_KEY_KP_EQUAL -> Key.KEY_KP_EQUAL; + case GLFW_KEY_LEFT_SHIFT -> Key.KEY_LEFT_SHIFT; + case GLFW_KEY_LEFT_CONTROL -> Key.KEY_LEFT_CONTROL; + case GLFW_KEY_LEFT_ALT -> Key.KEY_LEFT_ALT; + case GLFW_KEY_LEFT_SUPER -> Key.KEY_LEFT_SUPER; + case GLFW_KEY_RIGHT_SHIFT -> Key.KEY_RIGHT_SHIFT; + case GLFW_KEY_RIGHT_CONTROL -> Key.KEY_RIGHT_CONTROL; + case GLFW_KEY_RIGHT_ALT -> Key.KEY_RIGHT_ALT; + case GLFW_KEY_RIGHT_SUPER -> Key.KEY_RIGHT_SUPER; + default -> throw new AppException("Unknown key code: %d", code); + }; + } + + public static KeyAction parseAction(int code) { + return switch (code) { + case GLFW_PRESS -> KeyAction.PRESS; + case GLFW_RELEASE -> KeyAction.RELEASE; + case GLFW_REPEAT -> KeyAction.REPEAT; + default -> throw new AppException("Unknown key code: %d", code); + }; + } +} diff --git a/engine/src/main/java/com/bartlomiejpluta/base/engine/ui/manager/InputManager.java b/engine/src/main/java/com/bartlomiejpluta/base/engine/ui/manager/InputManager.java deleted file mode 100644 index 68221f98..00000000 --- a/engine/src/main/java/com/bartlomiejpluta/base/engine/ui/manager/InputManager.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.bartlomiejpluta.base.engine.ui.manager; - -import com.bartlomiejpluta.base.api.game.input.Input; -import com.bartlomiejpluta.base.engine.error.AppException; -import com.bartlomiejpluta.base.engine.ui.model.GLFWInput; -import com.bartlomiejpluta.base.engine.ui.model.GLFWScreen; -import lombok.NonNull; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Component; - -@Slf4j -@Component -public class InputManager { - private GLFWScreen screen; - private Input input; - - void registerScreen(@NonNull GLFWScreen screen) { - this.screen = screen; - } - - public Input getInput() { - if (input != null) { - return input; - } - - log.info("Creating input model singleton instance"); - - if (screen == null) { - throw new AppException("GLFWScreen is not registered yet"); - } - - input = new GLFWInput(screen); - - return input; - } -} diff --git a/engine/src/main/java/com/bartlomiejpluta/base/engine/ui/manager/ScreenManager.java b/engine/src/main/java/com/bartlomiejpluta/base/engine/ui/manager/ScreenManager.java index 1ec1d4b0..21579ab9 100644 --- a/engine/src/main/java/com/bartlomiejpluta/base/engine/ui/manager/ScreenManager.java +++ b/engine/src/main/java/com/bartlomiejpluta/base/engine/ui/manager/ScreenManager.java @@ -11,12 +11,9 @@ import org.springframework.stereotype.Component; @Component @RequiredArgsConstructor(onConstructor = @__(@Autowired)) public class ScreenManager { - private final InputManager inputManager; public Screen createScreen(String title, int width, int height) { log.info("Creating GLFW window ([{}], {}x{})", title, width, height); - var screen = GLFWScreen.create(title, width, height); - inputManager.registerScreen(screen); - return screen; + return GLFWScreen.create(title, width, height); } } diff --git a/engine/src/main/java/com/bartlomiejpluta/base/engine/ui/model/GLFWInput.java b/engine/src/main/java/com/bartlomiejpluta/base/engine/ui/model/GLFWInput.java index 3b6ff1f1..e2321d1a 100644 --- a/engine/src/main/java/com/bartlomiejpluta/base/engine/ui/model/GLFWInput.java +++ b/engine/src/main/java/com/bartlomiejpluta/base/engine/ui/model/GLFWInput.java @@ -1,15 +1,59 @@ package com.bartlomiejpluta.base.engine.ui.model; +import com.bartlomiejpluta.base.api.game.context.Context; import com.bartlomiejpluta.base.api.game.input.Input; import com.bartlomiejpluta.base.api.game.input.Key; -import lombok.RequiredArgsConstructor; +import com.bartlomiejpluta.base.api.game.input.KeyEvent; +import com.bartlomiejpluta.base.api.game.screen.Screen; +import com.bartlomiejpluta.base.engine.ui.event.GLFWKeyEvent; +import lombok.NonNull; +import lombok.extern.slf4j.Slf4j; -@RequiredArgsConstructor +import java.util.Deque; +import java.util.LinkedList; +import java.util.function.Consumer; + +import static com.bartlomiejpluta.base.engine.ui.event.GLFWKeyEvent.glfwCode; +import static org.lwjgl.glfw.GLFW.*; + +@Slf4j public class GLFWInput implements Input { - private final GLFWScreen screen; + private final long windowHandle; + private final Deque> keyEventHandlers = new LinkedList<>(); + + public GLFWInput(@NonNull Screen screen) { + this.windowHandle = screen.getID(); + } + + public void init(Context context) { + log.info("Registering key callback"); + glfwSetKeyCallback(windowHandle, (window, key, scancode, action, mods) -> { + var event = GLFWKeyEvent.of(key, action); + + context.handleKeyEvent(event); + + for (var handler : keyEventHandlers) { + if (event.isConsumed()) { + return; + } + + handler.accept(event); + } + }); + } @Override public boolean isKeyPressed(Key key) { - return screen.isKeyPressed(key); + return glfwGetKey(windowHandle, glfwCode(key)) == GLFW_PRESS; + } + + @Override + public void addKeyEventHandler(Consumer handler) { + keyEventHandlers.addLast(handler); + } + + @Override + public void removeKeyEventHandler(Consumer handler) { + keyEventHandlers.remove(handler); } } diff --git a/engine/src/main/java/com/bartlomiejpluta/base/engine/ui/model/GLFWScreen.java b/engine/src/main/java/com/bartlomiejpluta/base/engine/ui/model/GLFWScreen.java index 0b838917..338973a2 100644 --- a/engine/src/main/java/com/bartlomiejpluta/base/engine/ui/model/GLFWScreen.java +++ b/engine/src/main/java/com/bartlomiejpluta/base/engine/ui/model/GLFWScreen.java @@ -1,6 +1,5 @@ package com.bartlomiejpluta.base.engine.ui.model; -import com.bartlomiejpluta.base.api.game.input.Key; import com.bartlomiejpluta.base.api.game.screen.Screen; import com.bartlomiejpluta.base.engine.error.AppException; import lombok.Getter; @@ -43,7 +42,7 @@ public class GLFWScreen implements Screen { @Override public void init() { - if(initialized) { + if (initialized) { throw new IllegalStateException("The window is already initialized"); } @@ -109,16 +108,17 @@ public class GLFWScreen implements Screen { clear(0.0f, 0.0f, 0.0f, 0.0f); } + @Override + public long getID() { + return windowHandle; + } + @Override public void update() { glfwSwapBuffers(windowHandle); glfwPollEvents(); } - public boolean isKeyPressed(Key key) { - return glfwGetKey(windowHandle, glfwCode(key)) == GLFW_PRESS; - } - @Override public void clear(float r, float g, float b, float alpha) { glClearColor(r, g, b, alpha); @@ -140,133 +140,7 @@ public class GLFWScreen implements Screen { return size; } - public static GLFWScreen create(String title, int width, int height) { + public static Screen create(String title, int width, int height) { return new GLFWScreen(title, width, height); } - - private static int glfwCode(Key key) { - return switch (key) { - case KEY_SPACE -> GLFW_KEY_SPACE; - case KEY_APOSTROPHE -> GLFW_KEY_APOSTROPHE; - case KEY_COMMA -> GLFW_KEY_COMMA; - case KEY_MINUS -> GLFW_KEY_MINUS; - case KEY_PERIOD -> GLFW_KEY_PERIOD; - case KEY_SLASH -> GLFW_KEY_SLASH; - case KEY_0 -> GLFW_KEY_0; - case KEY_1 -> GLFW_KEY_1; - case KEY_2 -> GLFW_KEY_2; - case KEY_3 -> GLFW_KEY_3; - case KEY_4 -> GLFW_KEY_4; - case KEY_5 -> GLFW_KEY_5; - case KEY_6 -> GLFW_KEY_6; - case KEY_7 -> GLFW_KEY_7; - case KEY_8 -> GLFW_KEY_8; - case KEY_9 -> GLFW_KEY_9; - case KEY_SEMICOLON -> GLFW_KEY_SEMICOLON; - case KEY_EQUAL -> GLFW_KEY_EQUAL; - case KEY_A -> GLFW_KEY_A; - case KEY_B -> GLFW_KEY_B; - case KEY_C -> GLFW_KEY_C; - case KEY_D -> GLFW_KEY_D; - case KEY_E -> GLFW_KEY_E; - case KEY_F -> GLFW_KEY_F; - case KEY_G -> GLFW_KEY_G; - case KEY_H -> GLFW_KEY_H; - case KEY_I -> GLFW_KEY_I; - case KEY_J -> GLFW_KEY_J; - case KEY_K -> GLFW_KEY_K; - case KEY_L -> GLFW_KEY_L; - case KEY_M -> GLFW_KEY_M; - case KEY_N -> GLFW_KEY_N; - case KEY_O -> GLFW_KEY_O; - case KEY_P -> GLFW_KEY_P; - case KEY_Q -> GLFW_KEY_Q; - case KEY_R -> GLFW_KEY_R; - case KEY_S -> GLFW_KEY_S; - case KEY_T -> GLFW_KEY_T; - case KEY_U -> GLFW_KEY_U; - case KEY_V -> GLFW_KEY_V; - case KEY_W -> GLFW_KEY_W; - case KEY_X -> GLFW_KEY_X; - case KEY_Y -> GLFW_KEY_Y; - case KEY_Z -> GLFW_KEY_Z; - case KEY_LEFT_BRACKET -> GLFW_KEY_LEFT_BRACKET; - case KEY_BACKSLASH -> GLFW_KEY_BACKSLASH; - case KEY_RIGHT_BRACKET -> GLFW_KEY_RIGHT_BRACKET; - case KEY_GRAVE_ACCENT -> GLFW_KEY_GRAVE_ACCENT; - case KEY_WORLD_1 -> GLFW_KEY_WORLD_1; - case KEY_WORLD_2 -> GLFW_KEY_WORLD_2; - case KEY_ESCAPE -> GLFW_KEY_ESCAPE; - case KEY_ENTER -> GLFW_KEY_ENTER; - case KEY_TAB -> GLFW_KEY_TAB; - case KEY_BACKSPACE -> GLFW_KEY_BACKSPACE; - case KEY_INSERT -> GLFW_KEY_INSERT; - case KEY_DELETE -> GLFW_KEY_DELETE; - case KEY_RIGHT -> GLFW_KEY_RIGHT; - case KEY_LEFT -> GLFW_KEY_LEFT; - case KEY_DOWN -> GLFW_KEY_DOWN; - case KEY_UP -> GLFW_KEY_UP; - case KEY_PAGE_UP -> GLFW_KEY_PAGE_UP; - case KEY_PAGE_DOWN -> GLFW_KEY_PAGE_DOWN; - case KEY_HOME -> GLFW_KEY_HOME; - case KEY_END -> GLFW_KEY_END; - case KEY_CAPS_LOCK -> GLFW_KEY_CAPS_LOCK; - case KEY_SCROLL_LOCK -> GLFW_KEY_SCROLL_LOCK; - case KEY_NUM_LOCK -> GLFW_KEY_NUM_LOCK; - case KEY_PRINT_SCREEN -> GLFW_KEY_PRINT_SCREEN; - case KEY_PAUSE -> GLFW_KEY_PAUSE; - case KEY_F1 -> GLFW_KEY_F1; - case KEY_F2 -> GLFW_KEY_F2; - case KEY_F3 -> GLFW_KEY_F3; - case KEY_F4 -> GLFW_KEY_F4; - case KEY_F5 -> GLFW_KEY_F5; - case KEY_F6 -> GLFW_KEY_F6; - case KEY_F7 -> GLFW_KEY_F7; - case KEY_F8 -> GLFW_KEY_F8; - case KEY_F9 -> GLFW_KEY_F9; - case KEY_F10 -> GLFW_KEY_F10; - case KEY_F11 -> GLFW_KEY_F11; - case KEY_F12 -> GLFW_KEY_F12; - case KEY_F13 -> GLFW_KEY_F13; - case KEY_F14 -> GLFW_KEY_F14; - case KEY_F15 -> GLFW_KEY_F15; - case KEY_F16 -> GLFW_KEY_F16; - case KEY_F17 -> GLFW_KEY_F17; - case KEY_F18 -> GLFW_KEY_F18; - case KEY_F19 -> GLFW_KEY_F19; - case KEY_F20 -> GLFW_KEY_F20; - case KEY_F21 -> GLFW_KEY_F21; - case KEY_F22 -> GLFW_KEY_F22; - case KEY_F23 -> GLFW_KEY_F23; - case KEY_F24 -> GLFW_KEY_F24; - case KEY_F25 -> GLFW_KEY_F25; - case KEY_KP_0 -> GLFW_KEY_KP_0; - case KEY_KP_1 -> GLFW_KEY_KP_1; - case KEY_KP_2 -> GLFW_KEY_KP_2; - case KEY_KP_3 -> GLFW_KEY_KP_3; - case KEY_KP_4 -> GLFW_KEY_KP_4; - case KEY_KP_5 -> GLFW_KEY_KP_5; - case KEY_KP_6 -> GLFW_KEY_KP_6; - case KEY_KP_7 -> GLFW_KEY_KP_7; - case KEY_KP_8 -> GLFW_KEY_KP_8; - case KEY_KP_9 -> GLFW_KEY_KP_9; - case KEY_KP_DECIMAL -> GLFW_KEY_KP_DECIMAL; - case KEY_KP_DIVIDE -> GLFW_KEY_KP_DIVIDE; - case KEY_KP_MULTIPLY -> GLFW_KEY_KP_MULTIPLY; - case KEY_KP_SUBTRACT -> GLFW_KEY_KP_SUBTRACT; - case KEY_KP_ADD -> GLFW_KEY_KP_ADD; - case KEY_KP_ENTER -> GLFW_KEY_KP_ENTER; - case KEY_KP_EQUAL -> GLFW_KEY_KP_EQUAL; - case KEY_LEFT_SHIFT -> GLFW_KEY_LEFT_SHIFT; - case KEY_LEFT_CONTROL -> GLFW_KEY_LEFT_CONTROL; - case KEY_LEFT_ALT -> GLFW_KEY_LEFT_ALT; - case KEY_LEFT_SUPER -> GLFW_KEY_LEFT_SUPER; - case KEY_RIGHT_SHIFT -> GLFW_KEY_RIGHT_SHIFT; - case KEY_RIGHT_CONTROL -> GLFW_KEY_RIGHT_CONTROL; - case KEY_RIGHT_ALT -> GLFW_KEY_RIGHT_ALT; - case KEY_RIGHT_SUPER -> GLFW_KEY_RIGHT_SUPER; - case KEY_MENU -> GLFW_KEY_MENU; - case KEY_LAST -> GLFW_KEY_LAST; - }; - } }