summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Vink <mike1994vink@gmail.com>2021-07-21 12:46:35 +0200
committerMike Vink <mike1994vink@gmail.com>2021-07-21 12:46:35 +0200
commitda613e94970da31409464c81740162f9bd7c7831 (patch)
treee16a81890f5e43b771ae8a227580e9a535b82652
parentf4dc48cd8359d5b8da35f678ae6630c5c4427769 (diff)
feat(): start making heartbeatquery
-rw-r--r--api/src/main/java/akkamon/api/EventSocket.java12
-rw-r--r--api/src/main/java/akkamon/api/MessagingEngine.java61
-rw-r--r--api/src/main/java/akkamon/api/models/Event.java2
-rw-r--r--api/src/main/java/akkamon/api/models/EventType.java10
-rw-r--r--api/src/main/java/akkamon/api/models/HeartBeatEvent.java4
-rw-r--r--client/src/GridPhysics.ts18
-rw-r--r--client/src/client.ts4
-rw-r--r--client/src/events.ts25
-rw-r--r--client/src/sprite.ts4
-rw-r--r--domain/src/main/java/akkamon/domain/AkkamonMessageEngine.java6
-rw-r--r--domain/src/main/java/akkamon/domain/AkkamonNexus.java152
-rw-r--r--domain/src/main/java/akkamon/domain/AkkamonSession.java4
-rw-r--r--domain/src/main/java/akkamon/domain/Direction.java3
-rw-r--r--domain/src/main/java/akkamon/domain/SceneTrainerGroup.java88
-rw-r--r--domain/src/main/java/akkamon/domain/TilePos.java10
-rw-r--r--domain/src/main/java/akkamon/domain/Trainer.java34
16 files changed, 391 insertions, 46 deletions
diff --git a/api/src/main/java/akkamon/api/EventSocket.java b/api/src/main/java/akkamon/api/EventSocket.java
index 7b9619a..f800ab3 100644
--- a/api/src/main/java/akkamon/api/EventSocket.java
+++ b/api/src/main/java/akkamon/api/EventSocket.java
@@ -10,6 +10,7 @@ import java.util.concurrent.CountDownLatch;
public class EventSocket extends WebSocketAdapter implements AkkamonSession {
private final CountDownLatch closureLatch = new CountDownLatch(1);
+ private String trainerId;
@Override
public void onWebSocketConnect(Session sess)
@@ -22,7 +23,6 @@ public class EventSocket extends WebSocketAdapter implements AkkamonSession {
public void onWebSocketText(String message)
{
super.onWebSocketText(message);
- System.out.println("Received TEXT message: " + message);
App.messagingEngine.incoming(this, message);
}
@@ -56,4 +56,14 @@ public class EventSocket extends WebSocketAdapter implements AkkamonSession {
e.printStackTrace();
}
}
+
+ @Override
+ public void setTrainerId(String trainerId) {
+ this.trainerId = trainerId;
+ }
+
+ @Override
+ public String getTrainerId() {
+ return trainerId;
+ }
}
diff --git a/api/src/main/java/akkamon/api/MessagingEngine.java b/api/src/main/java/akkamon/api/MessagingEngine.java
index e888d8b..17b8f08 100644
--- a/api/src/main/java/akkamon/api/MessagingEngine.java
+++ b/api/src/main/java/akkamon/api/MessagingEngine.java
@@ -3,7 +3,6 @@ package akkamon.api;
import akka.actor.typed.ActorRef;
import akka.actor.typed.ActorSystem;
import akkamon.api.models.Event;
-import akkamon.api.models.HeartBeatEvent;
import akkamon.domain.AkkamonMessageEngine;
import akkamon.domain.AkkamonNexus;
import akkamon.domain.AkkamonSession;
@@ -11,13 +10,14 @@ import com.google.gson.Gson;
import java.util.HashMap;
import java.util.Map;
+import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class MessagingEngine implements AkkamonMessageEngine {
- private Map<String, AkkamonSession> trainerIdToAkkamonSessions = new HashMap<>();
+ private Map<String, Set<AkkamonSession>> sceneIdToAkkamonSessions = new HashMap<>();
private Gson gson = new Gson();
private ActorRef<AkkamonNexus.Command> system;
@@ -36,44 +36,71 @@ public class MessagingEngine implements AkkamonMessageEngine {
}
private void heartBeat() {
- if (!trainerIdToAkkamonSessions.isEmpty()) {
- for (Map.Entry<String, AkkamonSession> entry : trainerIdToAkkamonSessions.entrySet()) {
- // System.out.println("heartbeat to " + entry.getKey());
- entry.getValue().send(gson.toJson(new HeartBeatEvent()));
- }
- }
+ system.tell(new AkkamonNexus.RequestHeartBeat(
+ UUID.randomUUID().getMostSignificantBits() & Long.MAX_VALUE,
+ system
+ ));
}
@Override
- public void broadCastGridPosition() {
+ public void broadCastToScene(String sceneId, String message) {
+ Set<AkkamonSession> sessionsInScene = sceneIdToAkkamonSessions.get(sceneId);
+ for (AkkamonSession session : sessionsInScene) {
+ session.send(message);
+ }
}
@Override
- public void registerTrainerSession(String trainerId, AkkamonSession session) {
- trainerIdToAkkamonSessions.put(trainerId, session);
+ public void registerTrainerSessionToScene(String sceneId, AkkamonSession session) {
+ sceneIdToAkkamonSessions.get(sceneId).add(session);
+ session.setTrainerId(sceneId);
+ heartBeat();
}
@Override
- public void removeTrainerSession(String trainerId, AkkamonSession session) {
+ public void removeTrainerSessionFromScene(String sceneId, AkkamonSession session) {
}
void incoming(AkkamonSession session, String message) {
Event event = gson.fromJson(message, Event.class);
- String trainerId = String.valueOf(trainerIdToAkkamonSessions.size());
+ // TODO use session trainerId
String sceneId = "akkamonStartScene";
switch (event.type) {
case START_MOVING:
system.tell(new AkkamonNexus.RequestStartMoving(
UUID.randomUUID().getMostSignificantBits() & Long.MAX_VALUE,
- "0",
+ session.getTrainerId(),
event.sceneId,
- event.direction
+ event.direction,
+ system
));
break;
+ case NEW_TILE_POS:
+ system.tell(
+ new AkkamonNexus.RequestNewTilePos(
+ UUID.randomUUID().getMostSignificantBits() & Long.MAX_VALUE,
+ session.getTrainerId(),
+ event.sceneId,
+ event.tilePos,
+ system
+ )
+ );
+ break;
+ case STOP_MOVING:
+ system.tell(
+ new AkkamonNexus.RequestStopMoving(
+ UUID.randomUUID().getMostSignificantBits() & Long.MAX_VALUE,
+ session.getTrainerId(),
+ event.sceneId,
+ event.direction,
+ system
+ )
+ );
+ break;
case TRAINER_REGISTRATION:
-
+ String trainerId = String.valueOf(sceneIdToAkkamonSessions.size());
system.tell(new AkkamonNexus.RequestTrainerRegistration(
trainerId,
sceneId,
@@ -82,7 +109,7 @@ public class MessagingEngine implements AkkamonMessageEngine {
));
break;
case HEART_BEAT:
- System.out.println("My heart goes boom skip!");
+ //System.out.println("My <3 beats!");
break;
}
diff --git a/api/src/main/java/akkamon/api/models/Event.java b/api/src/main/java/akkamon/api/models/Event.java
index 351d39f..8354b10 100644
--- a/api/src/main/java/akkamon/api/models/Event.java
+++ b/api/src/main/java/akkamon/api/models/Event.java
@@ -1,10 +1,12 @@
package akkamon.api.models;
import akkamon.domain.Direction;
+import akkamon.domain.TilePos;
public class Event {
public EventType type;
public String trainerId;
public Direction direction;
public String sceneId;
+ public TilePos tilePos;
}
diff --git a/api/src/main/java/akkamon/api/models/EventType.java b/api/src/main/java/akkamon/api/models/EventType.java
index ad537a5..be3b2b3 100644
--- a/api/src/main/java/akkamon/api/models/EventType.java
+++ b/api/src/main/java/akkamon/api/models/EventType.java
@@ -10,5 +10,13 @@ public enum EventType {
HEART_BEAT,
@SerializedName("StartMoving")
- START_MOVING
+ START_MOVING,
+
+ @SerializedName("NewTilePos")
+ NEW_TILE_POS,
+
+ @SerializedName("StopMoving")
+ STOP_MOVING,
+
+
}
diff --git a/api/src/main/java/akkamon/api/models/HeartBeatEvent.java b/api/src/main/java/akkamon/api/models/HeartBeatEvent.java
index 1b3dd0e..472c7e4 100644
--- a/api/src/main/java/akkamon/api/models/HeartBeatEvent.java
+++ b/api/src/main/java/akkamon/api/models/HeartBeatEvent.java
@@ -1,5 +1,7 @@
package akkamon.api.models;
public class HeartBeatEvent extends Event {
- public EventType type = EventType.HEART_BEAT;
+ public HeartBeatEvent() {
+ this.type = EventType.HEART_BEAT;
+ }
}
diff --git a/client/src/GridPhysics.ts b/client/src/GridPhysics.ts
index d363a60..b1fe459 100644
--- a/client/src/GridPhysics.ts
+++ b/client/src/GridPhysics.ts
@@ -6,7 +6,9 @@ import {
akkamonClient
} from './app';
import {
- StartMovingEvent
+ StartMovingEvent,
+ StopMovingEvent,
+ NewTilePosEvent
} from './events';
export class GridPhysics {
@@ -51,7 +53,7 @@ export class GridPhysics {
private startMoving(direction: Direction): void {
console.log("Sending startMovingEvent");
akkamonClient.send(
- new StartMovingEvent(direction)
+ new StartMovingEvent(this.playerSprite.getScene(), direction)
);
this.playerSprite.startAnimation(direction);
this.movementDirection = direction;
@@ -80,6 +82,12 @@ export class GridPhysics {
}
private updatePlayerSpriteTilePosition() {
+ akkamonClient.send(
+ new NewTilePosEvent(
+ this.playerSprite.getScene(),
+ this.playerSprite.getTilePos()
+ )
+ );
this.playerSprite.setTilePos(
this.playerSprite
.getTilePos()
@@ -127,6 +135,12 @@ export class GridPhysics {
}
private stopMoving(): void {
+ akkamonClient.send(
+ new StopMovingEvent(
+ this.playerSprite.getScene(),
+ this.movementDirection
+ )
+ );
this.playerSprite.stopAnimation(this.movementDirection);
this.movementDirection = Direction.NONE;
}
diff --git a/client/src/client.ts b/client/src/client.ts
index c83c39a..77d6676 100644
--- a/client/src/client.ts
+++ b/client/src/client.ts
@@ -26,8 +26,8 @@ export class Client
in(eventString: string) {
let event: AkkamonEvent = JSON.parse(eventString);
- // console.log("-> client is handling incoming event:");
- // console.log(event);
+ console.log("-> client is handling incoming event:");
+ console.log(event);
switch (event.type) {
case EventType.HEART_BEAT:
this.send(new HeartBeatReplyEvent());
diff --git a/client/src/events.ts b/client/src/events.ts
index 5a64d5b..cc001f7 100644
--- a/client/src/events.ts
+++ b/client/src/events.ts
@@ -6,7 +6,9 @@ import type { Direction } from './Direction';
export enum EventType {
HEART_BEAT = "HeartBeat",
PLAYER_REGISTRATION = "PlayerRegistrationEvent",
- START_MOVING = "StartMoving"
+ START_MOVING = "StartMoving",
+ STOP_MOVING = "StopMoving",
+ NEW_TILE_POS = "NewTilePos"
}
export interface AkkamonEvent {
@@ -26,10 +28,31 @@ export class StartMovingEvent implements AkkamonEvent {
public type: EventType = EventType.START_MOVING;
constructor(
+ public sceneId: string,
public direction: Direction,
) { }
}
+export class StopMovingEvent implements AkkamonEvent {
+
+ public type: EventType = EventType.STOP_MOVING;
+
+ constructor(
+ public sceneId: string,
+ public direction: Direction,
+ ) { }
+}
+
+export class NewTilePosEvent implements AkkamonEvent {
+
+ public type: EventType = EventType.NEW_TILE_POS;
+
+ constructor(
+ public sceneId: string,
+ public tilePos: {x: number, y: number}
+ ) { }
+}
+
export class HeartBeatReplyEvent implements AkkamonEvent {
public type: EventType = EventType.HEART_BEAT;
diff --git a/client/src/sprite.ts b/client/src/sprite.ts
index 77ca2a0..960d374 100644
--- a/client/src/sprite.ts
+++ b/client/src/sprite.ts
@@ -63,4 +63,8 @@ export class PlayerSprite extends Phaser.GameObjects.Sprite implements AkkamonPl
setTilePos(tilePosition: Phaser.Math.Vector2): void {
this.tilePos = tilePosition.clone();
}
+
+ getScene(): string {
+ return this.scene.scene.key;
+ }
}
diff --git a/domain/src/main/java/akkamon/domain/AkkamonMessageEngine.java b/domain/src/main/java/akkamon/domain/AkkamonMessageEngine.java
index fd22ce1..fc03915 100644
--- a/domain/src/main/java/akkamon/domain/AkkamonMessageEngine.java
+++ b/domain/src/main/java/akkamon/domain/AkkamonMessageEngine.java
@@ -2,9 +2,9 @@ package akkamon.domain;
public interface AkkamonMessageEngine {
// broadcasts position info to WebSocket Clients
- void broadCastGridPosition();
+ void broadCastToScene(String sceneId, String message);
- void registerTrainerSession(String trainerId, AkkamonSession session);
+ void registerTrainerSessionToScene(String sceneId, AkkamonSession session);
- void removeTrainerSession(String trainerId, AkkamonSession session);
+ void removeTrainerSessionFromScene(String sceneId, AkkamonSession session);
}
diff --git a/domain/src/main/java/akkamon/domain/AkkamonNexus.java b/domain/src/main/java/akkamon/domain/AkkamonNexus.java
index c9e07f0..0b52ffa 100644
--- a/domain/src/main/java/akkamon/domain/AkkamonNexus.java
+++ b/domain/src/main/java/akkamon/domain/AkkamonNexus.java
@@ -15,7 +15,8 @@ public class AkkamonNexus extends AbstractBehavior<AkkamonNexus.Command> {
public interface Command {}
- public static class RequestTrainerRegistration implements AkkamonNexus.Command, SceneTrainerGroup.Command {
+ public static class RequestTrainerRegistration
+ implements AkkamonNexus.Command, SceneTrainerGroup.Command {
public String trainerId;
public String sceneId;
public AkkamonSession session;
@@ -47,20 +48,104 @@ public class AkkamonNexus extends AbstractBehavior<AkkamonNexus.Command> {
}
}
- public static class RequestStartMoving implements Command, SceneTrainerGroup.Command {
+ public static class RequestStartMoving
+ implements Command, SceneTrainerGroup.Command, Trainer.Command {
public long requestId;
- public String trainerid;
+ public String trainerId;
public String sceneId;
public Direction direction;
+ public ActorRef<AkkamonNexus.Command> replyTo;
- public RequestStartMoving(long requestId, String trainerid, String sceneId, Direction direction) {
+ public RequestStartMoving(long requestId, String trainerId, String sceneId, Direction direction, ActorRef<AkkamonNexus.Command> replyTo) {
this.requestId = requestId;
- this.trainerid = trainerid;
+ this.trainerId = trainerId;
this.sceneId = sceneId;
this.direction = direction;
+ this.replyTo = replyTo;
+ }
+ }
+
+ public static class RequestStopMoving
+ implements Command, SceneTrainerGroup.Command, Trainer.Command {
+ public long requestId;
+ public String trainerId;
+ public String sceneId;
+ public Direction direction;
+ public ActorRef<AkkamonNexus.Command> replyTo;
+
+ public RequestStopMoving(
+ long requestId,
+ String trainerId,
+ String sceneId,
+ Direction direction,
+ ActorRef<AkkamonNexus.Command> replyTo) {
+ this.requestId = requestId;
+ this.trainerId = trainerId;
+ this.sceneId = sceneId;
+ this.direction = direction;
+ this.replyTo = replyTo;
+ }
+ }
+
+ public static class RequestNewTilePos
+ implements Command, SceneTrainerGroup.Command, Trainer.Command {
+ public long requestId;
+ public String trainerId;
+ public String sceneId;
+ public TilePos tilePos;
+ public ActorRef<AkkamonNexus.Command> replyTo;
+
+ public RequestNewTilePos(long requestId, String trainerId, String sceneId, TilePos tilePos, ActorRef<Command> replyTo) {
+ this.requestId = requestId;
+ this.trainerId = trainerId;
+ this.sceneId = sceneId;
+ this.tilePos = tilePos;
+ this.replyTo = replyTo;
+ }
+ }
+
+ public static class RequestHeartBeat
+ implements Command, SceneTrainerGroup.Command {
+
+ public long requestId;
+ public ActorRef<AkkamonNexus.Command> replyTo;
+
+ public RequestHeartBeat(long requestId, ActorRef<AkkamonNexus.Command> replyTo) {
+ this.requestId = requestId;
+ this.replyTo = replyTo;
}
}
+ public static class RespondHeartBeatQuery implements Command {
+
+ }
+
+ public interface TrainerPositionReading { }
+
+ public static class TrainerPosition implements TrainerPositionReading {
+ public final TilePos value;
+
+ public TrainerPosition(TilePos value) {
+ this.value = value;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ TrainerPosition other = (TrainerPosition) o;
+
+ return this.value.x == other.value.x && this.value.y == other.value.y;
+ }
+
+ @Override
+ public String toString() {
+ return "TrainerPosition={x: " + value.x + ", " + value.y + "}";
+ }
+
+ }
+
private static class SceneTrainerGroupTerminated implements AkkamonNexus.Command {
public SceneTrainerGroupTerminated(String sceneId) {
}
@@ -82,21 +167,59 @@ public class AkkamonNexus extends AbstractBehavior<AkkamonNexus.Command> {
@Override
public Receive<Command> createReceive() {
return newReceiveBuilder()
- .onMessage(
- RequestTrainerRegistration.class,
- this::onTrainerRegistration
- )
- .onMessage(
- TrainerRegistered.class,
- this::onTrainerRegistered
- )
+ .onMessage(RequestTrainerRegistration.class, this::onTrainerRegistration)
+ .onMessage(TrainerRegistered.class, this::onTrainerRegistered)
+ .onMessage(RequestHeartBeat.class, this::onHeartBeat)
+ .onMessage(RequestStartMoving.class, this::onStartMoving)
+ .onMessage(RequestStopMoving.class, this::onStopMoving)
+ .onMessage(RequestNewTilePos.class, this::onNewTilePos)
.build();
}
+ private AkkamonNexus onHeartBeat(RequestHeartBeat heartBeatRequest) {
+ return this;
+ }
+
+ private AkkamonNexus onNewTilePos(RequestNewTilePos newTilePosRequest) {
+ ActorRef<SceneTrainerGroup.Command> sceneTrainerGroup = sceneIdToActor.get(
+ newTilePosRequest.sceneId
+ );
+ if (sceneTrainerGroup != null) {
+ sceneTrainerGroup.tell(newTilePosRequest);
+ } else {
+ getContext().getLog().info("Ignoring newTilePos request in scene {}, it isn't mapped to a sceneTrainerActor.");
+ }
+ return this;
+ }
+
+ private AkkamonNexus onStopMoving(RequestStopMoving stopMovingRequest) {
+ ActorRef<SceneTrainerGroup.Command> sceneTrainerGroup = sceneIdToActor.get(
+ stopMovingRequest.sceneId
+ );
+ if (sceneTrainerGroup != null) {
+ sceneTrainerGroup.tell(stopMovingRequest);
+ } else {
+ getContext().getLog().info("Ignoring stopMove request in scene {}, it isn't mapped to a sceneTrainerActor.");
+ }
+ return this;
+ }
+
+ private AkkamonNexus onStartMoving(RequestStartMoving startMovingRequest) {
+ ActorRef<SceneTrainerGroup.Command> sceneTrainerGroup = sceneIdToActor.get(
+ startMovingRequest.sceneId
+ );
+ if (sceneTrainerGroup != null) {
+ sceneTrainerGroup.tell(startMovingRequest);
+ } else {
+ getContext().getLog().info("Ignoring stopMove request in scene {}, it isn't mapped to a sceneTrainerActor.");
+ }
+ return this;
+ }
+
private AkkamonNexus onTrainerRegistered(TrainerRegistered reply) {
// TODO test when registration fails?
getContext().getLog().info("Adding {} to Live AkkamonSessions in Messaging Engine", reply.trainerId);
- messageEngine.registerTrainerSession(reply.trainerId, reply.session);
+ messageEngine.registerTrainerSessionToScene(reply.trainerId, reply.session);
return this;
}
@@ -121,5 +244,4 @@ public class AkkamonNexus extends AbstractBehavior<AkkamonNexus.Command> {
return this;
}
-
}
diff --git a/domain/src/main/java/akkamon/domain/AkkamonSession.java b/domain/src/main/java/akkamon/domain/AkkamonSession.java
index b04aaab..68aa1fc 100644
--- a/domain/src/main/java/akkamon/domain/AkkamonSession.java
+++ b/domain/src/main/java/akkamon/domain/AkkamonSession.java
@@ -2,4 +2,8 @@ package akkamon.domain;
public interface AkkamonSession {
void send(String event);
+
+ void setTrainerId(String trainerId);
+
+ String getTrainerId();
}
diff --git a/domain/src/main/java/akkamon/domain/Direction.java b/domain/src/main/java/akkamon/domain/Direction.java
index c0908d8..71343c6 100644
--- a/domain/src/main/java/akkamon/domain/Direction.java
+++ b/domain/src/main/java/akkamon/domain/Direction.java
@@ -4,5 +4,6 @@ public enum Direction {
UP,
DOWN,
LEFT,
- RIGHT
+ RIGHT,
+ NONE
}
diff --git a/domain/src/main/java/akkamon/domain/SceneTrainerGroup.java b/domain/src/main/java/akkamon/domain/SceneTrainerGroup.java
index e6bd8ce..f01edc4 100644
--- a/domain/src/main/java/akkamon/domain/SceneTrainerGroup.java
+++ b/domain/src/main/java/akkamon/domain/SceneTrainerGroup.java
@@ -46,14 +46,100 @@ public class SceneTrainerGroup extends AbstractBehavior<SceneTrainerGroup.Comman
return newReceiveBuilder()
.onMessage(
AkkamonNexus.RequestTrainerRegistration.class,
- this::onTrainerRegistration)
+ this::onTrainerRegistration
+ )
+ .onMessage(
+ AkkamonNexus.RequestStartMoving.class,
+ this::onStartMoving
+ )
+ .onMessage(
+ AkkamonNexus.RequestStopMoving.class,
+ this::onStopMoving
+ )
+ .onMessage(
+ AkkamonNexus.RequestNewTilePos.class,
+ this::onNewTilePos
+ )
.build();
}
+ private SceneTrainerGroup onNewTilePos(AkkamonNexus.RequestNewTilePos newTilePosRequest) {
+ if (this.sceneId.equals(newTilePosRequest.sceneId)) {
+ ActorRef<Trainer.Command> trainerActor = trainerIdToActor.get(newTilePosRequest.trainerId);
+ if (trainerActor != null) {
+ trainerActor.tell(newTilePosRequest);
+ } else {
+ getContext()
+ .getLog()
+ .warn(
+ "Ignoring newTilePos for trainerId {}. There is no actor mapped to it.",
+ newTilePosRequest.trainerId
+ );
+ }
+ } else {
+ getContext()
+ .getLog()
+ .warn(
+ "Ignoring newTilePos for {}. This actor is responsible for {}.",
+ newTilePosRequest.sceneId,
+ this.sceneId);
+ }
+ return this;
+ }
+
+ private SceneTrainerGroup onStopMoving(AkkamonNexus.RequestStopMoving stopMovingRequest) {
+ if (this.sceneId.equals(stopMovingRequest.sceneId)) {
+ ActorRef<Trainer.Command> trainerActor = trainerIdToActor.get(stopMovingRequest.trainerId);
+ if (trainerActor != null) {
+ trainerActor.tell(stopMovingRequest);
+ } else {
+ getContext()
+ .getLog()
+ .warn(
+ "Ignoring stopMovingRequest for trainerId {}. There is no actor mapped to it.",
+ stopMovingRequest.trainerId
+ );
+ }
+ } else {
+ getContext()
+ .getLog()
+ .warn(
+ "Ignoring stopMovingRequest for {}. This actor is responsible for {}.",
+ stopMovingRequest.sceneId,
+ this.sceneId);
+ }
+ return this;
+ }
+
+ private SceneTrainerGroup onStartMoving(AkkamonNexus.RequestStartMoving startMovingRequest) {
+ if (this.sceneId.equals(startMovingRequest.sceneId)) {
+ ActorRef<Trainer.Command> trainerActor = trainerIdToActor.get(startMovingRequest.trainerId);
+ if (trainerActor != null) {
+ trainerActor.tell(startMovingRequest);
+ } else {
+ getContext()
+ .getLog()
+ .warn(
+ "Ignoring startMovingRequest for trainerId {}. There is no actor mapped to it.",
+ startMovingRequest.trainerId
+ );
+ }
+ } else {
+ getContext()
+ .getLog()
+ .warn(
+ "Ignoring startMovingRequest for {}. This actor is responsible for {}.",
+ startMovingRequest.sceneId,
+ this.sceneId);
+ }
+ return this;
+ }
+
private SceneTrainerGroup onTrainerRegistration(AkkamonNexus.RequestTrainerRegistration registrationRequest) {
if (this.sceneId.equals(registrationRequest.sceneId)) {
ActorRef<Trainer.Command> trainerActor = trainerIdToActor.get(registrationRequest.trainerId);
if (trainerActor != null) {
+ // TODO add optional already registered?
registrationRequest.replyTo.tell(new AkkamonNexus.TrainerRegistered(
registrationRequest.trainerId,
registrationRequest.session
diff --git a/domain/src/main/java/akkamon/domain/TilePos.java b/domain/src/main/java/akkamon/domain/TilePos.java
new file mode 100644
index 0000000..95e3f71
--- /dev/null
+++ b/domain/src/main/java/akkamon/domain/TilePos.java
@@ -0,0 +1,10 @@
+package akkamon.domain;
+
+public class TilePos {
+ public int x;
+ public int y;
+
+ public String toString() {
+ return "tilePos={x: " + x + ", y: " + y + "}";
+ }
+}
diff --git a/domain/src/main/java/akkamon/domain/Trainer.java b/domain/src/main/java/akkamon/domain/Trainer.java
index 7f540a1..b756a97 100644
--- a/domain/src/main/java/akkamon/domain/Trainer.java
+++ b/domain/src/main/java/akkamon/domain/Trainer.java
@@ -6,6 +6,8 @@ import akka.actor.typed.javadsl.ActorContext;
import akka.actor.typed.javadsl.Behaviors;
import akka.actor.typed.javadsl.Receive;
+import java.util.Optional;
+
public class Trainer extends AbstractBehavior<Trainer.Command> {
public interface Command { }
@@ -17,6 +19,8 @@ public class Trainer extends AbstractBehavior<Trainer.Command> {
private String sceneId;
private String trainerId;
+ private Optional<TilePos> lastValidTilePos = Optional.empty();
+
public Trainer(ActorContext<Command> context, String sceneId, String trainerId) {
super(context);
this.sceneId = sceneId;
@@ -25,7 +29,35 @@ public class Trainer extends AbstractBehavior<Trainer.Command> {
@Override
public Receive<Command> createReceive() {
- return null;
+ return newReceiveBuilder()
+ .onMessage(
+ AkkamonNexus.RequestStartMoving.class,
+ this::onStartMoving
+ )
+ .onMessage(
+ AkkamonNexus.RequestStopMoving.class,
+ this::onStopMoving)
+ .onMessage(
+ AkkamonNexus.RequestNewTilePos.class,
+ this::onNewTilePos
+ )
+ .build();
+ }
+
+ private Trainer onNewTilePos(AkkamonNexus.RequestNewTilePos newTilePosRequest) {
+ getContext().getLog().info("Trainer {} has new {}.", trainerId, newTilePosRequest.tilePos);
+ lastValidTilePos = Optional.of(newTilePosRequest.tilePos);
+ return this;
+ }
+
+ private Trainer onStopMoving(AkkamonNexus.RequestStopMoving stopMovingRequest) {
+ getContext().getLog().info("Trainer {} stops to move {}.", trainerId, stopMovingRequest.direction);
+ return this;
+ }
+
+ private Trainer onStartMoving(AkkamonNexus.RequestStartMoving startMovingRequest) {
+ getContext().getLog().info("Trainer {} starts to move {}.", trainerId, startMovingRequest.direction);
+ return this;
}
}