Skip to content

Commit

Permalink
Decider decideOnEvents can now take multiple commands as varargs
Browse files Browse the repository at this point in the history
  • Loading branch information
johanhaleby committed Nov 17, 2023
1 parent 6c1d266 commit 0b3e54e
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 17 deletions.
40 changes: 31 additions & 9 deletions dsl/decider/src/main/java/org/occurrent/dsl/decider/Decider.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -36,19 +37,40 @@ default boolean isTerminal(@Nullable S state) {
return false;
}

default Decision<S, E> decideOnEvents(List<E> events, C command) {
@Nullable S currentState = fold(initialState(), events);
List<E> newEvents = decide(command, currentState);
S newState = fold(currentState, newEvents);
return new Decision<>(newState, newEvents);
@SuppressWarnings("unchecked")
default Decision<S, E> decideOnEvents(List<E> events, C command, C... additionalCommands) {
BiFunction<List<E>, C, Decision<S, E>> single = (es, c) -> {
@Nullable S currentState = fold(initialState(), es);
List<E> newEvents = decide(c, currentState);
S newState = fold(currentState, newEvents);
return new Decision<>(newState, newEvents);
};

Decision<S, E> decisionAfterFirstCommand = single.apply(events, command);
final Decision<S, E> finalDecision;
if (additionalCommands == null || additionalCommands.length == 0) {
finalDecision = decisionAfterFirstCommand;
} else {
Decision<S, E> decision = decisionAfterFirstCommand;
for (C additionalCommand : additionalCommands) {
Decision<S, E> thisDecision = single.apply(decision.events, additionalCommand);
List<E> accumulatedEvents = new ArrayList<>(decision.events);
accumulatedEvents.addAll(thisDecision.events);
decision = new Decision<>(thisDecision.state, accumulatedEvents);
}
finalDecision = decision;
}
return finalDecision;
}

default List<E> decideOnEventsAndReturnEvents(List<E> events, C command) {
return decideOnEvents(events, command).events;
@SuppressWarnings("unchecked")
default List<E> decideOnEventsAndReturnEvents(List<E> events, C command, C... additionalCommands) {
return decideOnEvents(events, command, additionalCommands).events;
}

default @Nullable S decideOnEventsAndReturnState(List<E> events, C command) {
return decideOnEvents(events, command).state;
@SuppressWarnings("unchecked")
default @Nullable S decideOnEventsAndReturnState(List<E> events, C command, C... additionalCommands) {
return decideOnEvents(events, command, additionalCommands).state;
}

default Decision<S, E> decideOnState(S state, C command) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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),
Expand All @@ -56,10 +55,4 @@ class RockPaperScissorsExample {
println()
println("events:\n${events.joinToString("\n")}")
}

private fun executeCommands(vararg gameCommands: GameCommand): Decision<GameState, GameEvent> =
gameCommands.fold(Decision<GameState, GameEvent>(null, emptyList())) { decision, c ->
val (newState, newEvents) = rps.decideOnState(decision.state, c)
Decision(newState, decision.events + newEvents)
}
}

0 comments on commit 0b3e54e

Please sign in to comment.