Base of InputModule refactoring

This commit is contained in:
2014-07-27 16:16:32 +02:00
parent a4108f2caf
commit a9b38b9417
28 changed files with 221 additions and 219 deletions
@@ -6,6 +6,7 @@ import mightypork.gamecore.backends.lwjgl.audio.SlickAudioModule;
import mightypork.gamecore.backends.lwjgl.graphics.LwjglGraphicsModule;
import mightypork.gamecore.core.AppBackend;
import mightypork.gamecore.graphics.GraphicsModule;
import mightypork.gamecore.input.InputModule;
/**
@@ -17,6 +18,7 @@ public class LwjglBackend extends AppBackend {
private LwjglGraphicsModule graphics;
private SlickAudioModule audio;
private LwjglInputModule input;
@Override
@@ -24,6 +26,11 @@ public class LwjglBackend extends AppBackend {
{
addChildClient(graphics = new LwjglGraphicsModule());
addChildClient(audio = new SlickAudioModule());
addChildClient(input = new LwjglInputModule());
graphics.init();
audio.init();
input.init();
app.addInitTask(new InitTaskRedirectSlickLog());
}
@@ -41,4 +48,11 @@ public class LwjglBackend extends AppBackend {
{
return audio;
}
@Override
public InputModule getInput()
{
return input;
}
}
@@ -1,14 +1,13 @@
package mightypork.gamecore.input;
package mightypork.gamecore.backends.lwjgl;
import mightypork.gamecore.core.App;
import mightypork.gamecore.core.events.UserQuitRequest;
import mightypork.gamecore.input.events.InputReadyEvent;
import mightypork.gamecore.input.InputModule;
import mightypork.gamecore.input.Keys;
import mightypork.gamecore.input.events.KeyEvent;
import mightypork.gamecore.input.events.MouseButtonEvent;
import mightypork.gamecore.input.events.MouseMotionEvent;
import mightypork.utils.eventbus.clients.BusNode;
import mightypork.utils.interfaces.Destroyable;
import mightypork.utils.interfaces.Updateable;
import mightypork.utils.math.constraints.vect.Vect;
import mightypork.utils.math.constraints.vect.var.VectVar;
@@ -24,9 +23,7 @@ import org.lwjgl.opengl.Display;
*
* @author Ondřej Hruška (MightyPork)
*/
public class InputSystem extends BusNode implements Updateable, KeyBinder, Destroyable {
private static boolean inited = false;
public class LwjglInputModule extends InputModule implements Updateable {
/** Current mouse position */
private static final Vect mousePos = new Vect() {
@@ -49,40 +46,18 @@ public class InputSystem extends BusNode implements Updateable, KeyBinder, Destr
}
};
private final KeyBindingPool keybindings;
private final VectVar mouseMove = Vect.makeVar();
private final VectVar mouseLastPos = Vect.makeVar();
/**
* @param app app access
*/
public InputSystem() {
initDevices();
// global keybindings
keybindings = new KeyBindingPool();
addChildClient(keybindings);
App.bus().send(new InputReadyEvent());
}
@Override
public final void destroy()
public void destroy()
{
Mouse.destroy();
Keyboard.destroy();
}
private void initDevices()
@Override
protected void initDevices()
{
if (inited) return;
inited = true;
try {
Mouse.create();
Keyboard.create();
@@ -92,19 +67,8 @@ public class InputSystem extends BusNode implements Updateable, KeyBinder, Destr
}
}
@Override
public final void bindKey(KeyStroke stroke, Edge edge, Runnable task)
{
keybindings.bindKey(stroke, edge, task);
}
@Override
public void unbindKey(KeyStroke stroke)
{
keybindings.unbindKey(stroke);
}
private final VectVar mouseMove = Vect.makeVar();
private final VectVar mouseLastPos = Vect.makeVar();
@Override
@@ -172,94 +136,62 @@ public class InputSystem extends BusNode implements Updateable, KeyBinder, Destr
}
/**
* Get absolute mouse position. This vect is final and views at it can
* safely be made.
*
* @return mouse position
*/
public static Vect getMousePos()
@Override
public Vect getMousePos()
{
return mousePos;
}
/**
* @return true if mouse is inside window.
*/
public static boolean isMouseInside()
@Override
public boolean isMouseInside()
{
return Mouse.isInsideWindow();
}
/**
* Trap mouse cursor in the window
*
* @param grab true to grab
*/
public static void grabMouse(boolean grab)
@Override
public void grabMouse(boolean grab)
{
Mouse.setGrabbed(grab);
}
/**
* Check if key is down
*
* @param key key to check (constant from the {@link Keys} class)
* @return is down
*/
public static boolean isKeyDown(int key)
@Override
public boolean isKeyDown(int key)
{
return Keyboard.isKeyDown(key);
}
/**
* Check mouse button state
*
* @param button button to test (0 left, 1 right, 2 middle)
* @return button is down
*/
public static boolean isMouseButtonDown(int button)
@Override
public boolean isMouseButtonDown(int button)
{
return Mouse.isButtonDown(button);
}
/**
* @return bit mask of active mod keys
*/
public static int getActiveModKeys()
@Override
public int getActiveModKeys()
{
int mods = 0;
if (Keyboard.isKeyDown(Keys.L_ALT) || Keyboard.isKeyDown(Keys.R_ALT)) {
if (isKeyDown(Keys.L_ALT) || isKeyDown(Keys.R_ALT)) {
mods |= Keys.MOD_ALT;
}
if (Keyboard.isKeyDown(Keys.L_SHIFT) || Keyboard.isKeyDown(Keys.R_SHIFT)) {
if (isKeyDown(Keys.L_SHIFT) || isKeyDown(Keys.R_SHIFT)) {
mods |= Keys.MOD_SHIFT;
}
if (Keyboard.isKeyDown(Keys.L_CONTROL) || Keyboard.isKeyDown(Keys.R_CONTROL)) {
if (isKeyDown(Keys.L_CONTROL) || isKeyDown(Keys.R_CONTROL)) {
mods |= Keys.MOD_CONTROL;
}
if (Keyboard.isKeyDown(Keys.L_META) || Keyboard.isKeyDown(Keys.R_META)) {
if (isKeyDown(Keys.L_META) || isKeyDown(Keys.R_META)) {
mods |= Keys.MOD_META;
}
return mods;
}
/**
* @return true if the system is initialized
*/
public static boolean isReady()
{
return inited;
}
}
@@ -22,33 +22,22 @@ import org.newdawn.slick.openal.SoundStore;
*/
public class SlickAudioModule extends AudioModule {
private static final Vect INITIAL_LISTENER_POS = Vect.ZERO;
private static final int MAX_SOURCES = 256;
private VectVar listener = Vect.makeVar();
private static boolean soundSystemInited = false;
private final VectVar listenerPos = Vect.makeVar();
public SlickAudioModule() {
if (!soundSystemInited) {
soundSystemInited = true;
try {
SoundStore.get().setMaxSources(MAX_SOURCES);
SoundStore.get().init();
setListenerPos(INITIAL_LISTENER_POS);
} catch (final Throwable t) {
Log.e("Error initializing sound system.", t);
}
}
@Override
public void init()
{
SoundStore.get().setMaxSources(256);
SoundStore.get().init();
setListenerPos(Vect.ZERO);
}
@Override
public void setListenerPos(Vect pos)
{
listener.setTo(pos);
listenerPos.setTo(pos);
final FloatBuffer buf3 = BufferHelper.alloc(3);
final FloatBuffer buf6 = BufferHelper.alloc(6);
buf3.clear();
@@ -66,7 +55,7 @@ public class SlickAudioModule extends AudioModule {
@Override
public Vect getListenerPos()
{
return listener;
return listenerPos;
}
@@ -49,7 +49,7 @@ public class LwjglGraphicsModule extends GraphicsModule {
/** FPS the user wants */
private int targetFps;
/** FPS meter used for measuring actual FPS */
private FpsMeter fpsMeter;
private FpsMeter fpsMeter = new FpsMeter();
/** Flag that at the end of frame, fullscreen should be toggled. */
private boolean fullscreenToggleRequested;
@@ -79,6 +79,17 @@ public class LwjglGraphicsModule extends GraphicsModule {
private static final Rect rect = Rect.make(screenSize);
@Override
public void init()
{
try {
Display.create();
} catch (final Exception e) {
throw new RuntimeException("Could not initialize display.", e);
}
}
@Override
public void setColor(Color color)
{
@@ -423,27 +434,6 @@ public class LwjglGraphicsModule extends GraphicsModule {
}
@Override
public void createDisplay()
{
if (Display.isCreated()) throw new IllegalStateException("Display already created.");
try {
Display.create();
fpsMeter = new FpsMeter();
if (fullscreenSetRequested && fullscreenSetState) {
doToggleFullscreen();
Display.update();
fullscreenSetRequested = false;
}
} catch (final Exception e) {
throw new RuntimeException("Could not initialize display.", e);
}
}
@Override
public void setFullscreen(boolean fs)
{
@@ -27,7 +27,6 @@ public class DeferredLwjglFont extends DeferredFont {
private IFont font = null;
/**
* A font from resource
*
@@ -4,7 +4,6 @@ package mightypork.gamecore.backends.lwjgl.graphics.font;
import java.awt.Font;
import java.io.IOException;
import mightypork.gamecore.graphics.textures.FilterMode;
import mightypork.utils.annotations.Alias;
+20 -10
View File
@@ -2,17 +2,12 @@ package mightypork.gamecore.core;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import mightypork.gamecore.audio.AudioModule;
import mightypork.gamecore.core.config.Config;
import mightypork.gamecore.core.init.InitTaskCrashHandler;
import mightypork.gamecore.core.init.InitTaskIonizables;
import mightypork.gamecore.core.init.InitTaskLog;
import mightypork.gamecore.core.init.InitTaskLogHeader;
import mightypork.gamecore.graphics.GraphicsModule;
import mightypork.gamecore.input.InputModule;
import mightypork.utils.annotations.Stub;
import mightypork.utils.eventbus.EventBus;
import mightypork.utils.eventbus.clients.BusNode;
@@ -164,6 +159,10 @@ public class App extends BusNode {
}
/**
* Shut down the running instance.<br>
* Deinitialize backend modules and terminate the JVM.
*/
public static void shutdown()
{
if (instance == null) throw new IllegalStateException("App is not running.");
@@ -199,9 +198,9 @@ public class App extends BusNode {
/**
* Get graphics module from the backend
* Get graphics module from the running app's backend
*
* @return backend
* @return graphics module
*/
public static GraphicsModule gfx()
{
@@ -210,9 +209,9 @@ public class App extends BusNode {
/**
* Get audio module from the backend
* Get audio module from the running app's backend
*
* @return backend
* @return audio module
*/
public static AudioModule audio()
{
@@ -220,6 +219,17 @@ public class App extends BusNode {
}
/**
* Get input module from the running app's backend
*
* @return input module
*/
public static InputModule input()
{
return instance.backend.getInput();
}
/**
* Get event bus instance.
*
@@ -3,6 +3,7 @@ package mightypork.gamecore.core;
import mightypork.gamecore.audio.AudioModule;
import mightypork.gamecore.graphics.GraphicsModule;
import mightypork.gamecore.input.InputModule;
import mightypork.utils.eventbus.clients.BusNode;
@@ -53,4 +54,12 @@ public abstract class AppBackend extends BusNode {
* @return audio module
*/
public abstract AudioModule getAudio();
/**
* Get input module
*
* @return input module
*/
public abstract InputModule getInput();
}
@@ -13,6 +13,9 @@ import mightypork.utils.interfaces.Destroyable;
*/
public abstract class BackendModule extends BusNode implements Destroyable {
public abstract void init();
@Override
@Stub
public void destroy()
+3 -2
View File
@@ -28,8 +28,9 @@ public abstract class InitTask {
* Assign the initialized app instance to a protected "app" field.
*
* @param app app
*/
void bind(App app) {
*/
void bind(App app)
{
this.app = app;
}
@@ -3,7 +3,6 @@ package mightypork.gamecore.core.config;
import mightypork.gamecore.core.InitTask;
import mightypork.utils.annotations.Stub;
import mightypork.utils.exceptions.IllegalValueException;
/**
@@ -85,8 +85,6 @@ public class InitTaskDisplay extends InitTask {
gfx.setTargetFps(fps);
if (fullscreen) gfx.setFullscreen(true);
gfx.createDisplay();
}
@@ -4,6 +4,7 @@ package mightypork.gamecore.graphics;
import mightypork.gamecore.core.BackendModule;
import mightypork.gamecore.graphics.textures.DeferredTexture;
import mightypork.gamecore.graphics.textures.TxQuad;
import mightypork.gamecore.gui.events.ViewportChangeEvent;
import mightypork.utils.math.color.Color;
import mightypork.utils.math.color.Grad;
import mightypork.utils.math.constraints.rect.Rect;
@@ -280,13 +281,9 @@ public abstract class GraphicsModule extends BackendModule {
/**
* Create a main window, if needed
*/
public abstract void createDisplay();
/**
* Set fullscreen
* Set fullscreen. The fullscreen state will be changed when possible (eg.
* at the end of the current frame) and a {@link ViewportChangeEvent} will
* be fired.
*
* @param fs true for fullscreen
*/
@@ -294,13 +291,15 @@ public abstract class GraphicsModule extends BackendModule {
/**
* Request fullscreen toggle (eg. at the end of render frame)
* Request fullscreen toggle. See setFullscreen() for more info)
*/
public abstract void switchFullscreen();
/**
* Get fullscreen state
* Get fullscreen state (note that methods changing fullscreen may not have
* immediate effect, so this method may report the old state if the
* fullscreen state has not yet been changed).
*
* @return is fullscreen
*/
@@ -1,10 +1,11 @@
package mightypork.gamecore.gui.components;
import mightypork.gamecore.backends.lwjgl.LwjglInputModule;
import mightypork.gamecore.core.App;
import mightypork.gamecore.graphics.Renderable;
import mightypork.gamecore.gui.events.LayoutChangeEvent;
import mightypork.gamecore.gui.events.LayoutChangeListener;
import mightypork.gamecore.input.InputSystem;
import mightypork.utils.Support;
import mightypork.utils.annotations.Stub;
import mightypork.utils.interfaces.Enableable;
@@ -98,7 +99,7 @@ public abstract class BaseComponent extends AbstractRectCache implements Compone
@Override
public final boolean isMouseOver()
{
return InputSystem.getMousePos().isInside(this);
return App.input().getMousePos().isInside(this);
}
@@ -1,10 +1,11 @@
package mightypork.gamecore.gui.components.input;
import mightypork.gamecore.backends.lwjgl.LwjglInputModule;
import mightypork.gamecore.core.App;
import mightypork.gamecore.graphics.fonts.IFont;
import mightypork.gamecore.gui.components.DynamicWidthComponent;
import mightypork.gamecore.gui.components.painters.TextPainter;
import mightypork.gamecore.input.InputSystem;
import mightypork.utils.math.AlignX;
import mightypork.utils.math.color.Color;
import mightypork.utils.math.color.pal.RGB;
@@ -46,7 +47,7 @@ public class TextButton extends ClickableComponent implements DynamicWidthCompon
protected void renderComponent()
{
if (isMouseOver()) {
if (InputSystem.isMouseButtonDown(0)) {
if (App.input().isMouseButtonDown(0)) {
offset.setTo(offsetUnder);
} else {
offset.setTo(hoverMove ? offsetOver : offsetPassive);
@@ -4,12 +4,12 @@ package mightypork.gamecore.gui.screens;
import java.util.ArrayList;
import java.util.Collection;
import mightypork.gamecore.backends.lwjgl.LwjglInputModule;
import mightypork.gamecore.core.App;
import mightypork.gamecore.graphics.Renderable;
import mightypork.gamecore.gui.components.layout.ConstraintLayout;
import mightypork.gamecore.gui.events.LayoutChangeListener;
import mightypork.gamecore.input.Edge;
import mightypork.gamecore.input.InputSystem;
import mightypork.gamecore.input.KeyBinder;
import mightypork.gamecore.input.KeyBindingPool;
import mightypork.gamecore.input.KeyStroke;
@@ -52,7 +52,7 @@ public abstract class Overlay extends BusNode implements Comparable<Overlay>, Up
public Overlay() {
this.mouse = InputSystem.getMousePos();
this.mouse = App.input().getMousePos();
this.root = new ConstraintLayout(App.gfx().getRect());
addChildClient(root);
@@ -0,0 +1,91 @@
package mightypork.gamecore.input;
import mightypork.gamecore.core.BackendModule;
import mightypork.utils.math.constraints.vect.Vect;
/**
* Abstract input module
*
* @author Ondřej Hruška (MightyPork)
*/
public abstract class InputModule extends BackendModule implements KeyBinder {
protected KeyBindingPool keybindings;
@Override
public final void init()
{
keybindings = new KeyBindingPool();
addChildClient(keybindings);
initDevices();
}
protected abstract void initDevices();
@Override
public void bindKey(KeyStroke stroke, Edge edge, Runnable task)
{
keybindings.bindKey(stroke, edge, task);
}
@Override
public void unbindKey(KeyStroke stroke)
{
keybindings.unbindKey(stroke);
}
/**
* Get absolute mouse position. Should always return the same Vect instance
* (use a VectVar or similar).
*
* @return mouse position
*/
public abstract Vect getMousePos();
/**
* Check if mouse is inside window
*
* @return true if mouse is inside window.
*/
public abstract boolean isMouseInside();
/**
* Trap mouse cursor in the window / release it
*
* @param grab true to grab, false to release
*/
public abstract void grabMouse(boolean grab);
/**
* Check if key is down (constant from the {@link Keys} class)
*
* @param key key to check
* @return is down
*/
public abstract boolean isKeyDown(int key);
/**
* Check mouse button state
*
* @param button button to test (0 left, 1 right, 2 middle)
* @return button is down
*/
public abstract boolean isMouseButtonDown(int button);
/**
* @return bit mask of active mod keys
*/
public abstract int getActiveModKeys();
}
+2 -12
View File
@@ -1,7 +1,6 @@
package mightypork.gamecore.input;
import mightypork.gamecore.input.events.InputReadyListener;
import mightypork.gamecore.input.events.KeyEvent;
import mightypork.gamecore.input.events.KeyEventHandler;
@@ -11,7 +10,7 @@ import mightypork.gamecore.input.events.KeyEventHandler;
*
* @author Ondřej Hruška (MightyPork)
*/
public class KeyBinding implements KeyEventHandler, InputReadyListener {
public class KeyBinding implements KeyEventHandler {
private final KeyStroke keystroke;
private Runnable handler;
@@ -28,8 +27,7 @@ public class KeyBinding implements KeyEventHandler, InputReadyListener {
this.keystroke = stroke;
this.handler = handler;
this.edge = edge;
if (InputSystem.isReady()) wasDown = stroke.isDown();
wasDown = stroke.isDown();
}
@@ -69,12 +67,4 @@ public class KeyBinding implements KeyEventHandler, InputReadyListener {
handler.run();
}
}
@Override
public void onInputReady()
{
wasDown = keystroke.isDown();
}
}
+5 -3
View File
@@ -1,6 +1,7 @@
package mightypork.gamecore.input;
import mightypork.gamecore.core.App;
import mightypork.utils.string.StringUtil;
import org.lwjgl.input.Keyboard;
@@ -28,9 +29,10 @@ public class KeyStroke {
}
// FIXME TODO can probably be immutable!
/**
* Change to...
* Change to...<br>
* (KeyStroke is mutable, so that upon changing it in Config, all existing
* key bindings are updated automatically.)
*
* @param key key code
* @param modmask modifiers
@@ -58,7 +60,7 @@ public class KeyStroke {
public boolean isDown()
{
boolean st = Keyboard.isKeyDown(key);
st &= (InputSystem.getActiveModKeys() == mod);
st &= (App.input().getActiveModKeys() == mod);
return st;
}
@@ -1,15 +0,0 @@
package mightypork.gamecore.input.events;
import mightypork.utils.eventbus.BusEvent;
public class InputReadyEvent extends BusEvent<InputReadyListener> {
@Override
protected void handleBy(InputReadyListener handler)
{
handler.onInputReady();
}
}
@@ -1,7 +0,0 @@
package mightypork.gamecore.input.events;
public interface InputReadyListener {
void onInputReady();
}
@@ -1,5 +1,6 @@
package mightypork.gamecore.resources.loading;
import mightypork.gamecore.resources.DeferredResource;
+2 -2
View File
@@ -4,6 +4,7 @@ package mightypork.rogue;
import junk.AppInitOptions;
import junk.BaseApp;
import mightypork.gamecore.backends.lwjgl.LwjglBackend;
import mightypork.gamecore.backends.lwjgl.LwjglInputModule;
import mightypork.gamecore.core.config.Config;
import mightypork.gamecore.core.events.MainLoopRequest;
import mightypork.gamecore.core.events.ShudownRequest;
@@ -15,7 +16,6 @@ import mightypork.gamecore.gui.events.ViewportChangeEvent;
import mightypork.gamecore.gui.events.ViewportChangeListener;
import mightypork.gamecore.gui.screens.ScreenRegistry;
import mightypork.gamecore.input.Edge;
import mightypork.gamecore.input.InputSystem;
import mightypork.gamecore.resources.Res;
import mightypork.rogue.RogueStateManager.RogueState;
import mightypork.rogue.events.RogueStateRequest;
@@ -104,7 +104,7 @@ public final class RogueApp extends BaseApp implements ViewportChangeListener, S
@Override
protected void initInputSystem(InputSystem input)
protected void initInputSystem(LwjglInputModule input)
{
// this will work only with reusable events (such as requests)
bindEventToKey(new FullscreenToggleRequest(), "global.fullscreen");
-2
View File
@@ -1,8 +1,6 @@
package mightypork.rogue;
public class RogueKeys implements KeySetup {
@Override
-2
View File
@@ -1,8 +1,6 @@
package mightypork.rogue;
public class RogueRoutes implements RouteSetup {
@Override
@@ -5,9 +5,9 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import mightypork.gamecore.backends.lwjgl.LwjglInputModule;
import mightypork.gamecore.core.config.Config;
import mightypork.gamecore.input.Edge;
import mightypork.gamecore.input.InputSystem;
import mightypork.gamecore.input.KeyBindingPool;
import mightypork.gamecore.input.KeyStroke;
import mightypork.gamecore.input.Keys;
@@ -103,7 +103,7 @@ public class MIPKeyboard extends MapInteractionPlugin implements DelegatingClien
if (mapView.plc.getPlayer().getMoveProgress() < 0.8) return false;
if (InputSystem.getActiveModKeys() != Keys.MOD_NONE) return false;
if (LwjglInputModule.getActiveModKeys() != Keys.MOD_NONE) return false;
for (int i = 0; i < 4; i++) {
if (keys[i].isDown()) {
@@ -1,7 +1,7 @@
package mightypork.rogue.world.gui.interaction;
import mightypork.gamecore.input.InputSystem;
import mightypork.gamecore.backends.lwjgl.LwjglInputModule;
import mightypork.rogue.world.entity.impl.EntityPlayer;
import mightypork.rogue.world.events.PlayerStepEndListener;
import mightypork.rogue.world.gui.MapView;
@@ -30,10 +30,10 @@ public class MIPMouse extends MapInteractionPlugin implements PlayerStepEndListe
{
if (isImmobile()) return;
final Vect pos = InputSystem.getMousePos();
final Vect pos = LwjglInputModule.getMousePos();
if (!pos.isInside(mapView)) return;
if (InputSystem.isMouseButtonDown(LEFT)) {
if (LwjglInputModule.isMouseButtonDown(LEFT)) {
if (mouseWalk(pos)) return;
if (mapView.plc.getPlayer().isMoving() && troToNav(pos)) return;
}
@@ -117,10 +117,10 @@ public class MIPMouse extends MapInteractionPlugin implements PlayerStepEndListe
{
if (isImmobile()) return;
final Vect pos = InputSystem.getMousePos();
final Vect pos = LwjglInputModule.getMousePos();
if (!pos.isInside(mapView)) return;
if (InputSystem.isMouseButtonDown(LEFT)) {
if (LwjglInputModule.isMouseButtonDown(LEFT)) {
if (mouseWalk(pos)) return;
if (mapView.plc.getPlayer().isMoving() && troToNav(pos)) return;
}