InMemoryBattleSessionGateway.kt
package io.github.lishangbu.avalon.game.battle.engine.adapter.memory.session
import io.github.lishangbu.avalon.game.battle.engine.adapter.memory.store.InMemoryBattleSessionStore
import io.github.lishangbu.avalon.game.battle.engine.application.gateway.BattleSessionGateway
import io.github.lishangbu.avalon.game.battle.engine.core.model.BattleType
import io.github.lishangbu.avalon.game.battle.engine.core.model.UnitState
import io.github.lishangbu.avalon.game.battle.engine.core.session.BattleSession
import io.github.lishangbu.avalon.game.battle.engine.core.session.BattleSessionChoice
import io.github.lishangbu.avalon.game.battle.engine.core.session.BattleSessionFactory
import io.github.lishangbu.avalon.game.battle.engine.core.session.BattleSessionQuery
import io.github.lishangbu.avalon.game.battle.engine.core.session.BattleSessionTurnResult
import io.github.lishangbu.avalon.game.battle.engine.spi.store.BattleSessionStore
/**
* BattleSessionGateway 的内存版实现。
*
* 设计意图:
* - 为当前阶段提供最小可用的会话网关实现。
* - 适用于本地测试、单进程运行和 application 层通过 gateway 驱动 session 的场景。
*/
class InMemoryBattleSessionGateway(
private val sessionFactory: BattleSessionFactory,
private val sessionStore: BattleSessionStore = InMemoryBattleSessionStore(),
) : BattleSessionGateway {
override fun createSession(
sessionId: String,
formatId: String,
): BattleSessionQuery {
require(sessionStore.find(sessionId) == null) { "Session '$sessionId' already exists." }
val session = sessionFactory.create(sessionId, formatId)
sessionStore.save(sessionId, session)
return session.query()
}
override fun configureSession(
sessionId: String,
battleKind: BattleType,
capturableSideId: String?,
): BattleSessionQuery {
val session = requireSession(sessionId)
session.configureBattle(battleKind, capturableSideId)
return session.query()
}
override fun startSession(sessionId: String): BattleSessionQuery {
val session = requireSession(sessionId)
session.start()
return session.query()
}
override fun registerSide(
sessionId: String,
sideId: String,
): BattleSessionQuery {
val session = requireSession(sessionId)
session.registerSide(sideId)
return session.query()
}
override fun registerUnit(
sessionId: String,
sideId: String,
unit: UnitState,
active: Boolean,
): BattleSessionQuery {
val session = requireSession(sessionId)
session.registerUnit(sideId, unit, active)
return session.query()
}
override fun submitChoice(
sessionId: String,
choice: BattleSessionChoice,
): BattleSessionQuery {
val session = requireSession(sessionId)
session.submitChoice(choice)
return session.query()
}
override fun submitChoices(
sessionId: String,
choices: List<BattleSessionChoice>,
): BattleSessionQuery {
val session = requireSession(sessionId)
session.submitChoices(choices)
return session.query()
}
override fun submitReplacementChoice(
sessionId: String,
sideId: String,
incomingUnitId: String,
): BattleSessionQuery {
val session = requireSession(sessionId)
session.submitReplacementChoice(sideId, incomingUnitId)
return session.query()
}
override fun markSessionSettled(sessionId: String): BattleSessionQuery {
val session = requireSession(sessionId)
session.markSettled()
return session.query()
}
override fun resolveTurn(sessionId: String): BattleSessionTurnResult {
val session = requireSession(sessionId)
return session.resolveTurn()
}
override fun querySession(sessionId: String): BattleSessionQuery = requireSession(sessionId).query()
private fun requireSession(sessionId: String): BattleSession =
requireNotNull(sessionStore.find(sessionId)) {
"Session '$sessionId' was not found."
}
}