Merge KeyEventHandler to Reactive and replace old key event system with Reactive API

This commit is contained in:
2021-04-06 17:25:39 +02:00
parent 898bcc809c
commit 125d063af3
27 changed files with 200 additions and 146 deletions

View File

@@ -1,6 +1,8 @@
package com.bartlomiejpluta.base.api.entity;
import com.bartlomiejpluta.base.api.animation.Animated;
import com.bartlomiejpluta.base.api.event.Event;
import com.bartlomiejpluta.base.api.event.EventType;
import com.bartlomiejpluta.base.api.event.Reactive;
import com.bartlomiejpluta.base.api.map.layer.object.ObjectLayer;
import com.bartlomiejpluta.base.api.move.Direction;
@@ -9,6 +11,7 @@ import com.bartlomiejpluta.base.internal.logic.Updatable;
import com.bartlomiejpluta.base.internal.render.Renderable;
import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer;
public interface Entity extends Reactive, Movable, Animated, Renderable, Updatable {
@@ -39,4 +42,8 @@ public interface Entity extends Reactive, Movable, Animated, Renderable, Updatab
void setZIndex(int zIndex);
CompletableFuture<Void> performInstantAnimation();
<E extends Event> void addEventListener(EventType<E> type, Consumer<E> listener);
<E extends Event> void removeEventListener(EventType<E> type, Consumer<E> listener);
}

View File

@@ -2,4 +2,8 @@ package com.bartlomiejpluta.base.api.event;
public interface Event {
EventType<? extends Event> getType();
boolean isConsumed();
void consume();
}

View File

@@ -1,11 +1,5 @@
package com.bartlomiejpluta.base.api.event;
import java.util.function.Consumer;
public interface Reactive {
<E extends Event> void handleEvent(E event);
<E extends Event> void addEventListener(EventType<E> type, Consumer<E> listener);
<E extends Event> void removeEventListener(EventType<E> type, Consumer<E> listener);
}

View File

@@ -1,9 +1,9 @@
package com.bartlomiejpluta.base.api.gui;
import com.bartlomiejpluta.base.api.input.KeyEventHandler;
import com.bartlomiejpluta.base.api.event.Reactive;
import com.bartlomiejpluta.base.api.screen.Screen;
public interface Widget extends KeyEventHandler {
public interface Widget extends Reactive {
Widget getParent();
void setParent(Widget parent);

View File

@@ -62,7 +62,7 @@ public final class WindowManager extends BaseWidget {
requireNonNull(window, "Window cannot be null");
if (windows.isEmpty()) {
input.addKeyEventHandler(this);
input.addKeyEventHandler(this::forwardKeyEventToTopWindow);
}
windows.addLast(window);
@@ -70,6 +70,13 @@ public final class WindowManager extends BaseWidget {
window.onOpen(this);
}
private void forwardKeyEventToTopWindow(KeyEvent event) {
var topWindow = windows.peekLast();
if (topWindow != null) {
topWindow.handleEvent(event);
}
}
public void closeAll() {
// Use iterator to support removal from loop inside
@@ -88,7 +95,7 @@ public final class WindowManager extends BaseWidget {
window.onClose(this);
if (windows.isEmpty()) {
input.removeKeyEventHandler(this);
input.removeKeyEventHandler(this::forwardKeyEventToTopWindow);
}
}
@@ -114,14 +121,6 @@ public final class WindowManager extends BaseWidget {
}
}
@Override
public void handleKeyEvent(KeyEvent event) {
var topWindow = windows.peekLast();
if (topWindow != null) {
topWindow.handleKeyEvent(event);
}
}
private void drawWindow(Screen screen, Window window, GUI gui) {
switch (window.getWindowPosition()) {
case TOP -> window.setPosition(

View File

@@ -1,9 +1,11 @@
package com.bartlomiejpluta.base.api.input;
import java.util.function.Consumer;
public interface Input {
boolean isKeyPressed(Key key);
void addKeyEventHandler(KeyEventHandler handler);
void addKeyEventHandler(Consumer<KeyEvent> handler);
void removeKeyEventHandler(KeyEventHandler handler);
void removeKeyEventHandler(Consumer<KeyEvent> handler);
}

View File

@@ -1,7 +0,0 @@
package com.bartlomiejpluta.base.api.input;
public interface InputEvent {
boolean isConsumed();
void consume();
}

View File

@@ -1,7 +1,12 @@
package com.bartlomiejpluta.base.api.input;
public interface KeyEvent extends InputEvent {
import com.bartlomiejpluta.base.api.event.Event;
import com.bartlomiejpluta.base.api.event.EventType;
public interface KeyEvent extends Event {
Key getKey();
KeyAction getAction();
EventType<KeyEvent> TYPE = new EventType<>("KEY_EVENT");
}

View File

@@ -1,14 +0,0 @@
package com.bartlomiejpluta.base.api.input;
@FunctionalInterface
public interface KeyEventHandler {
void handleKeyEvent(KeyEvent event);
default void onKeyEventHandlerRegister() {
// do nothing
}
default void onKeyEventHandlerUnregister() {
// do nothing
}
}

View File

@@ -1,14 +1,14 @@
package com.bartlomiejpluta.base.api.map.layer.object;
import com.bartlomiejpluta.base.api.entity.Entity;
import com.bartlomiejpluta.base.api.event.Event;
import com.bartlomiejpluta.base.api.event.Reactive;
import com.bartlomiejpluta.base.api.map.layer.base.Layer;
import com.bartlomiejpluta.base.api.move.Movement;
import org.joml.Vector2ic;
import java.util.List;
public interface ObjectLayer extends Layer {
public interface ObjectLayer extends Layer, Reactive {
void addEntity(Entity entity);
void removeEntity(Entity entity);
@@ -24,6 +24,4 @@ public interface ObjectLayer extends Layer {
boolean isTileReachable(Vector2ic tileCoordinates);
void pushMovement(Movement movement);
void fireEvent(Event event);
}

View File

@@ -27,7 +27,7 @@ public final class EntityMovement implements Movement {
public boolean perform() {
var result = object.move(this);
if (result) {
object.getLayer().fireEvent(new MoveEvent(MoveEvent.Action.BEGIN, object, this));
object.getLayer().handleEvent(new MoveEvent(MoveEvent.Action.BEGIN, object, this));
}
return result;
@@ -40,6 +40,6 @@ public final class EntityMovement implements Movement {
@Override
public void onFinish() {
object.getLayer().fireEvent(new MoveEvent(MoveEvent.Action.END, object, this));
object.getLayer().handleEvent(new MoveEvent(MoveEvent.Action.END, object, this));
}
}

View File

@@ -2,12 +2,13 @@ package com.bartlomiejpluta.base.api.move;
import com.bartlomiejpluta.base.api.event.Event;
import com.bartlomiejpluta.base.api.event.EventType;
import com.bartlomiejpluta.base.lib.event.BaseEvent;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
@Getter
@RequiredArgsConstructor
public final class MoveEvent implements Event {
public final class MoveEvent extends BaseEvent {
public enum Action {BEGIN, END}
private final Action action;

View File

@@ -0,0 +1,15 @@
package com.bartlomiejpluta.base.lib.event;
import com.bartlomiejpluta.base.api.event.Event;
import lombok.Getter;
public abstract class BaseEvent implements Event {
@Getter
private boolean consumed = false;
@Override
public void consume() {
consumed = true;
}
}

View File

@@ -0,0 +1,52 @@
package com.bartlomiejpluta.base.lib.event;
import com.bartlomiejpluta.base.api.event.Event;
import com.bartlomiejpluta.base.api.event.EventType;
import com.bartlomiejpluta.base.api.event.Reactive;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Consumer;
public final class EventHandler implements Reactive {
private final Map<EventType<?>, ArrayList<Consumer<? extends Event>>> listeners = new HashMap<>();
@SuppressWarnings("unchecked")
@Override
public <E extends Event> void handleEvent(E event) {
var list = listeners.get(event.getType());
if (list != null) {
for (var i = list.size() - 1; i >= 0; --i) {
if (event.isConsumed()) {
return;
}
((Consumer<E>) list.get(i)).accept(event);
}
}
}
public <E extends Event> void addListener(EventType<E> type, Consumer<E> listener) {
var list = this.listeners.get(type);
if (list != null) {
list.add(listener);
} else {
list = new ArrayList<>();
list.add(listener);
listeners.put(type, list);
}
}
public <E extends Event> void removeListener(EventType<E> type, Consumer<E> listener) {
var list = this.listeners.get(type);
if (list != null) {
list.remove(listener);
if (list.isEmpty()) {
this.listeners.remove(type);
}
}
}
}

View File

@@ -1,9 +1,9 @@
package com.bartlomiejpluta.base.lib.gui;
import com.bartlomiejpluta.base.api.context.Context;
import com.bartlomiejpluta.base.api.event.Event;
import com.bartlomiejpluta.base.api.gui.Component;
import com.bartlomiejpluta.base.api.gui.GUI;
import com.bartlomiejpluta.base.api.input.KeyEvent;
import java.util.LinkedList;
import java.util.List;
@@ -92,13 +92,16 @@ public abstract class BaseContainer extends BaseComponent {
}
@Override
public void handleKeyEvent(KeyEvent event) {
public <E extends Event> void handleEvent(E event) {
// Populate event downstream
for (var child : children) {
if (event.isConsumed()) {
return;
}
child.handleKeyEvent(event);
}
child.handleEvent(event);
}
eventHandler.handleEvent(event);
}
}

View File

@@ -1,8 +1,12 @@
package com.bartlomiejpluta.base.lib.gui;
import com.bartlomiejpluta.base.api.event.Event;
import com.bartlomiejpluta.base.api.event.EventType;
import com.bartlomiejpluta.base.api.gui.SizeMode;
import com.bartlomiejpluta.base.api.gui.Widget;
import com.bartlomiejpluta.base.api.input.KeyEvent;
import com.bartlomiejpluta.base.lib.event.EventHandler;
import java.util.function.Consumer;
public abstract class BaseWidget implements Widget {
protected Widget parent;
@@ -26,6 +30,8 @@ public abstract class BaseWidget implements Widget {
protected float paddingBottom;
protected float paddingLeft;
protected final EventHandler eventHandler = new EventHandler();
protected abstract float getContentWidth();
protected abstract float getContentHeight();
@@ -277,7 +283,15 @@ public abstract class BaseWidget implements Widget {
}
@Override
public void handleKeyEvent(KeyEvent event) {
// Designed to be overridden if needed so
public <E extends Event> void handleEvent(E event) {
eventHandler.handleEvent(event);
}
protected <E extends Event> void addEventListener(EventType<E> type, Consumer<E> listener) {
eventHandler.addListener(type, listener);
}
protected <E extends Event> void removeEventListener(EventType<E> type, Consumer<E> listener) {
eventHandler.removeListener(type, listener);
}
}

View File

@@ -1,8 +1,8 @@
package com.bartlomiejpluta.base.lib.gui;
import com.bartlomiejpluta.base.api.context.Context;
import com.bartlomiejpluta.base.api.event.Event;
import com.bartlomiejpluta.base.api.gui.*;
import com.bartlomiejpluta.base.api.input.KeyEvent;
import com.bartlomiejpluta.base.api.screen.Screen;
import static java.util.Objects.requireNonNull;
@@ -59,8 +59,10 @@ public abstract class BaseWindow extends BaseWidget implements Window {
}
@Override
public void handleKeyEvent(KeyEvent event) {
content.handleKeyEvent(event);
public <E extends Event> void handleEvent(E event) {
if (content != null) {
content.handleEvent(event);
}
}
@Override

View File

@@ -1,6 +1,7 @@
package com.bartlomiejpluta.base.lib.gui;
import com.bartlomiejpluta.base.api.context.Context;
import com.bartlomiejpluta.base.api.event.Event;
import com.bartlomiejpluta.base.api.gui.GUI;
import com.bartlomiejpluta.base.api.input.Key;
import com.bartlomiejpluta.base.api.input.KeyAction;
@@ -14,6 +15,7 @@ public class HOptionChoice extends HScrollableLayout {
public HOptionChoice(Context context, GUI gui) {
super(context, gui);
addEventListener(KeyEvent.TYPE, this::switchOption);
}
@Override
@@ -26,16 +28,18 @@ public class HOptionChoice extends HScrollableLayout {
}
@Override
public void handleKeyEvent(KeyEvent event) {
if (children.isEmpty()) {
return;
public <E extends Event> void handleEvent(E event) {
if (selected < children.size()) {
children.get(selected).handleEvent(event);
}
// First we want to propagate it down tree
children.get(selected).handleKeyEvent(event);
if (!event.isConsumed()) {
eventHandler.handleEvent(event);
}
}
// If event is still not consumed, we try to consume it right here
if (event.isConsumed()) {
private void switchOption(KeyEvent event) {
if (children.isEmpty()) {
return;
}

View File

@@ -18,6 +18,7 @@ public class HScrollableLayout extends HLayout {
public HScrollableLayout(Context context, GUI gui) {
super(context, gui);
addEventListener(KeyEvent.TYPE, this::handleKeyEvent);
}
public float getActualScroll() {
@@ -83,10 +84,7 @@ public class HScrollableLayout extends HLayout {
super.setHeightMode(mode);
}
@Override
public void handleKeyEvent(KeyEvent event) {
super.handleKeyEvent(event);
private void handleKeyEvent(KeyEvent event) {
if (event.isConsumed()) {
return;
}

View File

@@ -1,6 +1,7 @@
package com.bartlomiejpluta.base.lib.gui;
import com.bartlomiejpluta.base.api.context.Context;
import com.bartlomiejpluta.base.api.event.Event;
import com.bartlomiejpluta.base.api.gui.GUI;
import com.bartlomiejpluta.base.api.input.Key;
import com.bartlomiejpluta.base.api.input.KeyAction;
@@ -14,6 +15,7 @@ public class VOptionChoice extends VScrollableLayout {
public VOptionChoice(Context context, GUI gui) {
super(context, gui);
addEventListener(KeyEvent.TYPE, this::switchOption);
}
@Override
@@ -26,16 +28,18 @@ public class VOptionChoice extends VScrollableLayout {
}
@Override
public void handleKeyEvent(KeyEvent event) {
if (children.isEmpty()) {
return;
public <E extends Event> void handleEvent(E event) {
if (selected < children.size()) {
children.get(selected).handleEvent(event);
}
// First we want to propagate it down tree
children.get(selected).handleKeyEvent(event);
if (!event.isConsumed()) {
eventHandler.handleEvent(event);
}
}
// If event is still not consumed, we try to consume it right here
if (event.isConsumed()) {
private void switchOption(KeyEvent event) {
if (children.isEmpty()) {
return;
}

View File

@@ -18,6 +18,7 @@ public class VScrollableLayout extends VLayout {
public VScrollableLayout(Context context, GUI gui) {
super(context, gui);
addEventListener(KeyEvent.TYPE, this::scroll);
}
public float getActualScroll() {
@@ -83,10 +84,7 @@ public class VScrollableLayout extends VLayout {
super.setHeightMode(mode);
}
@Override
public void handleKeyEvent(KeyEvent event) {
super.handleKeyEvent(event);
private void scroll(KeyEvent event) {
if (event.isConsumed()) {
return;
}

View File

@@ -5,18 +5,17 @@ import com.bartlomiejpluta.base.api.audio.Sound;
import com.bartlomiejpluta.base.api.camera.Camera;
import com.bartlomiejpluta.base.api.context.Context;
import com.bartlomiejpluta.base.api.entity.Entity;
import com.bartlomiejpluta.base.api.event.Reactive;
import com.bartlomiejpluta.base.api.gui.GUI;
import com.bartlomiejpluta.base.api.image.Image;
import com.bartlomiejpluta.base.api.input.Input;
import com.bartlomiejpluta.base.api.input.KeyEvent;
import com.bartlomiejpluta.base.api.input.KeyEventHandler;
import com.bartlomiejpluta.base.api.map.handler.MapHandler;
import com.bartlomiejpluta.base.api.runner.GameRunner;
import com.bartlomiejpluta.base.api.screen.Screen;
import com.bartlomiejpluta.base.engine.audio.manager.SoundManager;
import com.bartlomiejpluta.base.engine.core.engine.GameEngine;
import com.bartlomiejpluta.base.engine.database.service.DatabaseService;
import com.bartlomiejpluta.base.engine.error.AppException;
import com.bartlomiejpluta.base.engine.gui.manager.FontManager;
import com.bartlomiejpluta.base.engine.gui.manager.WidgetDefinitionManager;
import com.bartlomiejpluta.base.engine.gui.render.NanoVGGUI;
@@ -42,7 +41,7 @@ import java.util.List;
@Slf4j
@Builder
public class DefaultContext implements Context, KeyEventHandler {
public class DefaultContext implements Context {
@NonNull
private final GameEngine engine;
@@ -106,11 +105,23 @@ public class DefaultContext implements Context, KeyEventHandler {
this.input = input;
this.camera = camera;
input.addKeyEventHandler(this);
input.addKeyEventHandler(this::populateKeyEventToObjectLayers);
gameRunner.init(this);
}
private void populateKeyEventToObjectLayers(KeyEvent event) {
if (map == null || event.isConsumed()) {
return;
}
for (var layer : map.getLayers()) {
if (layer instanceof Reactive) {
((Reactive) layer).handleEvent(event);
}
}
}
@SneakyThrows
@Override
public void openMap(@NonNull String mapUid) {
@@ -237,24 +248,6 @@ public class DefaultContext implements Context, KeyEventHandler {
}
}
@Override
public void handleKeyEvent(KeyEvent event) {
if (map == null || event.isConsumed()) {
return;
}
for (var layer : map.getLayers()) {
if (layer instanceof KeyEventHandler) {
((KeyEventHandler) layer).handleKeyEvent(event);
}
}
}
@Override
public void onKeyEventHandlerUnregister() {
throw new AppException("Context cannot be unregistered");
}
@Override
public void update(float dt) {
gameRunner.update(dt);

View File

@@ -1,9 +1,9 @@
package com.bartlomiejpluta.base.engine.gui.widget;
import com.bartlomiejpluta.base.api.event.Event;
import com.bartlomiejpluta.base.api.gui.GUI;
import com.bartlomiejpluta.base.api.gui.SizeMode;
import com.bartlomiejpluta.base.api.gui.Widget;
import com.bartlomiejpluta.base.api.input.KeyEvent;
import com.bartlomiejpluta.base.api.screen.Screen;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
@@ -233,7 +233,7 @@ public class ScreenWidget implements Widget {
}
@Override
public void handleKeyEvent(KeyEvent event) {
public <E extends Event> void handleEvent(E event) {
throw new UnsupportedOperationException();
}

View File

@@ -1,5 +1,7 @@
package com.bartlomiejpluta.base.engine.ui.event;
import com.bartlomiejpluta.base.api.event.Event;
import com.bartlomiejpluta.base.api.event.EventType;
import com.bartlomiejpluta.base.api.input.Key;
import com.bartlomiejpluta.base.api.input.KeyAction;
import com.bartlomiejpluta.base.api.input.KeyEvent;
@@ -19,6 +21,11 @@ public class GLFWKeyEvent implements KeyEvent {
private final KeyAction action;
private boolean consumed;
@Override
public EventType<? extends Event> getType() {
return KeyEvent.TYPE;
}
@Override
public void consume() {
consumed = true;

View File

@@ -2,7 +2,7 @@ package com.bartlomiejpluta.base.engine.ui.model;
import com.bartlomiejpluta.base.api.input.Input;
import com.bartlomiejpluta.base.api.input.Key;
import com.bartlomiejpluta.base.api.input.KeyEventHandler;
import com.bartlomiejpluta.base.api.input.KeyEvent;
import com.bartlomiejpluta.base.api.screen.Screen;
import com.bartlomiejpluta.base.engine.ui.event.GLFWKeyEvent;
import lombok.NonNull;
@@ -10,6 +10,7 @@ import lombok.extern.slf4j.Slf4j;
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.*;
@@ -17,7 +18,7 @@ import static org.lwjgl.glfw.GLFW.*;
@Slf4j
public class GLFWInput implements Input {
private final long windowHandle;
private final Deque<KeyEventHandler> keyEventHandlers = new LinkedList<>();
private final Deque<Consumer<KeyEvent>> keyEventHandlers = new LinkedList<>();
public GLFWInput(@NonNull Screen screen) {
this.windowHandle = screen.getID();
@@ -39,7 +40,7 @@ public class GLFWInput implements Input {
return;
}
iterator.next().handleKeyEvent(event);
iterator.next().accept(event);
}
});
@@ -52,14 +53,12 @@ public class GLFWInput implements Input {
}
@Override
public void addKeyEventHandler(@NonNull KeyEventHandler handler) {
public void addKeyEventHandler(@NonNull Consumer<KeyEvent> handler) {
keyEventHandlers.addLast(handler);
handler.onKeyEventHandlerRegister();
}
@Override
public void removeKeyEventHandler(@NonNull KeyEventHandler handler) {
public void removeKeyEventHandler(@NonNull Consumer<KeyEvent> handler) {
keyEventHandlers.remove(handler);
handler.onKeyEventHandlerUnregister();
}
}

View File

@@ -12,6 +12,7 @@ import com.bartlomiejpluta.base.engine.core.gl.object.mesh.Mesh;
import com.bartlomiejpluta.base.engine.error.AppException;
import com.bartlomiejpluta.base.engine.world.entity.manager.EntitySetManager;
import com.bartlomiejpluta.base.engine.world.movement.MovableSprite;
import com.bartlomiejpluta.base.lib.event.EventHandler;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
@@ -19,7 +20,9 @@ import org.joml.Vector2f;
import org.joml.Vector2fc;
import org.joml.Vector2i;
import java.util.*;
import java.util.LinkedList;
import java.util.Map;
import java.util.Queue;
import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer;
@@ -34,7 +37,7 @@ public class DefaultEntity extends MovableSprite implements Entity {
private final Vector2f entityScale = new Vector2f(1, 1);
private Vector2fc entitySetSize;
private final Map<EventType<?>, List<Consumer<? extends Event>>> listeners = new HashMap<>();
private final EventHandler eventHandler = new EventHandler();
@Getter
@Setter
@@ -236,40 +239,19 @@ public class DefaultEntity extends MovableSprite implements Entity {
return entityScale.y;
}
@SuppressWarnings("unchecked")
@Override
public <E extends Event> void handleEvent(E event) {
var list = listeners.get(event.getType());
if (list != null) {
for (var listener : list) {
((Consumer<E>) listener).accept(event);
}
}
eventHandler.handleEvent(event);
}
@Override
public <E extends Event> void addEventListener(EventType<E> type, Consumer<E> listener) {
var list = this.listeners.get(type);
if (list != null) {
list.add(listener);
} else {
list = new ArrayList<>();
list.add(listener);
listeners.put(type, list);
}
eventHandler.addListener(type, listener);
}
@Override
public <E extends Event> void removeEventListener(EventType<E> type, Consumer<E> listener) {
var list = this.listeners.get(type);
if (list != null) {
list.remove(listener);
if (list.isEmpty()) {
this.listeners.remove(type);
}
}
eventHandler.removeListener(type, listener);
}
@Override

View File

@@ -4,8 +4,7 @@ import com.bartlomiejpluta.base.api.ai.NPC;
import com.bartlomiejpluta.base.api.camera.Camera;
import com.bartlomiejpluta.base.api.entity.Entity;
import com.bartlomiejpluta.base.api.event.Event;
import com.bartlomiejpluta.base.api.input.KeyEvent;
import com.bartlomiejpluta.base.api.input.KeyEventHandler;
import com.bartlomiejpluta.base.api.event.Reactive;
import com.bartlomiejpluta.base.api.map.layer.object.ObjectLayer;
import com.bartlomiejpluta.base.api.map.layer.object.PassageAbility;
import com.bartlomiejpluta.base.api.map.model.GameMap;
@@ -24,7 +23,7 @@ import java.util.Queue;
import static java.lang.Float.compare;
import static java.lang.Integer.compare;
public class DefaultObjectLayer extends BaseLayer implements ObjectLayer, KeyEventHandler {
public class DefaultObjectLayer extends BaseLayer implements ObjectLayer, Reactive {
@Getter
private final ArrayList<Entity> entities = new ArrayList<>();
@@ -156,14 +155,9 @@ public class DefaultObjectLayer extends BaseLayer implements ObjectLayer, KeyEve
return z == 0 ? compare(a.getPosition().y(), b.getPosition().y()) : z;
}
@Override
public void handleKeyEvent(KeyEvent event) {
}
@SuppressWarnings("ForLoopReplaceableByForEach")
@Override
public void fireEvent(Event event) {
public <E extends Event> void handleEvent(E event) {
// Disclaimer
// For the sake of an easy adding and removing
// entities from the entity.update() method inside