From 0b3e54e8ca97a874e3bf25e6e519f23282bab2aa Mon Sep 17 00:00:00 2001 From: Johan Haleby Date: Fri, 17 Nov 2023 17:20:05 +0100 Subject: [PATCH] Decider decideOnEvents can now take multiple commands as varargs --- .../org/occurrent/dsl/decider/Decider.java | 40 ++++++++++++++----- .../RockPaperScissorsExample.kt | 9 +---- 2 files changed, 32 insertions(+), 17 deletions(-) diff --git a/dsl/decider/src/main/java/org/occurrent/dsl/decider/Decider.java b/dsl/decider/src/main/java/org/occurrent/dsl/decider/Decider.java index 48b418cc3..e0c57d7b2 100644 --- a/dsl/decider/src/main/java/org/occurrent/dsl/decider/Decider.java +++ b/dsl/decider/src/main/java/org/occurrent/dsl/decider/Decider.java @@ -20,6 +20,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.ArrayList; import java.util.List; import java.util.function.BiFunction; import java.util.function.Predicate; @@ -36,19 +37,40 @@ default boolean isTerminal(@Nullable S state) { return false; } - default Decision decideOnEvents(List events, C command) { - @Nullable S currentState = fold(initialState(), events); - List newEvents = decide(command, currentState); - S newState = fold(currentState, newEvents); - return new Decision<>(newState, newEvents); + @SuppressWarnings("unchecked") + default Decision decideOnEvents(List events, C command, C... additionalCommands) { + BiFunction, C, Decision> single = (es, c) -> { + @Nullable S currentState = fold(initialState(), es); + List newEvents = decide(c, currentState); + S newState = fold(currentState, newEvents); + return new Decision<>(newState, newEvents); + }; + + Decision decisionAfterFirstCommand = single.apply(events, command); + final Decision finalDecision; + if (additionalCommands == null || additionalCommands.length == 0) { + finalDecision = decisionAfterFirstCommand; + } else { + Decision decision = decisionAfterFirstCommand; + for (C additionalCommand : additionalCommands) { + Decision thisDecision = single.apply(decision.events, additionalCommand); + List accumulatedEvents = new ArrayList<>(decision.events); + accumulatedEvents.addAll(thisDecision.events); + decision = new Decision<>(thisDecision.state, accumulatedEvents); + } + finalDecision = decision; + } + return finalDecision; } - default List decideOnEventsAndReturnEvents(List events, C command) { - return decideOnEvents(events, command).events; + @SuppressWarnings("unchecked") + default List decideOnEventsAndReturnEvents(List events, C command, C... additionalCommands) { + return decideOnEvents(events, command, additionalCommands).events; } - default @Nullable S decideOnEventsAndReturnState(List events, C command) { - return decideOnEvents(events, command).state; + @SuppressWarnings("unchecked") + default @Nullable S decideOnEventsAndReturnState(List events, C command, C... additionalCommands) { + return decideOnEvents(events, command, additionalCommands).state; } default Decision decideOnState(S state, C command) { diff --git a/example/domain/rps/multiround-decider-model/src/test/kotlin/org/occurrent/example/domain/rps/multirounddecidermodel/RockPaperScissorsExample.kt b/example/domain/rps/multiround-decider-model/src/test/kotlin/org/occurrent/example/domain/rps/multirounddecidermodel/RockPaperScissorsExample.kt index 89185a0b8..34de91234 100644 --- a/example/domain/rps/multiround-decider-model/src/test/kotlin/org/occurrent/example/domain/rps/multirounddecidermodel/RockPaperScissorsExample.kt +++ b/example/domain/rps/multiround-decider-model/src/test/kotlin/org/occurrent/example/domain/rps/multirounddecidermodel/RockPaperScissorsExample.kt @@ -21,7 +21,6 @@ import org.junit.jupiter.api.DisplayName import org.junit.jupiter.api.DisplayNameGeneration import org.junit.jupiter.api.DisplayNameGenerator import org.junit.jupiter.api.Test -import org.occurrent.dsl.decider.Decider.Decision import org.occurrent.dsl.decider.component1 import org.occurrent.dsl.decider.component2 import org.occurrent.example.domain.rps.multirounddecidermodel.InitiateNewGame.NumberOfRounds.THREE @@ -38,7 +37,7 @@ class RockPaperScissorsExample { val secondPlayerId = PlayerId.randomUUID() // When - val (state, events) = executeCommands( + val (state, events) = rps.decideOnEvents(emptyList(), InitiateNewGame(gameId, Timestamp.now(), firstPlayerId, THREE), ShowHandGesture(gameId, Timestamp.now(), firstPlayerId, HandGesture.PAPER), @@ -56,10 +55,4 @@ class RockPaperScissorsExample { println() println("events:\n${events.joinToString("\n")}") } - - private fun executeCommands(vararg gameCommands: GameCommand): Decision = - gameCommands.fold(Decision(null, emptyList())) { decision, c -> - val (newState, newEvents) = rps.decideOnState(decision.state, c) - Decision(newState, decision.events + newEvents) - } } \ No newline at end of file