EventContextAttributeReader.kt
package io.github.lishangbu.avalon.game.battle.engine.core.runtime.support
import io.github.lishangbu.avalon.game.battle.engine.core.event.EventContext
/**
* `EventContext.attributes` 的轻量类型化读取器。
*
* 设计意图:
* - 把 `Map<String, Any?>` 上常见的字符串、布尔值、数值、Map 读取逻辑集中到一处;
* - 避免条件解释器和动作执行器到处手写 `as?`、`toString()`、字符串数值解析;
* - 为 battle attribute key 常量化之后的“按类型读取”提供统一入口。
*
* 说明:
* - 这里只处理 battle 引擎执行期最常见的几类读取,不做重量级 schema 校验;
* - 对于布尔值,兼容 `Boolean`、`String("true"/"false")`、`Number(0/非0)` 三类输入;
* - 对于数值,兼容 `Number` 与可解析的字符串;
* - 读取失败时返回 `null`,由调用方决定是否提供默认值。
*/
object EventContextAttributeReader {
fun readString(
key: String,
context: EventContext,
): String? = readString(key, context.attributes)
fun readString(
key: String,
attributes: Map<String, Any?>,
): String? = attributes[key]?.toString()
fun readBoolean(
key: String,
context: EventContext,
): Boolean? = readBoolean(key, context.attributes)
fun readBoolean(
key: String,
attributes: Map<String, Any?>,
): Boolean? =
when (val value = attributes[key]) {
null -> {
null
}
is Boolean -> {
value
}
is String -> {
when {
value.equals("true", ignoreCase = true) -> true
value.equals("false", ignoreCase = true) -> false
else -> null
}
}
is Number -> {
value.toInt() != 0
}
else -> {
null
}
}
fun readInt(
key: String,
context: EventContext,
): Int? = readInt(key, context.attributes)
fun readInt(
key: String,
attributes: Map<String, Any?>,
): Int? =
when (val value = attributes[key]) {
null -> null
is Int -> value
is Number -> value.toInt()
is String -> value.toIntOrNull()
else -> null
}
fun readDouble(
key: String,
context: EventContext,
): Double? = readDouble(key, context.attributes)
fun readDouble(
key: String,
attributes: Map<String, Any?>,
): Double? =
when (val value = attributes[key]) {
null -> null
is Double -> value
is Number -> value.toDouble()
is String -> value.toDoubleOrNull()
else -> null
}
fun readMap(
key: String,
context: EventContext,
): Map<*, *>? = readMap(key, context.attributes)
fun readMap(
key: String,
attributes: Map<String, Any?>,
): Map<*, *>? = attributes[key] as? Map<*, *>
}