refactoring

This commit is contained in:
2025-03-04 23:21:06 +01:00
parent f3ca94c97e
commit 06443d7efa
31 changed files with 140 additions and 185 deletions

View File

@@ -0,0 +1,79 @@
package eventDemo.app.event
import eventDemo.app.GameId
import eventDemo.app.entity.Card
import eventDemo.app.entity.Deck
import eventDemo.app.entity.Player
import eventDemo.libs.event.Event
import kotlinx.serialization.Serializable
/**
* An [Event] of a Game.
*/
@Serializable
sealed interface GameEvent : Event<GameId> {
override val id: GameId
}
/**
* An [Event] to represent a played card.
*/
data class CardIsPlayedEvent(
override val id: GameId,
val card: Card,
val player: Player,
) : GameEvent
/**
* An [Event] to represent a new player joining the game.
*/
data class NewPlayerEvent(
override val id: GameId,
val player: Player,
) : GameEvent
/**
* This [Event] is sent when a player is ready.
*/
data class PlayerReadyEvent(
override val id: GameId,
val player: Player,
) : GameEvent
/**
* This [Event] is sent when a player is ready.
*/
data class GameStartedEvent(
override val id: GameId,
val firstPlayer: Player,
val deck: Deck,
) : GameEvent {
companion object {
fun new(
id: GameId,
players: Set<Player>,
): GameStartedEvent =
GameStartedEvent(
id = id,
firstPlayer = players.random(),
deck = Deck.initHands(players).putOneCardOnDiscard(),
)
}
}
/**
* This [Event] is sent when a player can play.
*/
data class PlayerHavePassEvent(
override val id: GameId,
val player: Player,
) : GameEvent
/**
* This [Event] is sent when a player chose a color.
*/
data class PlayerChoseColorEvent(
override val id: GameId,
val player: Player,
val color: Card.Color,
) : GameEvent

View File

@@ -0,0 +1,8 @@
package eventDemo.app.event
import eventDemo.app.GameId
import eventDemo.libs.event.EventBus
class GameEventBus(
bus: EventBus<GameEvent, GameId>,
) : EventBus<GameEvent, GameId> by bus

View File

@@ -0,0 +1,18 @@
package eventDemo.app.event
import eventDemo.app.GameId
import eventDemo.libs.event.EventBus
import eventDemo.libs.event.EventStream
/**
* A stream to publish and read the played card event.
*/
class GameEventStream(
private val eventBus: EventBus<GameEvent, GameId>,
private val m: EventStream<GameEvent, GameId>,
) : EventStream<GameEvent, GameId> by m {
override fun publish(event: GameEvent) {
m.publish(event)
eventBus.publish(event)
}
}

View File

@@ -0,0 +1,72 @@
package eventDemo.app.event
import eventDemo.app.GameId
import eventDemo.app.GameState
import eventDemo.app.entity.Card
import eventDemo.libs.event.EventStream
fun GameId.buildStateFromEventStream(eventStream: EventStream<GameEvent, GameId>): GameState =
buildStateFromEvents(
eventStream.readAll(this),
)
private fun GameId.buildStateFromEvents(events: List<GameEvent>): GameState =
events.fold(GameState(this)) { state: GameState, event: GameEvent ->
when (event) {
is CardIsPlayedEvent -> {
val direction =
when (event.card) {
is Card.ReverseCard -> state.direction.revert()
else -> state.direction
}
val color =
when (event.card) {
is Card.ColorCard -> event.card.color
else -> state.lastColor
}
state.copy(
lastPlayer = event.player,
direction = direction,
lastColor = color,
)
}
is NewPlayerEvent -> {
if (state.isReady) error("The game is already started")
state.copy(
players = state.players + event.player,
)
}
is PlayerReadyEvent -> {
state.copy(
readyPlayers = state.readyPlayers + event.player,
)
}
is PlayerHavePassEvent -> {
state.copy(
lastPlayer = event.player,
)
}
is PlayerChoseColorEvent -> {
state.copy(
lastColor = event.color,
)
}
is GameStartedEvent -> {
state.copy(
lastColor = (event.deck.discard.first() as? Card.ColorCard)?.color,
lastCard = eventDemo.app.GameState.LastCard(event.deck.discard.first(), event.firstPlayer),
lastPlayer = event.firstPlayer,
deck = event.deck,
isStarted = true,
)
}
}
}