Merge KeyEventHandler to Reactive and replace old key event system with Reactive API
This commit is contained in:
@@ -1,6 +1,8 @@
|
|||||||
package com.bartlomiejpluta.base.api.entity;
|
package com.bartlomiejpluta.base.api.entity;
|
||||||
|
|
||||||
import com.bartlomiejpluta.base.api.animation.Animated;
|
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.event.Reactive;
|
||||||
import com.bartlomiejpluta.base.api.map.layer.object.ObjectLayer;
|
import com.bartlomiejpluta.base.api.map.layer.object.ObjectLayer;
|
||||||
import com.bartlomiejpluta.base.api.move.Direction;
|
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 com.bartlomiejpluta.base.internal.render.Renderable;
|
||||||
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
public interface Entity extends Reactive, Movable, Animated, Renderable, Updatable {
|
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);
|
void setZIndex(int zIndex);
|
||||||
|
|
||||||
CompletableFuture<Void> performInstantAnimation();
|
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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,4 +2,8 @@ package com.bartlomiejpluta.base.api.event;
|
|||||||
|
|
||||||
public interface Event {
|
public interface Event {
|
||||||
EventType<? extends Event> getType();
|
EventType<? extends Event> getType();
|
||||||
|
|
||||||
|
boolean isConsumed();
|
||||||
|
|
||||||
|
void consume();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,5 @@
|
|||||||
package com.bartlomiejpluta.base.api.event;
|
package com.bartlomiejpluta.base.api.event;
|
||||||
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
public interface Reactive {
|
public interface Reactive {
|
||||||
<E extends Event> void handleEvent(E event);
|
<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);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
package com.bartlomiejpluta.base.api.gui;
|
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;
|
import com.bartlomiejpluta.base.api.screen.Screen;
|
||||||
|
|
||||||
public interface Widget extends KeyEventHandler {
|
public interface Widget extends Reactive {
|
||||||
Widget getParent();
|
Widget getParent();
|
||||||
|
|
||||||
void setParent(Widget parent);
|
void setParent(Widget parent);
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ public final class WindowManager extends BaseWidget {
|
|||||||
requireNonNull(window, "Window cannot be null");
|
requireNonNull(window, "Window cannot be null");
|
||||||
|
|
||||||
if (windows.isEmpty()) {
|
if (windows.isEmpty()) {
|
||||||
input.addKeyEventHandler(this);
|
input.addKeyEventHandler(this::forwardKeyEventToTopWindow);
|
||||||
}
|
}
|
||||||
|
|
||||||
windows.addLast(window);
|
windows.addLast(window);
|
||||||
@@ -70,6 +70,13 @@ public final class WindowManager extends BaseWidget {
|
|||||||
window.onOpen(this);
|
window.onOpen(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void forwardKeyEventToTopWindow(KeyEvent event) {
|
||||||
|
var topWindow = windows.peekLast();
|
||||||
|
if (topWindow != null) {
|
||||||
|
topWindow.handleEvent(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void closeAll() {
|
public void closeAll() {
|
||||||
|
|
||||||
// Use iterator to support removal from loop inside
|
// Use iterator to support removal from loop inside
|
||||||
@@ -88,7 +95,7 @@ public final class WindowManager extends BaseWidget {
|
|||||||
window.onClose(this);
|
window.onClose(this);
|
||||||
|
|
||||||
if (windows.isEmpty()) {
|
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) {
|
private void drawWindow(Screen screen, Window window, GUI gui) {
|
||||||
switch (window.getWindowPosition()) {
|
switch (window.getWindowPosition()) {
|
||||||
case TOP -> window.setPosition(
|
case TOP -> window.setPosition(
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
package com.bartlomiejpluta.base.api.input;
|
package com.bartlomiejpluta.base.api.input;
|
||||||
|
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
public interface Input {
|
public interface Input {
|
||||||
boolean isKeyPressed(Key key);
|
boolean isKeyPressed(Key key);
|
||||||
|
|
||||||
void addKeyEventHandler(KeyEventHandler handler);
|
void addKeyEventHandler(Consumer<KeyEvent> handler);
|
||||||
|
|
||||||
void removeKeyEventHandler(KeyEventHandler handler);
|
void removeKeyEventHandler(Consumer<KeyEvent> handler);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
package com.bartlomiejpluta.base.api.input;
|
|
||||||
|
|
||||||
public interface InputEvent {
|
|
||||||
boolean isConsumed();
|
|
||||||
|
|
||||||
void consume();
|
|
||||||
}
|
|
||||||
@@ -1,7 +1,12 @@
|
|||||||
package com.bartlomiejpluta.base.api.input;
|
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();
|
Key getKey();
|
||||||
|
|
||||||
KeyAction getAction();
|
KeyAction getAction();
|
||||||
|
|
||||||
|
EventType<KeyEvent> TYPE = new EventType<>("KEY_EVENT");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,14 +1,14 @@
|
|||||||
package com.bartlomiejpluta.base.api.map.layer.object;
|
package com.bartlomiejpluta.base.api.map.layer.object;
|
||||||
|
|
||||||
import com.bartlomiejpluta.base.api.entity.Entity;
|
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.map.layer.base.Layer;
|
||||||
import com.bartlomiejpluta.base.api.move.Movement;
|
import com.bartlomiejpluta.base.api.move.Movement;
|
||||||
import org.joml.Vector2ic;
|
import org.joml.Vector2ic;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public interface ObjectLayer extends Layer {
|
public interface ObjectLayer extends Layer, Reactive {
|
||||||
void addEntity(Entity entity);
|
void addEntity(Entity entity);
|
||||||
|
|
||||||
void removeEntity(Entity entity);
|
void removeEntity(Entity entity);
|
||||||
@@ -24,6 +24,4 @@ public interface ObjectLayer extends Layer {
|
|||||||
boolean isTileReachable(Vector2ic tileCoordinates);
|
boolean isTileReachable(Vector2ic tileCoordinates);
|
||||||
|
|
||||||
void pushMovement(Movement movement);
|
void pushMovement(Movement movement);
|
||||||
|
|
||||||
void fireEvent(Event event);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ public final class EntityMovement implements Movement {
|
|||||||
public boolean perform() {
|
public boolean perform() {
|
||||||
var result = object.move(this);
|
var result = object.move(this);
|
||||||
if (result) {
|
if (result) {
|
||||||
object.getLayer().fireEvent(new MoveEvent(MoveEvent.Action.BEGIN, object, this));
|
object.getLayer().handleEvent(new MoveEvent(MoveEvent.Action.BEGIN, object, this));
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@@ -40,6 +40,6 @@ public final class EntityMovement implements Movement {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFinish() {
|
public void onFinish() {
|
||||||
object.getLayer().fireEvent(new MoveEvent(MoveEvent.Action.END, object, this));
|
object.getLayer().handleEvent(new MoveEvent(MoveEvent.Action.END, object, this));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,12 +2,13 @@ package com.bartlomiejpluta.base.api.move;
|
|||||||
|
|
||||||
import com.bartlomiejpluta.base.api.event.Event;
|
import com.bartlomiejpluta.base.api.event.Event;
|
||||||
import com.bartlomiejpluta.base.api.event.EventType;
|
import com.bartlomiejpluta.base.api.event.EventType;
|
||||||
|
import com.bartlomiejpluta.base.lib.event.BaseEvent;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public final class MoveEvent implements Event {
|
public final class MoveEvent extends BaseEvent {
|
||||||
public enum Action {BEGIN, END}
|
public enum Action {BEGIN, END}
|
||||||
|
|
||||||
private final Action action;
|
private final Action action;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
package com.bartlomiejpluta.base.lib.gui;
|
package com.bartlomiejpluta.base.lib.gui;
|
||||||
|
|
||||||
import com.bartlomiejpluta.base.api.context.Context;
|
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.Component;
|
||||||
import com.bartlomiejpluta.base.api.gui.GUI;
|
import com.bartlomiejpluta.base.api.gui.GUI;
|
||||||
import com.bartlomiejpluta.base.api.input.KeyEvent;
|
|
||||||
|
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -92,13 +92,16 @@ public abstract class BaseContainer extends BaseComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleKeyEvent(KeyEvent event) {
|
public <E extends Event> void handleEvent(E event) {
|
||||||
|
// Populate event downstream
|
||||||
for (var child : children) {
|
for (var child : children) {
|
||||||
if (event.isConsumed()) {
|
if (event.isConsumed()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
child.handleKeyEvent(event);
|
child.handleEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
eventHandler.handleEvent(event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,12 @@
|
|||||||
package com.bartlomiejpluta.base.lib.gui;
|
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.SizeMode;
|
||||||
import com.bartlomiejpluta.base.api.gui.Widget;
|
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 {
|
public abstract class BaseWidget implements Widget {
|
||||||
protected Widget parent;
|
protected Widget parent;
|
||||||
@@ -26,6 +30,8 @@ public abstract class BaseWidget implements Widget {
|
|||||||
protected float paddingBottom;
|
protected float paddingBottom;
|
||||||
protected float paddingLeft;
|
protected float paddingLeft;
|
||||||
|
|
||||||
|
protected final EventHandler eventHandler = new EventHandler();
|
||||||
|
|
||||||
protected abstract float getContentWidth();
|
protected abstract float getContentWidth();
|
||||||
|
|
||||||
protected abstract float getContentHeight();
|
protected abstract float getContentHeight();
|
||||||
@@ -277,7 +283,15 @@ public abstract class BaseWidget implements Widget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleKeyEvent(KeyEvent event) {
|
public <E extends Event> void handleEvent(E event) {
|
||||||
// Designed to be overridden if needed so
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
package com.bartlomiejpluta.base.lib.gui;
|
package com.bartlomiejpluta.base.lib.gui;
|
||||||
|
|
||||||
import com.bartlomiejpluta.base.api.context.Context;
|
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.gui.*;
|
||||||
import com.bartlomiejpluta.base.api.input.KeyEvent;
|
|
||||||
import com.bartlomiejpluta.base.api.screen.Screen;
|
import com.bartlomiejpluta.base.api.screen.Screen;
|
||||||
|
|
||||||
import static java.util.Objects.requireNonNull;
|
import static java.util.Objects.requireNonNull;
|
||||||
@@ -59,8 +59,10 @@ public abstract class BaseWindow extends BaseWidget implements Window {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleKeyEvent(KeyEvent event) {
|
public <E extends Event> void handleEvent(E event) {
|
||||||
content.handleKeyEvent(event);
|
if (content != null) {
|
||||||
|
content.handleEvent(event);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.bartlomiejpluta.base.lib.gui;
|
package com.bartlomiejpluta.base.lib.gui;
|
||||||
|
|
||||||
import com.bartlomiejpluta.base.api.context.Context;
|
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.gui.GUI;
|
||||||
import com.bartlomiejpluta.base.api.input.Key;
|
import com.bartlomiejpluta.base.api.input.Key;
|
||||||
import com.bartlomiejpluta.base.api.input.KeyAction;
|
import com.bartlomiejpluta.base.api.input.KeyAction;
|
||||||
@@ -14,6 +15,7 @@ public class HOptionChoice extends HScrollableLayout {
|
|||||||
|
|
||||||
public HOptionChoice(Context context, GUI gui) {
|
public HOptionChoice(Context context, GUI gui) {
|
||||||
super(context, gui);
|
super(context, gui);
|
||||||
|
addEventListener(KeyEvent.TYPE, this::switchOption);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -26,16 +28,18 @@ public class HOptionChoice extends HScrollableLayout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleKeyEvent(KeyEvent event) {
|
public <E extends Event> void handleEvent(E event) {
|
||||||
if (children.isEmpty()) {
|
if (selected < children.size()) {
|
||||||
return;
|
children.get(selected).handleEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
// First we want to propagate it down tree
|
if (!event.isConsumed()) {
|
||||||
children.get(selected).handleKeyEvent(event);
|
eventHandler.handleEvent(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// If event is still not consumed, we try to consume it right here
|
private void switchOption(KeyEvent event) {
|
||||||
if (event.isConsumed()) {
|
if (children.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ public class HScrollableLayout extends HLayout {
|
|||||||
|
|
||||||
public HScrollableLayout(Context context, GUI gui) {
|
public HScrollableLayout(Context context, GUI gui) {
|
||||||
super(context, gui);
|
super(context, gui);
|
||||||
|
addEventListener(KeyEvent.TYPE, this::handleKeyEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getActualScroll() {
|
public float getActualScroll() {
|
||||||
@@ -83,10 +84,7 @@ public class HScrollableLayout extends HLayout {
|
|||||||
super.setHeightMode(mode);
|
super.setHeightMode(mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private void handleKeyEvent(KeyEvent event) {
|
||||||
public void handleKeyEvent(KeyEvent event) {
|
|
||||||
super.handleKeyEvent(event);
|
|
||||||
|
|
||||||
if (event.isConsumed()) {
|
if (event.isConsumed()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.bartlomiejpluta.base.lib.gui;
|
package com.bartlomiejpluta.base.lib.gui;
|
||||||
|
|
||||||
import com.bartlomiejpluta.base.api.context.Context;
|
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.gui.GUI;
|
||||||
import com.bartlomiejpluta.base.api.input.Key;
|
import com.bartlomiejpluta.base.api.input.Key;
|
||||||
import com.bartlomiejpluta.base.api.input.KeyAction;
|
import com.bartlomiejpluta.base.api.input.KeyAction;
|
||||||
@@ -14,6 +15,7 @@ public class VOptionChoice extends VScrollableLayout {
|
|||||||
|
|
||||||
public VOptionChoice(Context context, GUI gui) {
|
public VOptionChoice(Context context, GUI gui) {
|
||||||
super(context, gui);
|
super(context, gui);
|
||||||
|
addEventListener(KeyEvent.TYPE, this::switchOption);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -26,16 +28,18 @@ public class VOptionChoice extends VScrollableLayout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleKeyEvent(KeyEvent event) {
|
public <E extends Event> void handleEvent(E event) {
|
||||||
if (children.isEmpty()) {
|
if (selected < children.size()) {
|
||||||
return;
|
children.get(selected).handleEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
// First we want to propagate it down tree
|
if (!event.isConsumed()) {
|
||||||
children.get(selected).handleKeyEvent(event);
|
eventHandler.handleEvent(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// If event is still not consumed, we try to consume it right here
|
private void switchOption(KeyEvent event) {
|
||||||
if (event.isConsumed()) {
|
if (children.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ public class VScrollableLayout extends VLayout {
|
|||||||
|
|
||||||
public VScrollableLayout(Context context, GUI gui) {
|
public VScrollableLayout(Context context, GUI gui) {
|
||||||
super(context, gui);
|
super(context, gui);
|
||||||
|
addEventListener(KeyEvent.TYPE, this::scroll);
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getActualScroll() {
|
public float getActualScroll() {
|
||||||
@@ -83,10 +84,7 @@ public class VScrollableLayout extends VLayout {
|
|||||||
super.setHeightMode(mode);
|
super.setHeightMode(mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private void scroll(KeyEvent event) {
|
||||||
public void handleKeyEvent(KeyEvent event) {
|
|
||||||
super.handleKeyEvent(event);
|
|
||||||
|
|
||||||
if (event.isConsumed()) {
|
if (event.isConsumed()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,18 +5,17 @@ import com.bartlomiejpluta.base.api.audio.Sound;
|
|||||||
import com.bartlomiejpluta.base.api.camera.Camera;
|
import com.bartlomiejpluta.base.api.camera.Camera;
|
||||||
import com.bartlomiejpluta.base.api.context.Context;
|
import com.bartlomiejpluta.base.api.context.Context;
|
||||||
import com.bartlomiejpluta.base.api.entity.Entity;
|
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.gui.GUI;
|
||||||
import com.bartlomiejpluta.base.api.image.Image;
|
import com.bartlomiejpluta.base.api.image.Image;
|
||||||
import com.bartlomiejpluta.base.api.input.Input;
|
import com.bartlomiejpluta.base.api.input.Input;
|
||||||
import com.bartlomiejpluta.base.api.input.KeyEvent;
|
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.map.handler.MapHandler;
|
||||||
import com.bartlomiejpluta.base.api.runner.GameRunner;
|
import com.bartlomiejpluta.base.api.runner.GameRunner;
|
||||||
import com.bartlomiejpluta.base.api.screen.Screen;
|
import com.bartlomiejpluta.base.api.screen.Screen;
|
||||||
import com.bartlomiejpluta.base.engine.audio.manager.SoundManager;
|
import com.bartlomiejpluta.base.engine.audio.manager.SoundManager;
|
||||||
import com.bartlomiejpluta.base.engine.core.engine.GameEngine;
|
import com.bartlomiejpluta.base.engine.core.engine.GameEngine;
|
||||||
import com.bartlomiejpluta.base.engine.database.service.DatabaseService;
|
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.FontManager;
|
||||||
import com.bartlomiejpluta.base.engine.gui.manager.WidgetDefinitionManager;
|
import com.bartlomiejpluta.base.engine.gui.manager.WidgetDefinitionManager;
|
||||||
import com.bartlomiejpluta.base.engine.gui.render.NanoVGGUI;
|
import com.bartlomiejpluta.base.engine.gui.render.NanoVGGUI;
|
||||||
@@ -42,7 +41,7 @@ import java.util.List;
|
|||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Builder
|
@Builder
|
||||||
public class DefaultContext implements Context, KeyEventHandler {
|
public class DefaultContext implements Context {
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
private final GameEngine engine;
|
private final GameEngine engine;
|
||||||
@@ -106,11 +105,23 @@ public class DefaultContext implements Context, KeyEventHandler {
|
|||||||
this.input = input;
|
this.input = input;
|
||||||
this.camera = camera;
|
this.camera = camera;
|
||||||
|
|
||||||
input.addKeyEventHandler(this);
|
input.addKeyEventHandler(this::populateKeyEventToObjectLayers);
|
||||||
|
|
||||||
gameRunner.init(this);
|
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
|
@SneakyThrows
|
||||||
@Override
|
@Override
|
||||||
public void openMap(@NonNull String mapUid) {
|
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
|
@Override
|
||||||
public void update(float dt) {
|
public void update(float dt) {
|
||||||
gameRunner.update(dt);
|
gameRunner.update(dt);
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
package com.bartlomiejpluta.base.engine.gui.widget;
|
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.GUI;
|
||||||
import com.bartlomiejpluta.base.api.gui.SizeMode;
|
import com.bartlomiejpluta.base.api.gui.SizeMode;
|
||||||
import com.bartlomiejpluta.base.api.gui.Widget;
|
import com.bartlomiejpluta.base.api.gui.Widget;
|
||||||
import com.bartlomiejpluta.base.api.input.KeyEvent;
|
|
||||||
import com.bartlomiejpluta.base.api.screen.Screen;
|
import com.bartlomiejpluta.base.api.screen.Screen;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
@@ -233,7 +233,7 @@ public class ScreenWidget implements Widget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleKeyEvent(KeyEvent event) {
|
public <E extends Event> void handleEvent(E event) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package com.bartlomiejpluta.base.engine.ui.event;
|
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.Key;
|
||||||
import com.bartlomiejpluta.base.api.input.KeyAction;
|
import com.bartlomiejpluta.base.api.input.KeyAction;
|
||||||
import com.bartlomiejpluta.base.api.input.KeyEvent;
|
import com.bartlomiejpluta.base.api.input.KeyEvent;
|
||||||
@@ -19,6 +21,11 @@ public class GLFWKeyEvent implements KeyEvent {
|
|||||||
private final KeyAction action;
|
private final KeyAction action;
|
||||||
private boolean consumed;
|
private boolean consumed;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EventType<? extends Event> getType() {
|
||||||
|
return KeyEvent.TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void consume() {
|
public void consume() {
|
||||||
consumed = true;
|
consumed = true;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package com.bartlomiejpluta.base.engine.ui.model;
|
|||||||
|
|
||||||
import com.bartlomiejpluta.base.api.input.Input;
|
import com.bartlomiejpluta.base.api.input.Input;
|
||||||
import com.bartlomiejpluta.base.api.input.Key;
|
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.api.screen.Screen;
|
||||||
import com.bartlomiejpluta.base.engine.ui.event.GLFWKeyEvent;
|
import com.bartlomiejpluta.base.engine.ui.event.GLFWKeyEvent;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
@@ -10,6 +10,7 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
|
|
||||||
import java.util.Deque;
|
import java.util.Deque;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import static com.bartlomiejpluta.base.engine.ui.event.GLFWKeyEvent.glfwCode;
|
import static com.bartlomiejpluta.base.engine.ui.event.GLFWKeyEvent.glfwCode;
|
||||||
import static org.lwjgl.glfw.GLFW.*;
|
import static org.lwjgl.glfw.GLFW.*;
|
||||||
@@ -17,7 +18,7 @@ import static org.lwjgl.glfw.GLFW.*;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
public class GLFWInput implements Input {
|
public class GLFWInput implements Input {
|
||||||
private final long windowHandle;
|
private final long windowHandle;
|
||||||
private final Deque<KeyEventHandler> keyEventHandlers = new LinkedList<>();
|
private final Deque<Consumer<KeyEvent>> keyEventHandlers = new LinkedList<>();
|
||||||
|
|
||||||
public GLFWInput(@NonNull Screen screen) {
|
public GLFWInput(@NonNull Screen screen) {
|
||||||
this.windowHandle = screen.getID();
|
this.windowHandle = screen.getID();
|
||||||
@@ -39,7 +40,7 @@ public class GLFWInput implements Input {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
iterator.next().handleKeyEvent(event);
|
iterator.next().accept(event);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -52,14 +53,12 @@ public class GLFWInput implements Input {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addKeyEventHandler(@NonNull KeyEventHandler handler) {
|
public void addKeyEventHandler(@NonNull Consumer<KeyEvent> handler) {
|
||||||
keyEventHandlers.addLast(handler);
|
keyEventHandlers.addLast(handler);
|
||||||
handler.onKeyEventHandlerRegister();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeKeyEventHandler(@NonNull KeyEventHandler handler) {
|
public void removeKeyEventHandler(@NonNull Consumer<KeyEvent> handler) {
|
||||||
keyEventHandlers.remove(handler);
|
keyEventHandlers.remove(handler);
|
||||||
handler.onKeyEventHandlerUnregister();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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.error.AppException;
|
||||||
import com.bartlomiejpluta.base.engine.world.entity.manager.EntitySetManager;
|
import com.bartlomiejpluta.base.engine.world.entity.manager.EntitySetManager;
|
||||||
import com.bartlomiejpluta.base.engine.world.movement.MovableSprite;
|
import com.bartlomiejpluta.base.engine.world.movement.MovableSprite;
|
||||||
|
import com.bartlomiejpluta.base.lib.event.EventHandler;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
@@ -19,7 +20,9 @@ import org.joml.Vector2f;
|
|||||||
import org.joml.Vector2fc;
|
import org.joml.Vector2fc;
|
||||||
import org.joml.Vector2i;
|
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.concurrent.CompletableFuture;
|
||||||
import java.util.function.Consumer;
|
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 final Vector2f entityScale = new Vector2f(1, 1);
|
||||||
private Vector2fc entitySetSize;
|
private Vector2fc entitySetSize;
|
||||||
|
|
||||||
private final Map<EventType<?>, List<Consumer<? extends Event>>> listeners = new HashMap<>();
|
private final EventHandler eventHandler = new EventHandler();
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
@@ -236,40 +239,19 @@ public class DefaultEntity extends MovableSprite implements Entity {
|
|||||||
return entityScale.y;
|
return entityScale.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
@Override
|
@Override
|
||||||
public <E extends Event> void handleEvent(E event) {
|
public <E extends Event> void handleEvent(E event) {
|
||||||
var list = listeners.get(event.getType());
|
eventHandler.handleEvent(event);
|
||||||
if (list != null) {
|
|
||||||
for (var listener : list) {
|
|
||||||
((Consumer<E>) listener).accept(event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <E extends Event> void addEventListener(EventType<E> type, Consumer<E> listener) {
|
public <E extends Event> void addEventListener(EventType<E> type, Consumer<E> listener) {
|
||||||
var list = this.listeners.get(type);
|
eventHandler.addListener(type, listener);
|
||||||
|
|
||||||
if (list != null) {
|
|
||||||
list.add(listener);
|
|
||||||
} else {
|
|
||||||
list = new ArrayList<>();
|
|
||||||
list.add(listener);
|
|
||||||
listeners.put(type, list);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <E extends Event> void removeEventListener(EventType<E> type, Consumer<E> listener) {
|
public <E extends Event> void removeEventListener(EventType<E> type, Consumer<E> listener) {
|
||||||
var list = this.listeners.get(type);
|
eventHandler.removeListener(type, listener);
|
||||||
|
|
||||||
if (list != null) {
|
|
||||||
list.remove(listener);
|
|
||||||
if (list.isEmpty()) {
|
|
||||||
this.listeners.remove(type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -4,8 +4,7 @@ import com.bartlomiejpluta.base.api.ai.NPC;
|
|||||||
import com.bartlomiejpluta.base.api.camera.Camera;
|
import com.bartlomiejpluta.base.api.camera.Camera;
|
||||||
import com.bartlomiejpluta.base.api.entity.Entity;
|
import com.bartlomiejpluta.base.api.entity.Entity;
|
||||||
import com.bartlomiejpluta.base.api.event.Event;
|
import com.bartlomiejpluta.base.api.event.Event;
|
||||||
import com.bartlomiejpluta.base.api.input.KeyEvent;
|
import com.bartlomiejpluta.base.api.event.Reactive;
|
||||||
import com.bartlomiejpluta.base.api.input.KeyEventHandler;
|
|
||||||
import com.bartlomiejpluta.base.api.map.layer.object.ObjectLayer;
|
import com.bartlomiejpluta.base.api.map.layer.object.ObjectLayer;
|
||||||
import com.bartlomiejpluta.base.api.map.layer.object.PassageAbility;
|
import com.bartlomiejpluta.base.api.map.layer.object.PassageAbility;
|
||||||
import com.bartlomiejpluta.base.api.map.model.GameMap;
|
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.Float.compare;
|
||||||
import static java.lang.Integer.compare;
|
import static java.lang.Integer.compare;
|
||||||
|
|
||||||
public class DefaultObjectLayer extends BaseLayer implements ObjectLayer, KeyEventHandler {
|
public class DefaultObjectLayer extends BaseLayer implements ObjectLayer, Reactive {
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private final ArrayList<Entity> entities = new ArrayList<>();
|
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;
|
return z == 0 ? compare(a.getPosition().y(), b.getPosition().y()) : z;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handleKeyEvent(KeyEvent event) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("ForLoopReplaceableByForEach")
|
@SuppressWarnings("ForLoopReplaceableByForEach")
|
||||||
@Override
|
@Override
|
||||||
public void fireEvent(Event event) {
|
public <E extends Event> void handleEvent(E event) {
|
||||||
// Disclaimer
|
// Disclaimer
|
||||||
// For the sake of an easy adding and removing
|
// For the sake of an easy adding and removing
|
||||||
// entities from the entity.update() method inside
|
// entities from the entity.update() method inside
|
||||||
|
|||||||
Reference in New Issue
Block a user