Implement event system scaffolding
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
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.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;
|
||||||
import com.bartlomiejpluta.base.api.move.Movable;
|
import com.bartlomiejpluta.base.api.move.Movable;
|
||||||
@@ -9,7 +10,7 @@ import com.bartlomiejpluta.base.internal.render.Renderable;
|
|||||||
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
public interface Entity extends Movable, Animated, Renderable, Updatable {
|
public interface Entity extends Reactive, Movable, Animated, Renderable, Updatable {
|
||||||
|
|
||||||
Direction getFaceDirection();
|
Direction getFaceDirection();
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
package com.bartlomiejpluta.base.api.entity;
|
|
||||||
|
|
||||||
import com.bartlomiejpluta.base.api.move.Movement;
|
|
||||||
|
|
||||||
public interface EntityStepInListener extends Entity {
|
|
||||||
void onEntityStepIn(Movement movement, Entity entity);
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
package com.bartlomiejpluta.base.api.entity;
|
|
||||||
|
|
||||||
import com.bartlomiejpluta.base.api.move.Movement;
|
|
||||||
|
|
||||||
public interface EntityStepOutListener extends Entity {
|
|
||||||
void onEntityStepOut(Movement movement, Entity entity);
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package com.bartlomiejpluta.base.api.event;
|
||||||
|
|
||||||
|
public interface Event {
|
||||||
|
EventType<? extends Event> getType();
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package com.bartlomiejpluta.base.api.event;
|
||||||
|
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
|
@EqualsAndHashCode
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public final class EventType<E extends Event> {
|
||||||
|
private final String type;
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
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);
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
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.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;
|
||||||
@@ -24,8 +25,5 @@ public interface ObjectLayer extends Layer {
|
|||||||
|
|
||||||
void pushMovement(Movement movement);
|
void pushMovement(Movement movement);
|
||||||
|
|
||||||
// Notifiers
|
void fireEvent(Event event);
|
||||||
void notifyEntityStepIn(Movement movement, Entity entity);
|
|
||||||
|
|
||||||
void notifyEntityStepOut(Movement movement, Entity entity);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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().notifyEntityStepOut(this, object);
|
object.getLayer().fireEvent(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().notifyEntityStepIn(this, object);
|
object.getLayer().fireEvent(new MoveEvent(MoveEvent.Action.END, object, this));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package com.bartlomiejpluta.base.api.move;
|
||||||
|
|
||||||
|
import com.bartlomiejpluta.base.api.event.Event;
|
||||||
|
import com.bartlomiejpluta.base.api.event.EventType;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public final class MoveEvent implements Event {
|
||||||
|
public enum Action {BEGIN, END}
|
||||||
|
|
||||||
|
private final Action action;
|
||||||
|
private final Movable movable;
|
||||||
|
private final Movement movement;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EventType<? extends Event> getType() {
|
||||||
|
return TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static EventType<MoveEvent> TYPE = new EventType<>("MOVE_EVENT");
|
||||||
|
}
|
||||||
@@ -2,6 +2,8 @@ package com.bartlomiejpluta.base.lib.entity;
|
|||||||
|
|
||||||
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.EventType;
|
||||||
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;
|
||||||
import com.bartlomiejpluta.base.api.move.EntityMovement;
|
import com.bartlomiejpluta.base.api.move.EntityMovement;
|
||||||
@@ -14,6 +16,7 @@ import org.joml.Vector2fc;
|
|||||||
import org.joml.Vector2ic;
|
import org.joml.Vector2ic;
|
||||||
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
public abstract class EntityDelegate implements Entity {
|
public abstract class EntityDelegate implements Entity {
|
||||||
protected final Entity entity;
|
protected final Entity entity;
|
||||||
@@ -267,6 +270,21 @@ public abstract class EntityDelegate implements Entity {
|
|||||||
entity.setZIndex(zIndex);
|
entity.setZIndex(zIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <E extends Event> void handleEvent(E event) {
|
||||||
|
entity.handleEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <E extends Event> void addEventListener(EventType<E> type, Consumer<E> listener) {
|
||||||
|
entity.addEventListener(type, listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <E extends Event> void removeEventListener(EventType<E> type, Consumer<E> listener) {
|
||||||
|
entity.removeEventListener(type, listener);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompletableFuture<Void> performInstantAnimation() {
|
public CompletableFuture<Void> performInstantAnimation() {
|
||||||
return entity.performInstantAnimation();
|
return entity.performInstantAnimation();
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package com.bartlomiejpluta.base.engine.world.entity.model;
|
package com.bartlomiejpluta.base.engine.world.entity.model;
|
||||||
|
|
||||||
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.EventType;
|
||||||
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;
|
||||||
import com.bartlomiejpluta.base.api.move.EntityMovement;
|
import com.bartlomiejpluta.base.api.move.EntityMovement;
|
||||||
@@ -17,10 +19,9 @@ import org.joml.Vector2f;
|
|||||||
import org.joml.Vector2fc;
|
import org.joml.Vector2fc;
|
||||||
import org.joml.Vector2i;
|
import org.joml.Vector2i;
|
||||||
|
|
||||||
import java.util.LinkedList;
|
import java.util.*;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Queue;
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import static java.util.Objects.requireNonNull;
|
import static java.util.Objects.requireNonNull;
|
||||||
|
|
||||||
@@ -33,6 +34,8 @@ 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<>();
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
private int zIndex = 0;
|
private int zIndex = 0;
|
||||||
@@ -233,6 +236,42 @@ public class DefaultEntity extends MovableSprite implements Entity {
|
|||||||
return entityScale.y;
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(float dt) {
|
public void update(float dt) {
|
||||||
super.update(dt);
|
super.update(dt);
|
||||||
|
|||||||
@@ -3,8 +3,7 @@ package com.bartlomiejpluta.base.engine.world.map.layer.object;
|
|||||||
import com.bartlomiejpluta.base.api.ai.NPC;
|
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.entity.EntityStepInListener;
|
import com.bartlomiejpluta.base.api.event.Event;
|
||||||
import com.bartlomiejpluta.base.api.entity.EntityStepOutListener;
|
|
||||||
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.input.KeyEventHandler;
|
||||||
import com.bartlomiejpluta.base.api.map.layer.object.ObjectLayer;
|
import com.bartlomiejpluta.base.api.map.layer.object.ObjectLayer;
|
||||||
@@ -20,7 +19,6 @@ import org.joml.Vector2ic;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Queue;
|
import java.util.Queue;
|
||||||
|
|
||||||
import static java.lang.Float.compare;
|
import static java.lang.Float.compare;
|
||||||
@@ -31,10 +29,6 @@ public class DefaultObjectLayer extends BaseLayer implements ObjectLayer, KeyEve
|
|||||||
@Getter
|
@Getter
|
||||||
private final ArrayList<Entity> entities = new ArrayList<>();
|
private final ArrayList<Entity> entities = new ArrayList<>();
|
||||||
|
|
||||||
private final List<EntityStepInListener> stepInListeners = new ArrayList<>();
|
|
||||||
private final List<EntityStepOutListener> stepOutListeners = new ArrayList<>();
|
|
||||||
private final List<KeyEventHandler> keyEventHandlers = new ArrayList<>();
|
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private final PassageAbility[][] passageMap;
|
private final PassageAbility[][] passageMap;
|
||||||
|
|
||||||
@@ -58,18 +52,6 @@ public class DefaultObjectLayer extends BaseLayer implements ObjectLayer, KeyEve
|
|||||||
layer.entities.remove(entity);
|
layer.entities.remove(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entity instanceof EntityStepInListener) {
|
|
||||||
stepInListeners.add((EntityStepInListener) entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (entity instanceof EntityStepOutListener) {
|
|
||||||
stepOutListeners.add((EntityStepOutListener) entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (entity instanceof KeyEventHandler) {
|
|
||||||
keyEventHandlers.add((KeyEventHandler) entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
entity.setStepSize(stepSize.x(), stepSize.y());
|
entity.setStepSize(stepSize.x(), stepSize.y());
|
||||||
entities.add(entity);
|
entities.add(entity);
|
||||||
|
|
||||||
@@ -80,18 +62,6 @@ public class DefaultObjectLayer extends BaseLayer implements ObjectLayer, KeyEve
|
|||||||
public void removeEntity(Entity entity) {
|
public void removeEntity(Entity entity) {
|
||||||
entities.remove(entity);
|
entities.remove(entity);
|
||||||
|
|
||||||
if (entity instanceof EntityStepInListener) {
|
|
||||||
stepInListeners.remove(entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (entity instanceof EntityStepOutListener) {
|
|
||||||
stepOutListeners.remove(entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (entity instanceof KeyEventHandler) {
|
|
||||||
keyEventHandlers.remove(entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
entity.onRemove(this);
|
entity.onRemove(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -149,7 +119,6 @@ public class DefaultObjectLayer extends BaseLayer implements ObjectLayer, KeyEve
|
|||||||
|
|
||||||
while (!movements.isEmpty()) {
|
while (!movements.isEmpty()) {
|
||||||
var movement = movements.poll();
|
var movement = movements.poll();
|
||||||
var from = movement.getFrom();
|
|
||||||
var to = movement.getTo();
|
var to = movement.getTo();
|
||||||
if (isTileReachable(to)) {
|
if (isTileReachable(to)) {
|
||||||
movement.perform();
|
movement.perform();
|
||||||
@@ -189,26 +158,19 @@ public class DefaultObjectLayer extends BaseLayer implements ObjectLayer, KeyEve
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleKeyEvent(KeyEvent event) {
|
public void handleKeyEvent(KeyEvent event) {
|
||||||
for (var handler : keyEventHandlers) {
|
|
||||||
if (event.isConsumed()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
handler.handleKeyEvent(event);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("ForLoopReplaceableByForEach")
|
||||||
@Override
|
@Override
|
||||||
public void notifyEntityStepIn(Movement movement, Entity entity) {
|
public void fireEvent(Event event) {
|
||||||
for (var listener : stepInListeners) {
|
// Disclaimer
|
||||||
listener.onEntityStepIn(movement, entity);
|
// For the sake of an easy adding and removing
|
||||||
}
|
// entities from the entity.update() method inside
|
||||||
}
|
// the loop, the loop itself has been implemented
|
||||||
|
// as plain old C-style for loop.
|
||||||
@Override
|
for (int i = 0; i < entities.size(); ++i) {
|
||||||
public void notifyEntityStepOut(Movement movement, Entity entity) {
|
entities.get(i).handleEvent(event);
|
||||||
for (var listener : stepOutListeners) {
|
|
||||||
listener.onEntityStepOut(movement, entity);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user