diff --git a/dashboard/pom.xml b/dashboard/pom.xml index 215093e..cddc3ad 100644 --- a/dashboard/pom.xml +++ b/dashboard/pom.xml @@ -168,6 +168,30 @@ + + org.apache.maven.plugins + maven-antrun-plugin + 3.1.0 + + + delete-mvnpm-deps + package + + run + + + + + + + + + + + + + + diff --git a/dashboard/src/main/java/rest/Dashboard.java b/dashboard/src/main/java/rest/Dashboard.java index f385c25..30cb9b4 100644 --- a/dashboard/src/main/java/rest/Dashboard.java +++ b/dashboard/src/main/java/rest/Dashboard.java @@ -76,11 +76,35 @@ public void reset() { @Produces(MediaType.SERVER_SENT_EVENTS) @RestStreamElementType(MediaType.TEXT_PLAIN) - public Multi events(@Context Sse sse) { + public Multi boardEvents(@Context Sse sse) { return gameService.events() + .filter(e -> e.type().sseEventName().equals("BoardUpdate") || e.type().sseEventName().equals("GameUpdate")) .group().intoLists() - .every(Duration.ofMillis(200)) - .map(g -> sse.newEvent(resolveSseEventName(g), "")); + .every(Duration.ofMillis(500)) + .map(g -> sse.newEvent("BoardUpdate", compactHtml(Templates.board().render()))); + } + + @Produces(MediaType.SERVER_SENT_EVENTS) + @RestStreamElementType(MediaType.TEXT_PLAIN) + public Multi controlsEvents(@Context Sse sse) { + return gameService.events() + .filter(e -> e.type().sseEventName().equals("ControlsUpdate") || e.type().sseEventName().equals("GameUpdate")) + .map(g -> sse.newEvent("ControlsUpdate", compactHtml(Templates.controls().render()))); + } + + private static String compactHtml(String html) { + return html.replaceAll("(\\s+|\\v)", " "); + } + + private String resolveEventData(String eventName) { + switch (eventName) { + case "BoardUpdate": + return Templates.board().render(); + case "ControlsUpdate": + return Templates.controls().render(); + default: + return Templates.index$game().render(); + } } private static String resolveSseEventName(List g) { diff --git a/dashboard/src/main/java/service/GameService.java b/dashboard/src/main/java/service/GameService.java index 8e32697..bd80a0f 100644 --- a/dashboard/src/main/java/service/GameService.java +++ b/dashboard/src/main/java/service/GameService.java @@ -120,7 +120,7 @@ public void stop() { rank.set(null); watching.set(null); watchStatus.set(OFF); - runners.replaceAll((r, v) -> v.runner().initialState()); + runners.replaceAll((r, v) -> v.active() ? v.runner().initialState() : v.runner().setInactive()); emitEvent(STOP); } @@ -129,7 +129,7 @@ public void reset() { watching.set(null); watchStatus.set(OFF); rank.set(null); - runners.replaceAll((r, v) -> v.runner().inactive()); + runners.replaceAll((r, v) -> v.runner().setInactive()); emitEvent(RESET); } @@ -177,6 +177,10 @@ public Collection runners() { return runners.values(); } + public Collection activeRunners() { + return runners.values().stream().filter(RunnerState::active).toList(); + } + public WatchStatus watchStatus() { return watchStatus.get(); } @@ -190,7 +194,7 @@ public Runner newRunner(String prevId) { if (prevId != null && runners.containsKey(prevId)) { final RunnerState state = runners.get(prevId); runner = state.runner(); - if (!state.isActive()) { + if (!state.active()) { runners.put(runner.id(), runner.initialState()); } } else { @@ -229,7 +233,7 @@ public void run(String runnerId, int distance, long time) { return null; } // inactive user becoming active - if (!state.isActive()) { + if (!state.active()) { emitEvent(NEW_RUNNER); return state.runner().initialState(); } @@ -296,7 +300,7 @@ public int getRank(String id) { } static Comparator rankComparator() { - return comparing(RunnerState::isActive).reversed() + return comparing(RunnerState::active).reversed() .thenComparing(comparing(RunnerState::saved).reversed()) .thenComparing(comparing(RunnerState::alive).reversed()) .thenComparing(comparing(RunnerState::distance).reversed()) @@ -339,14 +343,14 @@ public RunnerState initialState() { return new RunnerState(this, 0, 0, RunnerState.Status.alive); } - public RunnerState inactive() { + public RunnerState setInactive() { return new RunnerState(this, 0, 0, RunnerState.Status.inactive); } } - public int indexPercentage(int index) { - return (int) Math.floor((index + 0.5) * 100 / runners().size()); + public int indexPercentage(int index, int max) { + return (int) Math.floor((index + 0.5) * 100 / max); } public record RunnerState(Runner runner, int distance, long duration, Status status) { @@ -366,11 +370,15 @@ public boolean saved() { return status == Status.saved; } + public boolean inactive() { + return status == Status.inactive; + } + public boolean gameOver() { - return saved() || dead(); + return saved() || dead() || inactive(); } - public boolean isActive() { + public boolean active() { return status != Status.inactive; } diff --git a/dashboard/src/main/resources/application.properties b/dashboard/src/main/resources/application.properties index 0cd0f4c..8d531e3 100644 --- a/dashboard/src/main/resources/application.properties +++ b/dashboard/src/main/resources/application.properties @@ -11,7 +11,7 @@ mp.messaging.incoming.runners-in.topic=runners %dev.quarkus.http.cors=true %dev.quarkus.http.cors.origins=* - +quarkus.http.enable-compression=true quarkus.csrf-reactive.require-form-url-encoded=false game.target-distance=100 diff --git a/dashboard/src/main/resources/templates/Dashboard/board.html b/dashboard/src/main/resources/templates/Dashboard/board.html index 34441bf..bc435ec 100644 --- a/dashboard/src/main/resources/templates/Dashboard/board.html +++ b/dashboard/src/main/resources/templates/Dashboard/board.html @@ -1,7 +1,7 @@ -{#for item in cdi:game.runners} +{#let activeRunners = cdi:game.activeRunners} +{#for item in activeRunners} {#if item.active} -
+
{item.runner.name}
{/if} diff --git a/dashboard/src/main/resources/templates/Dashboard/controls.html b/dashboard/src/main/resources/templates/Dashboard/controls.html index d5005d3..8cf475d 100644 --- a/dashboard/src/main/resources/templates/Dashboard/controls.html +++ b/dashboard/src/main/resources/templates/Dashboard/controls.html @@ -1,4 +1,4 @@ -
+
{#when cdi:game.watchStatus} {#is WATCHING}

One-Two-Three

@@ -11,13 +11,13 @@

{config:venue}

{#is WARNING} {#is ROCKING} {#is GAME_OVER}