feature: init kotlin compose multiplatforme
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
val kotlinSerializationVersion: Provider<String> = providers.gradleProperty("kotlin_serialization_version")
|
||||
val androidCompileSdk: Provider<String> = providers.gradleProperty("android_compile_sdk")
|
||||
val androidMinSdk: Provider<String> = providers.gradleProperty("android_min_sdk")
|
||||
|
||||
plugins {
|
||||
kotlin("multiplatform")
|
||||
kotlin("plugin.serialization")
|
||||
id("com.android.library")
|
||||
}
|
||||
|
||||
kotlin {
|
||||
jvm()
|
||||
|
||||
androidTarget {
|
||||
compilerOptions {
|
||||
freeCompilerArgs.add("-opt-in=kotlin.uuid.ExperimentalUuidApi")
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(org.jetbrains.kotlin.gradle.ExperimentalWasmDsl::class)
|
||||
wasmJs {
|
||||
browser()
|
||||
}
|
||||
|
||||
compilerOptions {
|
||||
freeCompilerArgs.add("-opt-in=kotlin.uuid.ExperimentalUuidApi")
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
commonMain.dependencies {
|
||||
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:${kotlinSerializationVersion.get()}")
|
||||
}
|
||||
commonTest.dependencies {
|
||||
implementation(kotlin("test"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
android {
|
||||
namespace = "io.github.flecomte.eventdemo.shared"
|
||||
compileSdk = androidCompileSdk.get().toInt()
|
||||
|
||||
defaultConfig {
|
||||
minSdk = androidMinSdk.get().toInt()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package eventDemo.shared.command
|
||||
|
||||
import eventDemo.shared.ids.CommandId
|
||||
|
||||
/**
|
||||
* Interface to represent a Command.
|
||||
*
|
||||
* A command is a request for an action.
|
||||
*
|
||||
* Moved to `shared` (deviating slightly from the original plan of leaving it backend-only)
|
||||
* because [eventDemo.shared.game.command.GameCommand] - a wire type that must live in `shared`
|
||||
* for multiplatform client reuse - implements it. Since `shared` cannot depend on `backend`,
|
||||
* this minimal marker interface has to live wherever its implementers live.
|
||||
*/
|
||||
interface Command {
|
||||
val id: CommandId
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
package eventDemo.shared.game
|
||||
|
||||
import eventDemo.shared.serializers.UUIDSerializer
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlin.uuid.Uuid
|
||||
|
||||
/**
|
||||
* A Play card
|
||||
*/
|
||||
@Serializable
|
||||
sealed interface Card {
|
||||
val id: Uuid
|
||||
|
||||
/**
|
||||
* The color of a card
|
||||
*/
|
||||
@Serializable
|
||||
enum class Color {
|
||||
Blue,
|
||||
Red,
|
||||
Yellow,
|
||||
Green,
|
||||
}
|
||||
|
||||
sealed interface CardWithColor : Card {
|
||||
val color: Color
|
||||
}
|
||||
|
||||
/**
|
||||
* A play card with color and number
|
||||
*/
|
||||
@Serializable
|
||||
@SerialName("Simple")
|
||||
data class NumericCard(
|
||||
val number: Int,
|
||||
override val color: Color,
|
||||
@Serializable(with = UUIDSerializer::class)
|
||||
override val id: Uuid = Uuid.random(),
|
||||
) : Card,
|
||||
CardWithColor {
|
||||
init {
|
||||
if (number > 9) error("Card number cannot be greater of 9")
|
||||
if (number < 0) error("Card number cannot be lower of 0")
|
||||
}
|
||||
|
||||
override fun toString(): String =
|
||||
"Numeric Card $number $color"
|
||||
}
|
||||
|
||||
sealed interface Special : Card
|
||||
|
||||
/**
|
||||
* A revert card to revert the order of the turn.
|
||||
*/
|
||||
@Serializable
|
||||
@SerialName("Reverse")
|
||||
data class ReverseCard(
|
||||
override val color: Color,
|
||||
@Serializable(with = UUIDSerializer::class)
|
||||
override val id: Uuid = Uuid.random(),
|
||||
) : Special,
|
||||
CardWithColor {
|
||||
override fun toString(): String =
|
||||
"Revert Card $color"
|
||||
}
|
||||
|
||||
sealed interface PassTurnCard : Card
|
||||
|
||||
/**
|
||||
* A pass card to pass the turn of the next player.
|
||||
*/
|
||||
@Serializable
|
||||
@SerialName("Pass")
|
||||
data class PassCard(
|
||||
override val color: Color,
|
||||
@Serializable(with = UUIDSerializer::class)
|
||||
override val id: Uuid = Uuid.random(),
|
||||
) : Special,
|
||||
CardWithColor,
|
||||
PassTurnCard {
|
||||
override fun toString(): String =
|
||||
"Pass Card $color"
|
||||
}
|
||||
|
||||
/**
|
||||
* A play card to force the next player to take 2 card and pass the turn.
|
||||
*/
|
||||
@Serializable
|
||||
@SerialName("Plus2")
|
||||
data class Plus2Card(
|
||||
override val color: Color,
|
||||
@Serializable(with = UUIDSerializer::class)
|
||||
override val id: Uuid = Uuid.random(),
|
||||
) : Special,
|
||||
CardWithColor,
|
||||
PassTurnCard {
|
||||
override fun toString(): String =
|
||||
"Plus2 Card $color"
|
||||
}
|
||||
|
||||
sealed interface CardWith4Color : Card
|
||||
|
||||
/**
|
||||
* A play card to force the next player to take 4 card and pass the turn.
|
||||
*/
|
||||
@Serializable
|
||||
@SerialName("Plus4")
|
||||
class Plus4Card(
|
||||
@Serializable(with = UUIDSerializer::class)
|
||||
override val id: Uuid = Uuid.random(),
|
||||
) : Special,
|
||||
CardWith4Color,
|
||||
PassTurnCard {
|
||||
override fun toString(): String =
|
||||
"Plus4 Card"
|
||||
}
|
||||
|
||||
/**
|
||||
* A play card to change the color.
|
||||
*/
|
||||
@Serializable
|
||||
@SerialName("ChangeColor")
|
||||
class ChangeColorCard(
|
||||
@Serializable(with = UUIDSerializer::class)
|
||||
override val id: Uuid = Uuid.random(),
|
||||
) : Special,
|
||||
CardWith4Color {
|
||||
override fun toString(): String =
|
||||
"Change color Card"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package eventDemo.shared.game
|
||||
|
||||
import kotlin.jvm.JvmInline
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@JvmInline
|
||||
@Serializable
|
||||
value class DiscardPile(
|
||||
val cards: Set<Card> = emptySet(),
|
||||
) {
|
||||
fun withNewCard(card: Card): DiscardPile =
|
||||
DiscardPile(cards + card)
|
||||
|
||||
val topCard: Card? get() = cards.lastOrNull()
|
||||
|
||||
val topCardColor: Card.Color? get() = topCard?.let { if (it is Card.CardWithColor) it.color else null }
|
||||
|
||||
val size: Int get() = cards.size
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package eventDemo.shared.game
|
||||
|
||||
import kotlin.jvm.JvmInline
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@JvmInline
|
||||
@Serializable
|
||||
value class DrawPile(
|
||||
val cards: Set<Card> = emptySet(),
|
||||
) {
|
||||
val size: Int get() = cards.size
|
||||
|
||||
fun take(number: Int): Pair<DrawPile, Set<Card>> =
|
||||
cards.drop(number).toDrawPile() to cards.take(number).toSet()
|
||||
|
||||
val remainingCards
|
||||
get() = cards.size
|
||||
|
||||
fun shuffled(): DrawPile =
|
||||
cards.shuffled().toDrawPile()
|
||||
|
||||
val firstCard get() = cards.first()
|
||||
|
||||
fun generateValidDrawPile(): DrawPile =
|
||||
if (cards.first() is Card.CardWith4Color) {
|
||||
DrawPile(setOf(cards.first()) + cards.drop(1))
|
||||
.generateValidDrawPile()
|
||||
} else {
|
||||
this
|
||||
}
|
||||
}
|
||||
|
||||
private fun List<Card>.toDrawPile(): DrawPile =
|
||||
DrawPile(this.toSet())
|
||||
@@ -0,0 +1,74 @@
|
||||
package eventDemo.shared.game
|
||||
|
||||
import eventDemo.shared.ids.AggregateId
|
||||
import eventDemo.shared.ids.UserId
|
||||
import eventDemo.shared.serializers.UUIDSerializer
|
||||
import kotlin.jvm.JvmInline
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlin.uuid.Uuid
|
||||
|
||||
@Serializable
|
||||
data class Player(
|
||||
val name: String,
|
||||
val userId: UserId,
|
||||
val hand: PlayerHand = PlayerHand(),
|
||||
val id: PlayerId = PlayerId(Uuid.random()),
|
||||
) {
|
||||
@JvmInline
|
||||
@Serializable
|
||||
value class PlayerId(
|
||||
@Serializable(with = UUIDSerializer::class)
|
||||
override val id: Uuid = Uuid.random(),
|
||||
) : AggregateId {
|
||||
override fun toString(): String =
|
||||
id.toString()
|
||||
}
|
||||
}
|
||||
|
||||
@Serializable
|
||||
class PlayerList(
|
||||
val players: Set<Player> = emptySet(),
|
||||
) : Set<Player> by players {
|
||||
fun get(id: Player.PlayerId): Player =
|
||||
find { it.id == id } ?: error("no player with id $id")
|
||||
|
||||
fun get(id: UserId): Player =
|
||||
find { it.userId == id } ?: error("no player with userId $id")
|
||||
|
||||
fun withNewCardOnPlayerHand(
|
||||
playerId: Player.PlayerId,
|
||||
cards: Set<Card>,
|
||||
): PlayerList =
|
||||
players
|
||||
.withReplacedValue(get(playerId)) {
|
||||
it.copy(
|
||||
hand = it.hand.withNewCards(cards),
|
||||
)
|
||||
}.let { PlayerList(it) }
|
||||
|
||||
fun withDropCardOnPlayerHand(
|
||||
playerId: Player.PlayerId,
|
||||
card: Card,
|
||||
): PlayerList =
|
||||
players
|
||||
.withReplacedValue(get(playerId)) {
|
||||
it.copy(
|
||||
hand = it.hand.withoutTheCards(setOf(card)),
|
||||
)
|
||||
}.let { PlayerList(it) }
|
||||
|
||||
operator fun plus(player: Player): PlayerList =
|
||||
PlayerList(players + player)
|
||||
}
|
||||
|
||||
private inline fun <V> Set<V>.withReplacedValue(
|
||||
toReplace: V,
|
||||
transform: (V) -> V,
|
||||
): Set<V> =
|
||||
map {
|
||||
if (it == toReplace) {
|
||||
transform(it)
|
||||
} else {
|
||||
it
|
||||
}
|
||||
}.toSet()
|
||||
@@ -0,0 +1,19 @@
|
||||
package eventDemo.shared.game
|
||||
|
||||
import kotlin.jvm.JvmInline
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
@JvmInline
|
||||
value class PlayerHand(
|
||||
val cards: Set<Card> = emptySet(),
|
||||
) {
|
||||
fun withNewCards(newCards: Set<Card>): PlayerHand =
|
||||
PlayerHand(cards + newCards)
|
||||
|
||||
fun withoutTheCards(newCards: Set<Card>): PlayerHand =
|
||||
PlayerHand(cards - newCards)
|
||||
|
||||
val size: Int get() =
|
||||
cards.size
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package eventDemo.shared.game.command
|
||||
|
||||
import eventDemo.shared.command.Command
|
||||
import eventDemo.shared.ids.GameId
|
||||
import eventDemo.shared.ids.UserId
|
||||
import eventDemo.shared.serializers.GameIdSerializer
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
sealed interface GameCommand : Command {
|
||||
val userId: UserId
|
||||
val payload: Payload
|
||||
|
||||
@Serializable
|
||||
sealed interface Payload {
|
||||
@Serializable(with = GameIdSerializer::class)
|
||||
val aggregateId: GameId
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package eventDemo.shared.game.command
|
||||
|
||||
import eventDemo.shared.ids.CommandId
|
||||
import eventDemo.shared.ids.GameId
|
||||
import eventDemo.shared.ids.UserId
|
||||
import eventDemo.shared.serializers.GameIdSerializer
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/**
|
||||
* A command to perform an action to play a new card
|
||||
*/
|
||||
@Serializable
|
||||
data class JoinTheGameCommand(
|
||||
override val userId: UserId,
|
||||
override val payload: Payload,
|
||||
) : GameCommand {
|
||||
override val id: CommandId = CommandId()
|
||||
|
||||
@Serializable
|
||||
data class Payload(
|
||||
@Serializable(with = GameIdSerializer::class)
|
||||
override val aggregateId: GameId,
|
||||
) : GameCommand.Payload
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package eventDemo.shared.game.command
|
||||
|
||||
import eventDemo.shared.game.Card
|
||||
import eventDemo.shared.game.Player
|
||||
import eventDemo.shared.ids.CommandId
|
||||
import eventDemo.shared.ids.GameId
|
||||
import eventDemo.shared.ids.UserId
|
||||
import eventDemo.shared.serializers.GameIdSerializer
|
||||
import eventDemo.shared.serializers.PlayerIdSerializer
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/**
|
||||
* A command to perform an action to play a new card
|
||||
*/
|
||||
@Serializable
|
||||
data class PlayCardCommand(
|
||||
override val userId: UserId,
|
||||
override val payload: Payload,
|
||||
) : GameCommand {
|
||||
override val id: CommandId = CommandId()
|
||||
|
||||
@Serializable
|
||||
data class Payload(
|
||||
@Serializable(with = GameIdSerializer::class)
|
||||
override val aggregateId: GameId,
|
||||
@Serializable(with = PlayerIdSerializer::class)
|
||||
val playerId: Player.PlayerId,
|
||||
val card: Card,
|
||||
val chosenColor: Card.Color?,
|
||||
) : GameCommand.Payload
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package eventDemo.shared.game.command
|
||||
|
||||
import eventDemo.shared.game.Player
|
||||
import eventDemo.shared.ids.CommandId
|
||||
import eventDemo.shared.ids.GameId
|
||||
import eventDemo.shared.ids.UserId
|
||||
import eventDemo.shared.serializers.GameIdSerializer
|
||||
import eventDemo.shared.serializers.PlayerIdSerializer
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/**
|
||||
* A command to set as ready to play
|
||||
*/
|
||||
@Serializable
|
||||
data class ReadyToPlayCommand(
|
||||
override val userId: UserId,
|
||||
override val payload: Payload,
|
||||
) : GameCommand {
|
||||
override val id: CommandId = CommandId()
|
||||
|
||||
@Serializable
|
||||
data class Payload(
|
||||
@Serializable(with = GameIdSerializer::class)
|
||||
override val aggregateId: GameId,
|
||||
@Serializable(with = PlayerIdSerializer::class)
|
||||
val playerId: Player.PlayerId,
|
||||
) : GameCommand.Payload
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
package eventDemo.shared.game.command
|
||||
|
||||
import eventDemo.shared.game.Player
|
||||
import eventDemo.shared.ids.CommandId
|
||||
import eventDemo.shared.ids.GameId
|
||||
import eventDemo.shared.ids.UserId
|
||||
import eventDemo.shared.serializers.GameIdSerializer
|
||||
import eventDemo.shared.serializers.PlayerIdSerializer
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/**
|
||||
* A command to draw card on draw pile.
|
||||
*
|
||||
* Is can be triggered when you cannot play any card in your hand.
|
||||
*/
|
||||
@Serializable
|
||||
data class TakeCartFromDrawPileCommand(
|
||||
override val userId: UserId,
|
||||
override val payload: Payload,
|
||||
) : GameCommand {
|
||||
override val id: CommandId = CommandId()
|
||||
|
||||
@Serializable
|
||||
data class Payload(
|
||||
@Serializable(with = GameIdSerializer::class)
|
||||
override val aggregateId: GameId,
|
||||
@Serializable(with = PlayerIdSerializer::class)
|
||||
val playerId: Player.PlayerId,
|
||||
) : GameCommand.Payload
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package eventDemo.shared.game.notification
|
||||
|
||||
import eventDemo.shared.game.Player
|
||||
import eventDemo.shared.serializers.UUIDSerializer
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlin.uuid.Uuid
|
||||
|
||||
@Serializable
|
||||
data class ItsTheTurnOfNotification(
|
||||
@Serializable(with = UUIDSerializer::class)
|
||||
override val id: Uuid = Uuid.random(),
|
||||
val player: Player,
|
||||
) : Notification
|
||||
@@ -0,0 +1,11 @@
|
||||
package eventDemo.shared.game.notification
|
||||
|
||||
import eventDemo.shared.serializers.UUIDSerializer
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlin.uuid.Uuid
|
||||
|
||||
@Serializable
|
||||
sealed interface Notification {
|
||||
@Serializable(with = UUIDSerializer::class)
|
||||
val id: Uuid
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
package eventDemo.shared.game.notification
|
||||
|
||||
import eventDemo.shared.serializers.UUIDSerializer
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlin.uuid.Uuid
|
||||
|
||||
@Serializable
|
||||
data class PilesShuffledNotification(
|
||||
@Serializable(with = UUIDSerializer::class)
|
||||
override val id: Uuid = Uuid.random(),
|
||||
) : Notification
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package eventDemo.shared.game.notification
|
||||
|
||||
import eventDemo.shared.game.Player
|
||||
import eventDemo.shared.serializers.UUIDSerializer
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlin.uuid.Uuid
|
||||
|
||||
@Serializable
|
||||
data class PlayerAsJoinTheGameNotification(
|
||||
@Serializable(with = UUIDSerializer::class)
|
||||
override val id: Uuid = Uuid.random(),
|
||||
val player: Player,
|
||||
) : Notification
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
package eventDemo.shared.game.notification
|
||||
|
||||
import eventDemo.shared.game.Card
|
||||
import eventDemo.shared.game.Player
|
||||
import eventDemo.shared.serializers.UUIDSerializer
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlin.uuid.Uuid
|
||||
|
||||
@Serializable
|
||||
data class PlayerAsPlayACardNotification(
|
||||
@Serializable(with = UUIDSerializer::class)
|
||||
override val id: Uuid = Uuid.random(),
|
||||
val playerId: Player.PlayerId,
|
||||
val card: Card,
|
||||
) : Notification
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package eventDemo.shared.game.notification
|
||||
|
||||
import eventDemo.shared.game.Player
|
||||
import eventDemo.shared.serializers.UUIDSerializer
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlin.uuid.Uuid
|
||||
|
||||
@Serializable
|
||||
data class PlayerHavePassNotification(
|
||||
@Serializable(with = UUIDSerializer::class)
|
||||
override val id: Uuid = Uuid.random(),
|
||||
val playerId: Player.PlayerId,
|
||||
) : Notification
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package eventDemo.shared.game.notification
|
||||
|
||||
import eventDemo.shared.game.Player
|
||||
import eventDemo.shared.serializers.UUIDSerializer
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlin.uuid.Uuid
|
||||
|
||||
@Serializable
|
||||
data class PlayerWasReadyNotification(
|
||||
@Serializable(with = UUIDSerializer::class)
|
||||
override val id: Uuid = Uuid.random(),
|
||||
val playerId: Player.PlayerId,
|
||||
) : Notification
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package eventDemo.shared.game.notification
|
||||
|
||||
import eventDemo.shared.game.Player
|
||||
import eventDemo.shared.serializers.UUIDSerializer
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlin.uuid.Uuid
|
||||
|
||||
@Serializable
|
||||
data class PlayerWinNotification(
|
||||
@Serializable(with = UUIDSerializer::class)
|
||||
override val id: Uuid = Uuid.random(),
|
||||
val playerId: Player.PlayerId,
|
||||
) : Notification
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package eventDemo.shared.game.notification
|
||||
|
||||
import eventDemo.shared.game.Card
|
||||
import eventDemo.shared.serializers.UUIDSerializer
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlin.uuid.Uuid
|
||||
|
||||
@Serializable
|
||||
data class TheGameWasStartedNotification(
|
||||
@Serializable(with = UUIDSerializer::class)
|
||||
override val id: Uuid = Uuid.random(),
|
||||
val hand: Set<Card>,
|
||||
) : Notification
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package eventDemo.shared.game.notification
|
||||
|
||||
import eventDemo.shared.game.Player
|
||||
import eventDemo.shared.serializers.UUIDSerializer
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlin.uuid.Uuid
|
||||
|
||||
@Serializable
|
||||
data class WelcomeToTheGameNotification(
|
||||
@Serializable(with = UUIDSerializer::class)
|
||||
override val id: Uuid = Uuid.random(),
|
||||
val players: Set<Player>,
|
||||
) : Notification
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package eventDemo.shared.game.notification
|
||||
|
||||
import eventDemo.shared.game.Card
|
||||
import eventDemo.shared.serializers.UUIDSerializer
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlin.uuid.Uuid
|
||||
|
||||
@Serializable
|
||||
data class YourNewCardNotification(
|
||||
@Serializable(with = UUIDSerializer::class)
|
||||
override val id: Uuid = Uuid.random(),
|
||||
val cards: Set<Card>,
|
||||
) : Notification
|
||||
@@ -0,0 +1,23 @@
|
||||
package eventDemo.shared.game.projection
|
||||
|
||||
import eventDemo.shared.game.Player
|
||||
import eventDemo.shared.ids.GameId
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/**
|
||||
* This [projection][GameProjection] is used to list all current games
|
||||
*/
|
||||
@Serializable
|
||||
data class GameList(
|
||||
val aggregateId: GameId,
|
||||
val status: Status = Status.OPENING,
|
||||
val players: Set<Player> = emptySet(),
|
||||
val winners: Set<Player.PlayerId> = emptySet(),
|
||||
) : GameProjection {
|
||||
enum class Status {
|
||||
OPENING,
|
||||
IS_STARTED,
|
||||
FINISH,
|
||||
CANCELED,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package eventDemo.shared.game.projection
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
sealed interface GameProjection
|
||||
@@ -0,0 +1,19 @@
|
||||
package eventDemo.shared.http
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
class HttpErrorBadRequest(
|
||||
val title: String = "Bad Request",
|
||||
val invalidParams: List<InvalidParam> = emptyList(),
|
||||
) {
|
||||
// Hardcoded rather than derived from io.ktor.http.HttpStatusCode.BadRequest, since `shared`
|
||||
// (multiplatform, no Ktor dependency) cannot depend on the Ktor server APIs backend uses.
|
||||
val statusCode: Int = 400
|
||||
|
||||
@Serializable
|
||||
data class InvalidParam(
|
||||
val name: String,
|
||||
val reason: String,
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package eventDemo.shared.ids
|
||||
|
||||
import kotlin.uuid.Uuid
|
||||
|
||||
/**
|
||||
* Represent an ID for one aggregate, and it used in events
|
||||
* @see eventDemo.libs.eventSource.Event
|
||||
*/
|
||||
interface AggregateId {
|
||||
val id: Uuid
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package eventDemo.shared.ids
|
||||
|
||||
import eventDemo.shared.serializers.CommandIdSerializer
|
||||
import kotlin.jvm.JvmInline
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlin.uuid.Uuid
|
||||
|
||||
/**
|
||||
* An ID for the [eventDemo.shared.command.Command]
|
||||
*/
|
||||
@JvmInline
|
||||
@Serializable(with = CommandIdSerializer::class)
|
||||
value class CommandId(
|
||||
private val id: Uuid = Uuid.random(),
|
||||
) {
|
||||
constructor(id: String) : this(Uuid.parse(id))
|
||||
|
||||
override fun toString(): String =
|
||||
id.toString()
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package eventDemo.shared.ids
|
||||
|
||||
import eventDemo.shared.serializers.UUIDSerializer
|
||||
import kotlin.jvm.JvmInline
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlin.uuid.Uuid
|
||||
|
||||
@JvmInline
|
||||
@Serializable
|
||||
value class EventId(
|
||||
@Serializable(with = UUIDSerializer::class)
|
||||
val id: Uuid = Uuid.random(),
|
||||
)
|
||||
@@ -0,0 +1,19 @@
|
||||
package eventDemo.shared.ids
|
||||
|
||||
import eventDemo.shared.serializers.UUIDSerializer
|
||||
import kotlin.jvm.JvmInline
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlin.uuid.Uuid
|
||||
|
||||
/**
|
||||
* An [AggregateId] for a game.
|
||||
*/
|
||||
@JvmInline
|
||||
@Serializable
|
||||
value class GameId(
|
||||
@Serializable(with = UUIDSerializer::class)
|
||||
override val id: Uuid = Uuid.random(),
|
||||
) : AggregateId {
|
||||
override fun toString(): String =
|
||||
id.toString()
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package eventDemo.shared.ids
|
||||
|
||||
import eventDemo.shared.serializers.UUIDSerializer
|
||||
import kotlin.jvm.JvmInline
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlin.uuid.Uuid
|
||||
|
||||
@Serializable
|
||||
@JvmInline
|
||||
value class UserId(
|
||||
@Serializable(with = UUIDSerializer::class)
|
||||
override val id: Uuid = Uuid.random(),
|
||||
) : AggregateId
|
||||
@@ -0,0 +1,23 @@
|
||||
package eventDemo.shared.serializers
|
||||
|
||||
import eventDemo.shared.ids.CommandId
|
||||
import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.descriptors.PrimitiveKind
|
||||
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
|
||||
import kotlinx.serialization.descriptors.SerialDescriptor
|
||||
import kotlinx.serialization.encoding.Decoder
|
||||
import kotlinx.serialization.encoding.Encoder
|
||||
|
||||
object CommandIdSerializer : KSerializer<CommandId> {
|
||||
override fun deserialize(decoder: Decoder): CommandId =
|
||||
CommandId(decoder.decodeString())
|
||||
|
||||
override fun serialize(
|
||||
encoder: Encoder,
|
||||
value: CommandId,
|
||||
) {
|
||||
encoder.encodeString(value.toString())
|
||||
}
|
||||
|
||||
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("CommandId", PrimitiveKind.STRING)
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package eventDemo.shared.serializers
|
||||
|
||||
import eventDemo.shared.ids.EventId
|
||||
import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.descriptors.PrimitiveKind
|
||||
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
|
||||
import kotlinx.serialization.descriptors.SerialDescriptor
|
||||
import kotlinx.serialization.encoding.Decoder
|
||||
import kotlinx.serialization.encoding.Encoder
|
||||
import kotlin.uuid.Uuid
|
||||
|
||||
object EventIdSerializer : KSerializer<EventId> {
|
||||
override fun deserialize(decoder: Decoder): EventId =
|
||||
EventId(Uuid.parse(decoder.decodeString()))
|
||||
|
||||
override fun serialize(
|
||||
encoder: Encoder,
|
||||
value: EventId,
|
||||
) {
|
||||
encoder.encodeString(value.id.toString())
|
||||
}
|
||||
|
||||
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("EventId", PrimitiveKind.STRING)
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package eventDemo.shared.serializers
|
||||
|
||||
import eventDemo.shared.ids.GameId
|
||||
import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.descriptors.PrimitiveKind
|
||||
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
|
||||
import kotlinx.serialization.descriptors.SerialDescriptor
|
||||
import kotlinx.serialization.encoding.Decoder
|
||||
import kotlinx.serialization.encoding.Encoder
|
||||
import kotlin.uuid.Uuid
|
||||
|
||||
object GameIdSerializer : KSerializer<GameId> {
|
||||
override fun deserialize(decoder: Decoder): GameId =
|
||||
GameId(Uuid.parse(decoder.decodeString()))
|
||||
|
||||
override fun serialize(
|
||||
encoder: Encoder,
|
||||
value: GameId,
|
||||
) {
|
||||
encoder.encodeString(value.id.toString())
|
||||
}
|
||||
|
||||
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("GameId", PrimitiveKind.STRING)
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package eventDemo.shared.serializers
|
||||
|
||||
import eventDemo.shared.game.Player
|
||||
import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.descriptors.PrimitiveKind
|
||||
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
|
||||
import kotlinx.serialization.descriptors.SerialDescriptor
|
||||
import kotlinx.serialization.encoding.Decoder
|
||||
import kotlinx.serialization.encoding.Encoder
|
||||
import kotlin.uuid.Uuid
|
||||
|
||||
object PlayerIdSerializer : KSerializer<Player.PlayerId> {
|
||||
override fun deserialize(decoder: Decoder): Player.PlayerId =
|
||||
Player.PlayerId(Uuid.parse(decoder.decodeString()))
|
||||
|
||||
override fun serialize(
|
||||
encoder: Encoder,
|
||||
value: Player.PlayerId,
|
||||
) {
|
||||
encoder.encodeString(value.id.toString())
|
||||
}
|
||||
|
||||
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("PlayerId", PrimitiveKind.STRING)
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package eventDemo.shared.serializers
|
||||
|
||||
import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.descriptors.PrimitiveKind
|
||||
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
|
||||
import kotlinx.serialization.descriptors.SerialDescriptor
|
||||
import kotlinx.serialization.encoding.Decoder
|
||||
import kotlinx.serialization.encoding.Encoder
|
||||
import kotlin.uuid.Uuid
|
||||
|
||||
object UUIDSerializer : KSerializer<Uuid> {
|
||||
override fun deserialize(decoder: Decoder): Uuid =
|
||||
Uuid.parse(decoder.decodeString())
|
||||
|
||||
override fun serialize(
|
||||
encoder: Encoder,
|
||||
value: Uuid,
|
||||
) {
|
||||
encoder.encodeString(value.toString())
|
||||
}
|
||||
|
||||
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("UUID", PrimitiveKind.STRING)
|
||||
}
|
||||
Reference in New Issue
Block a user