perf(cpu): Optimized CityConstructions.containsBuildingOrEquivalent, Conditionals.conditionalApplies

This commit is contained in:
yairm210 2025-09-07 22:47:08 +03:00
parent c0674dc39f
commit de12183c53
3 changed files with 12 additions and 2 deletions

View File

@ -37,6 +37,7 @@ import com.unciv.ui.screens.civilopediascreen.FormattedLine
import com.unciv.ui.screens.pickerscreens.PromotionTree
import com.unciv.utils.withItem
import com.unciv.utils.withoutItem
import yairm210.purity.annotations.Cache
import yairm210.purity.annotations.LocalState
import yairm210.purity.annotations.Readonly
import kotlin.math.ceil
@ -59,6 +60,9 @@ class CityConstructions : IsPartOfGameInfoSerialization {
@Transient
private var builtBuildingObjects = ArrayList<Building>()
@Transient @Cache
private val containedBuildingFiltersCache = HashMap<String, Boolean>()
@Transient
val builtBuildingUniqueMap = UniqueMap()
@ -265,7 +269,10 @@ class CityConstructions : IsPartOfGameInfoSerialization {
@Readonly fun getBuiltBuildings(): Sequence<Building> = builtBuildingObjects.asSequence()
@Readonly fun containsBuildingOrEquivalent(buildingNameOrUnique: String): Boolean =
isBuilt(buildingNameOrUnique) || getBuiltBuildings().any { it.replaces == buildingNameOrUnique || it.hasUnique(buildingNameOrUnique, city.state) }
containedBuildingFiltersCache.getOrPut(buildingNameOrUnique) {
isBuilt(buildingNameOrUnique)
|| getBuiltBuildings().any { it.replaces == buildingNameOrUnique || it.hasUnique(buildingNameOrUnique, city.state) }
}
@Readonly
fun getWorkDone(constructionName: String): Int {
@ -658,6 +665,8 @@ class CityConstructions : IsPartOfGameInfoSerialization {
fun updateUniques(onLoadGame: Boolean = false) {
builtBuildingUniqueMap.clear()
containedBuildingFiltersCache.clear()
for (building in getBuiltBuildings())
builtBuildingUniqueMap.addUniques(building.uniqueObjects)
if (!onLoadGame) {

View File

@ -28,7 +28,7 @@ object Conditionals {
state: GameContext
): Boolean {
if (conditional.type?.targetTypes?.any { it.modifierType == UniqueTarget.ModifierType.Other } == true)
if (conditional.isOtherModifierType)
return true // not a filtering condition, includes e.g. ModifierHiddenFromUsers
/** Helper to simplify conditional tests requiring gameInfo */

View File

@ -43,6 +43,7 @@ class Unique(val text: String, val sourceObjectType: UniqueTarget? = null, val s
val allParams = params + modifiers.flatMap { it.params }
val isLocalEffect = params.contains("in this city") || hasModifier(UniqueType.ConditionalInThisCity)
val isOtherModifierType = type?.targetTypes?.any { it.modifierType == UniqueTarget.ModifierType.Other } == true
@Readonly fun hasFlag(flag: UniqueFlag) = type != null && type.flags.contains(flag)
@Readonly fun isHiddenToUsers() = hasFlag(UniqueFlag.HiddenToUsers) || hasModifier(UniqueType.ModifierHiddenFromUsers)