extract action command
This commit is contained in:
@@ -2,14 +2,12 @@ package eventDemo.app.command
|
||||
|
||||
import eventDemo.app.GameState
|
||||
import eventDemo.app.command.command.GameCommand
|
||||
import eventDemo.app.command.command.IWantToPlayCardCommand
|
||||
import eventDemo.app.command.command.IamReadyToPlayCommand
|
||||
import eventDemo.app.command.command.IwantToPlayCardCommand
|
||||
import eventDemo.app.entity.Player
|
||||
import eventDemo.app.event.GameEventStream
|
||||
import eventDemo.app.event.buildStateFromEventStream
|
||||
import eventDemo.app.event.event.CardIsPlayedEvent
|
||||
import eventDemo.app.event.event.GameEvent
|
||||
import eventDemo.app.event.event.PlayerReadyEvent
|
||||
import io.ktor.websocket.Frame
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@@ -29,7 +27,7 @@ class GameCommandHandler(
|
||||
outgoing: SendChannel<Frame>,
|
||||
) {
|
||||
private val commandStream = GameCommandStream(incoming, outgoing)
|
||||
private val playerNotifier = outgoing
|
||||
private val playerNotifier: (String) -> Unit = { runBlocking { outgoing.send(Frame.Text(it)) } }
|
||||
|
||||
/**
|
||||
* Init the handler
|
||||
@@ -41,48 +39,20 @@ class GameCommandHandler(
|
||||
nack()
|
||||
}
|
||||
|
||||
val state = command.buildState()
|
||||
val gameState = command.buildGameState()
|
||||
|
||||
when (command) {
|
||||
is IwantToPlayCardCommand -> {
|
||||
// Check the command can be executed
|
||||
if (state.commandCardCanBeExecuted(command)) {
|
||||
eventStream.publish(
|
||||
CardIsPlayedEvent(
|
||||
command.payload.gameId,
|
||||
command.payload.card,
|
||||
command.payload.player,
|
||||
),
|
||||
)
|
||||
} else {
|
||||
runBlocking {
|
||||
playerNotifier.send(Frame.Text("Command cannot be executed"))
|
||||
}
|
||||
}
|
||||
is IWantToPlayCardCommand -> {
|
||||
command.run(gameState, playerNotifier, eventStream)
|
||||
}
|
||||
|
||||
is IamReadyToPlayCommand -> {
|
||||
if (state.playerIsAlreadyReady(command.payload.player)) {
|
||||
nack()
|
||||
} else {
|
||||
PlayerReadyEvent(
|
||||
command.payload.gameId,
|
||||
command.payload.player,
|
||||
)
|
||||
}
|
||||
command.run(gameState, playerNotifier, eventStream)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun GameState.playerIsAlreadyReady(player: Player): Boolean = readyPlayers.contains(player)
|
||||
|
||||
private fun GameState.commandCardCanBeExecuted(command: IwantToPlayCardCommand): Boolean =
|
||||
canBePlayThisCard(
|
||||
command.payload.player,
|
||||
command.payload.card,
|
||||
)
|
||||
|
||||
private fun GameCommand.buildState(): GameState = payload.gameId.buildStateFromEventStream(eventStream)
|
||||
private fun GameCommand.buildGameState(): GameState = payload.gameId.buildStateFromEventStream(eventStream)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
package eventDemo.app.command.command
|
||||
|
||||
import eventDemo.app.GameState
|
||||
import eventDemo.app.entity.Card
|
||||
import eventDemo.app.entity.GameId
|
||||
import eventDemo.app.entity.Player
|
||||
import eventDemo.app.event.GameEventStream
|
||||
import eventDemo.app.event.event.CardIsPlayedEvent
|
||||
import eventDemo.libs.command.CommandId
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/**
|
||||
* A command to perform an action to play a new card
|
||||
*/
|
||||
@Serializable
|
||||
@SerialName("PlayCard")
|
||||
data class IWantToPlayCardCommand(
|
||||
override val payload: Payload,
|
||||
) : GameCommand {
|
||||
override val name: String = "PlayCard"
|
||||
override val id: CommandId = CommandId()
|
||||
|
||||
@Serializable
|
||||
data class Payload(
|
||||
override val gameId: GameId,
|
||||
override val player: Player,
|
||||
val card: Card,
|
||||
) : GameCommand.Payload
|
||||
|
||||
fun run(
|
||||
state: GameState,
|
||||
playerNotifier: (String) -> Unit,
|
||||
eventStream: GameEventStream,
|
||||
) {
|
||||
val commandCardCanBeExecuted: Boolean =
|
||||
state.canBePlayThisCard(
|
||||
payload.player,
|
||||
payload.card,
|
||||
)
|
||||
|
||||
if (commandCardCanBeExecuted) {
|
||||
eventStream.publish(
|
||||
CardIsPlayedEvent(
|
||||
payload.gameId,
|
||||
payload.card,
|
||||
payload.player,
|
||||
),
|
||||
)
|
||||
} else {
|
||||
playerNotifier("Command cannot be executed")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,10 @@
|
||||
package eventDemo.app.command.command
|
||||
|
||||
import eventDemo.app.GameState
|
||||
import eventDemo.app.entity.GameId
|
||||
import eventDemo.app.entity.Player
|
||||
import eventDemo.app.event.GameEventStream
|
||||
import eventDemo.app.event.event.PlayerReadyEvent
|
||||
import eventDemo.libs.command.CommandId
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
@@ -22,4 +25,23 @@ data class IamReadyToPlayCommand(
|
||||
override val gameId: GameId,
|
||||
override val player: Player,
|
||||
) : GameCommand.Payload
|
||||
|
||||
fun run(
|
||||
state: GameState,
|
||||
playerNotifier: (String) -> Unit,
|
||||
eventStream: GameEventStream,
|
||||
) {
|
||||
val playerIsAlreadyReady: Boolean = state.readyPlayers.contains(payload.player)
|
||||
|
||||
if (playerIsAlreadyReady) {
|
||||
playerNotifier("You are already ready")
|
||||
} else {
|
||||
eventStream.publish(
|
||||
PlayerReadyEvent(
|
||||
payload.gameId,
|
||||
payload.player,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
package eventDemo.app.command.command
|
||||
|
||||
import eventDemo.app.entity.Card
|
||||
import eventDemo.app.entity.GameId
|
||||
import eventDemo.app.entity.Player
|
||||
import eventDemo.libs.command.CommandId
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/**
|
||||
* A command to perform an action to play a new card
|
||||
*/
|
||||
@Serializable
|
||||
@SerialName("PlayCard")
|
||||
data class IwantToPlayCardCommand(
|
||||
override val payload: Payload,
|
||||
) : GameCommand {
|
||||
override val name: String = "PlayCard"
|
||||
override val id: CommandId = CommandId()
|
||||
|
||||
@Serializable
|
||||
data class Payload(
|
||||
override val gameId: GameId,
|
||||
override val player: Player,
|
||||
val card: Card,
|
||||
) : GameCommand.Payload
|
||||
}
|
||||
Reference in New Issue
Block a user