summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjoffrey-bion <joffrey.bion@gmail.com>2021-02-12 01:40:01 +0100
committerjoffrey-bion <joffrey.bion@gmail.com>2021-02-12 01:59:12 +0100
commitfaec8b33c0366d65848bdca264c9a3f5f5d102a6 (patch)
treec193fef242036f4d35a8dfcf4a86aff2638b49b4
parentFix pulsing red (remove incorrect preparedMove field) (diff)
downloadseven-wonders-faec8b33c0366d65848bdca264c9a3f5f5d102a6.tar.gz
seven-wonders-faec8b33c0366d65848bdca264c9a3f5f5d102a6.tar.bz2
seven-wonders-faec8b33c0366d65848bdca264c9a3f5f5d102a6.zip
Fix race when bots leave game
-rw-r--r--sw-bot/src/main/kotlin/org/luxons/sevenwonders/bot/SevenWondersBot.kt2
-rw-r--r--sw-client/build.gradle.kts3
-rw-r--r--sw-client/src/commonMain/kotlin/org/luxons/sevenwonders/client/SevenWondersClient.kt63
3 files changed, 38 insertions, 30 deletions
diff --git a/sw-bot/src/main/kotlin/org/luxons/sevenwonders/bot/SevenWondersBot.kt b/sw-bot/src/main/kotlin/org/luxons/sevenwonders/bot/SevenWondersBot.kt
index 86ade852..611c6369 100644
--- a/sw-bot/src/main/kotlin/org/luxons/sevenwonders/bot/SevenWondersBot.kt
+++ b/sw-bot/src/main/kotlin/org/luxons/sevenwonders/bot/SevenWondersBot.kt
@@ -93,7 +93,7 @@ class SevenWondersBot(
}
val lastTurn = endGameTurnInfo.await()
logger.info("BOT $player: leaving the game")
- session.leaveGame()
+ session.leaveGameAndAwaitEnd()
session.disconnect()
logger.info("BOT $player: disconnected")
lastTurn
diff --git a/sw-client/build.gradle.kts b/sw-client/build.gradle.kts
index 68953bc4..f29fcbf8 100644
--- a/sw-client/build.gradle.kts
+++ b/sw-client/build.gradle.kts
@@ -8,6 +8,9 @@ kotlin {
browser() // necessary for local dependency from JS UI module
}
sourceSets {
+ all {
+ languageSettings.useExperimentalAnnotation("kotlin.RequiresOptIn")
+ }
val commonMain by getting {
dependencies {
api(project(":sw-common-model"))
diff --git a/sw-client/src/commonMain/kotlin/org/luxons/sevenwonders/client/SevenWondersClient.kt b/sw-client/src/commonMain/kotlin/org/luxons/sevenwonders/client/SevenWondersClient.kt
index fc097d86..bf5778ad 100644
--- a/sw-client/src/commonMain/kotlin/org/luxons/sevenwonders/client/SevenWondersClient.kt
+++ b/sw-client/src/commonMain/kotlin/org/luxons/sevenwonders/client/SevenWondersClient.kt
@@ -1,7 +1,6 @@
package org.luxons.sevenwonders.client
-import kotlinx.coroutines.async
-import kotlinx.coroutines.coroutineScope
+import kotlinx.coroutines.*
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.map
@@ -150,30 +149,36 @@ class SevenWondersSession(private val stompSession: StompSessionWithKxSerializat
}
}
-suspend fun SevenWondersSession.createGameAndWaitLobby(gameName: String): LobbyDTO = coroutineScope {
- val lobbies = watchLobbyJoined()
- val joinedLobby = async { lobbies.first() }
- createGame(gameName)
- joinedLobby.await()
-}
-
-suspend fun SevenWondersSession.joinGameAndWaitLobby(gameId: Long): LobbyDTO = coroutineScope {
- val lobbies = watchLobbyJoined()
- val joinedLobby = async { lobbies.first() }
- joinGame(gameId)
- joinedLobby.await()
-}
-
-suspend fun SevenWondersSession.startGameAndAwaitFirstTurn(): PlayerTurnInfo = coroutineScope {
- val gameStartedEvents = watchGameStarted()
- val deferredFirstTurn = async { gameStartedEvents.first() }
- startGame()
- deferredFirstTurn.await()
-}
-
-suspend fun SevenWondersSession.joinGameAndWaitFirstTurn(gameId: Long): PlayerTurnInfo = coroutineScope {
- val gameStartedEvents = watchGameStarted()
- val deferredFirstTurn = async { gameStartedEvents.first() }
- joinGame(gameId)
- deferredFirstTurn.await()
-}
+suspend fun SevenWondersSession.createGameAndWaitLobby(gameName: String): LobbyDTO = doAndWaitForEvent(
+ send = { createGame(gameName) },
+ subscribe = { watchLobbyJoined() },
+)
+
+suspend fun SevenWondersSession.joinGameAndWaitLobby(gameId: Long): LobbyDTO = doAndWaitForEvent(
+ send = { joinGame(gameId) },
+ subscribe = { watchLobbyJoined() },
+)
+
+suspend fun SevenWondersSession.startGameAndAwaitFirstTurn(): PlayerTurnInfo = doAndWaitForEvent(
+ send = { startGame() },
+ subscribe = { watchGameStarted() },
+)
+
+suspend fun SevenWondersSession.joinGameAndWaitFirstTurn(gameId: Long): PlayerTurnInfo = doAndWaitForEvent(
+ send = { joinGame(gameId) },
+ subscribe = { watchGameStarted() },
+)
+
+suspend fun SevenWondersSession.leaveGameAndAwaitEnd() = doAndWaitForEvent(
+ send = { leaveGame() },
+ subscribe = { watchLobbyLeft() },
+)
+
+@OptIn(ExperimentalCoroutinesApi::class)
+private suspend fun <T> doAndWaitForEvent(send: suspend () -> Unit, subscribe: suspend () -> Flow<T>): T =
+ coroutineScope {
+ val eventsFlow = subscribe()
+ val deferredFirstEvent = async(start = CoroutineStart.UNDISPATCHED) { eventsFlow.first() }
+ send()
+ deferredFirstEvent.await()
+ }
bgstack15