summaryrefslogtreecommitdiff
path: root/sw-client
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 /sw-client
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
Diffstat (limited to 'sw-client')
-rw-r--r--sw-client/build.gradle.kts3
-rw-r--r--sw-client/src/commonMain/kotlin/org/luxons/sevenwonders/client/SevenWondersClient.kt63
2 files changed, 37 insertions, 29 deletions
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