Clean and fix
This commit is contained in:
@@ -10,10 +10,15 @@ import eventDemo.app.entity.Player
|
||||
import eventDemo.app.event.GameEventStream
|
||||
import eventDemo.app.event.buildStateFromEventStream
|
||||
import eventDemo.app.event.event.GameEvent
|
||||
import eventDemo.libs.command.CommandBlock
|
||||
import io.ktor.websocket.Frame
|
||||
import kotlinx.coroutines.DelicateCoroutinesApi
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.channels.ReceiveChannel
|
||||
import kotlinx.coroutines.channels.SendChannel
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.channels.trySendBlocking
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
/**
|
||||
* Listen [GameCommand] on [GameCommandStream], check the validity and execute an action.
|
||||
@@ -22,21 +27,31 @@ import kotlinx.coroutines.runBlocking
|
||||
*/
|
||||
class GameCommandHandler(
|
||||
private val eventStream: GameEventStream,
|
||||
incoming: ReceiveChannel<Frame>,
|
||||
outgoing: SendChannel<Frame>,
|
||||
) {
|
||||
private val commandStream = GameCommandStream(incoming, outgoing)
|
||||
private val playerNotifier: (String) -> Unit = { runBlocking { outgoing.send(Frame.Text(it)) } }
|
||||
|
||||
/**
|
||||
* Init the handler
|
||||
*/
|
||||
suspend fun init(player: Player) {
|
||||
@OptIn(DelicateCoroutinesApi::class)
|
||||
fun handle(
|
||||
player: Player,
|
||||
incoming: ReceiveChannel<Frame>,
|
||||
outgoing: SendChannel<Frame>,
|
||||
): Job {
|
||||
val commandStream = GameCommandStream(incoming, outgoing)
|
||||
val playerNotifier: (String) -> Unit = { outgoing.trySendBlocking(Frame.Text(it)) }
|
||||
return GlobalScope.launch {
|
||||
init(player, commandStream, playerNotifier)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun init(
|
||||
player: Player,
|
||||
commandStream: GameCommandStream,
|
||||
playerNotifier: (String) -> Unit,
|
||||
) {
|
||||
commandStream.process { command ->
|
||||
if (command.payload.player.id != player.id) {
|
||||
runBlocking {
|
||||
nack()
|
||||
}
|
||||
nack()
|
||||
}
|
||||
|
||||
val gameState = command.buildGameState()
|
||||
@@ -47,7 +62,7 @@ class GameCommandHandler(
|
||||
is IWantToJoinTheGameCommand -> command.run(gameState, playerNotifier, eventStream)
|
||||
is ICantPlayCommand -> command.run(gameState, playerNotifier, eventStream)
|
||||
}
|
||||
}
|
||||
} as CommandBlock<GameCommand>
|
||||
}
|
||||
|
||||
private fun GameCommand.buildGameState(): GameState = payload.gameId.buildStateFromEventStream(eventStream)
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package eventDemo.app.command
|
||||
|
||||
import eventDemo.app.entity.Player
|
||||
import eventDemo.app.event.GameEventBus
|
||||
import eventDemo.app.event.GameEventStream
|
||||
import eventDemo.app.eventListener.GameEventPlayerNotificationListener
|
||||
import io.ktor.server.application.ApplicationCall
|
||||
import io.ktor.server.auth.authenticate
|
||||
@@ -10,18 +8,15 @@ import io.ktor.server.auth.jwt.JWTPrincipal
|
||||
import io.ktor.server.auth.principal
|
||||
import io.ktor.server.routing.Route
|
||||
import io.ktor.server.websocket.webSocket
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
fun Route.gameSocket(
|
||||
eventStream: GameEventStream,
|
||||
eventBus: GameEventBus,
|
||||
playerNotificationListener: GameEventPlayerNotificationListener,
|
||||
commandHandler: GameCommandHandler,
|
||||
) {
|
||||
authenticate {
|
||||
webSocket("/game") {
|
||||
launch {
|
||||
GameCommandHandler(eventStream, incoming, outgoing).init(call.getPlayer())
|
||||
}
|
||||
GameEventPlayerNotificationListener(eventBus, outgoing).init()
|
||||
commandHandler.handle(call.getPlayer(), incoming, outgoing)
|
||||
playerNotificationListener.startListening(outgoing)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,18 +2,17 @@ package eventDemo.app.event
|
||||
|
||||
import eventDemo.app.entity.GameId
|
||||
import eventDemo.app.event.event.GameEvent
|
||||
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 {
|
||||
private val eventBus: GameEventBus,
|
||||
private val eventStream: EventStream<GameEvent, GameId>,
|
||||
) : EventStream<GameEvent, GameId> by eventStream {
|
||||
override fun publish(event: GameEvent) {
|
||||
m.publish(event)
|
||||
eventStream.publish(event)
|
||||
eventBus.publish(event)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,22 +1,18 @@
|
||||
package eventDemo.app.eventListener
|
||||
|
||||
import eventDemo.app.entity.GameId
|
||||
import eventDemo.app.event.GameEventBus
|
||||
import eventDemo.app.event.event.GameEvent
|
||||
import eventDemo.libs.event.EventBus
|
||||
import eventDemo.shared.toFrame
|
||||
import io.ktor.websocket.Frame
|
||||
import kotlinx.coroutines.channels.SendChannel
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.channels.trySendBlocking
|
||||
|
||||
class GameEventPlayerNotificationListener(
|
||||
private val eventBus: EventBus<GameEvent, GameId>,
|
||||
private val outgoing: SendChannel<Frame>,
|
||||
private val eventBus: GameEventBus,
|
||||
) {
|
||||
fun init() {
|
||||
fun startListening(outgoing: SendChannel<Frame>) {
|
||||
eventBus.subscribe { event: GameEvent ->
|
||||
runBlocking {
|
||||
outgoing.send(event.toFrame())
|
||||
}
|
||||
outgoing.trySendBlocking(event.toFrame())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
package eventDemo.app.eventListener
|
||||
|
||||
import eventDemo.app.entity.GameId
|
||||
import eventDemo.app.event.GameEventBus
|
||||
import eventDemo.app.event.GameEventStream
|
||||
import eventDemo.app.event.buildStateFromEventStream
|
||||
import eventDemo.app.event.event.GameEvent
|
||||
import eventDemo.app.event.event.GameStartedEvent
|
||||
import eventDemo.libs.event.EventBus
|
||||
import eventDemo.libs.event.EventStream
|
||||
|
||||
class GameEventReactionListener(
|
||||
private val eventBus: EventBus<GameEvent, GameId>,
|
||||
private val eventStream: EventStream<GameEvent, GameId>,
|
||||
private val eventBus: GameEventBus,
|
||||
private val eventStream: GameEventStream,
|
||||
) {
|
||||
fun init() {
|
||||
eventBus.subscribe { event: GameEvent ->
|
||||
|
||||
Reference in New Issue
Block a user