chore: Readonly 3

This commit is contained in:
yairm210 2025-07-14 12:48:17 +03:00
parent 87c096b085
commit 7e1cc64ca7
5 changed files with 39 additions and 4 deletions

View File

@ -47,9 +47,17 @@ allprojects {
apply(plugin = "io.github.yairm210.purity-plugin")
configure<yairm210.purity.PurityConfiguration>{
wellKnownPureFunctions = setOf()
wellKnownPureFunctions = setOf(
"kotlin.let",
"kotlin.run",
"kotlin.also",
"kotlin.apply",
"kotlin.takeIf",
"kotlin.takeUnless",
)
wellKnownReadonlyFunctions = setOf(
"kotlin.collections.any",
"kotlin.collections.get",
"kotlin.collections.all",
"kotlin.ranges.coerceAtLeast",
// Looks like the Collection.contains is not considered overridden :thunk:

View File

@ -56,6 +56,7 @@ import com.unciv.models.translations.tr
import com.unciv.ui.components.extensions.toPercent
import com.unciv.ui.screens.victoryscreen.RankingType
import org.jetbrains.annotations.VisibleForTesting
import yairm210.purity.annotations.Readonly
import kotlin.math.max
import kotlin.math.min
import kotlin.math.roundToInt
@ -323,7 +324,9 @@ class Civilization : IsPartOfGameInfoSerialization {
if (!knows(civInfo)) diplomacyFunctions.makeCivilizationsMeet(civInfo)
return getDiplomacyManager(civInfo.civName)!!
}
@Readonly
fun getDiplomacyManager(civInfo: Civilization): DiplomacyManager? = getDiplomacyManager(civInfo.civName)
@Readonly
fun getDiplomacyManager(civName: String): DiplomacyManager? = diplomacy[civName]
fun getProximity(civInfo: Civilization) = getProximity(civInfo.civName)

View File

@ -283,12 +283,18 @@ class Tile : IsPartOfGameInfoSerialization, Json.Serializable {
fun hasImprovementInProgress() = improvementQueue.isNotEmpty()
@Readonly
fun getTileImprovement(): TileImprovement? = if (improvement == null) null else ruleset.tileImprovements[improvement!!]
@Readonly
fun isPillaged(): Boolean = improvementIsPillaged || roadIsPillaged
@Readonly
fun getUnpillagedTileImprovement(): TileImprovement? = if (getUnpillagedImprovement() == null) null else ruleset.tileImprovements[improvement!!]
@Readonly
fun getTileImprovementInProgress(): TileImprovement? = improvementQueue.firstOrNull()?.let { ruleset.tileImprovements[it.improvement] }
@Readonly
fun containsGreatImprovement() = getTileImprovement()?.isGreatImprovement() == true
@Readonly
fun getImprovementToPillage(): TileImprovement? {
if (canPillageTileImprovement())
return ruleset.tileImprovements[improvement]!!
@ -297,6 +303,7 @@ class Tile : IsPartOfGameInfoSerialization, Json.Serializable {
return null
}
// same as above, but slightly quicker
@Readonly
fun getImprovementToPillageName(): String? {
if (canPillageTileImprovement())
return improvement
@ -304,6 +311,7 @@ class Tile : IsPartOfGameInfoSerialization, Json.Serializable {
return roadStatus.name
return null
}
@Readonly
fun getImprovementToRepair(): TileImprovement? {
if (improvement != null && improvementIsPillaged)
return ruleset.tileImprovements[improvement]!!
@ -311,24 +319,30 @@ class Tile : IsPartOfGameInfoSerialization, Json.Serializable {
return ruleset.tileImprovements[roadStatus.name]!!
return null
}
@Readonly
fun canPillageTile(): Boolean {
return canPillageTileImprovement() || canPillageRoad()
}
@Readonly
fun canPillageTileImprovement(): Boolean {
return improvement != null && !improvementIsPillaged
&& !ruleset.tileImprovements[improvement]!!.hasUnique(UniqueType.Unpillagable)
&& !ruleset.tileImprovements[improvement]!!.hasUnique(UniqueType.Irremovable)
}
@Readonly
fun canPillageRoad(): Boolean {
return roadStatus != RoadStatus.None && !roadIsPillaged
&& !ruleset.tileImprovements[roadStatus.name]!!.hasUnique(UniqueType.Unpillagable)
&& !ruleset.tileImprovements[roadStatus.name]!!.hasUnique(UniqueType.Irremovable)
}
@Readonly
fun getUnpillagedImprovement(): String? = if (improvementIsPillaged) null else improvement
/** @return [RoadStatus] on this [Tile], pillaged road counts as [RoadStatus.None] */
@Readonly
fun getUnpillagedRoad(): RoadStatus = if (roadIsPillaged) RoadStatus.None else roadStatus
@Readonly
fun getUnpillagedRoadImprovement(): TileImprovement? {
return if (getUnpillagedRoad() == RoadStatus.None) null
else ruleset.tileImprovements[getUnpillagedRoad().name]
@ -491,7 +505,7 @@ class Tile : IsPartOfGameInfoSerialization, Json.Serializable {
return MultiFilter.multiFilter(filter, { matchesSingleFilter(it, civInfo) })
}
@Readonly @Suppress("purity")
@Readonly
private fun matchesSingleFilter(filter: String, civInfo: Civilization? = null): Boolean {
if (matchesSingleTerrainFilter(filter, civInfo)) return true
if ((improvement == null || improvementIsPillaged) && filter == "unimproved") return true
@ -507,8 +521,8 @@ class Tile : IsPartOfGameInfoSerialization, Json.Serializable {
return if (multiFilter) MultiFilter.multiFilter(filter, { matchesSingleTerrainFilter(it, observingCiv) })
else matchesSingleTerrainFilter(filter, observingCiv)
}
@Readonly @Suppress("purity")
private fun matchesSingleTerrainFilter(filter: String, observingCiv: Civilization?): Boolean {
// Constant strings get their own 'when' for performance -
// see https://yairm210.medium.com/kotlin-when-string-optimization-e15c6eea2734

View File

@ -14,6 +14,7 @@ import com.unciv.models.ruleset.unit.BaseUnit
import com.unciv.ui.components.extensions.toPercent
import com.unciv.ui.objectdescriptions.ImprovementDescriptions
import com.unciv.ui.screens.civilopediascreen.FormattedLine
import yairm210.purity.annotations.Readonly
import kotlin.math.roundToInt
class TileImprovement : RulesetStatsObject() {
@ -50,8 +51,11 @@ class TileImprovement : RulesetStatsObject() {
fun getDescription(ruleset: Ruleset): String = ImprovementDescriptions.getDescription(this, ruleset)
fun getShortDecription() = ImprovementDescriptions.getShortDescription(this)
@Readonly
fun isGreatImprovement() = hasUnique(UniqueType.GreatImprovement)
@Readonly
fun isRoad() = RoadStatus.entries.any { it != RoadStatus.None && it.name == this.name }
@Readonly
fun isAncientRuinsEquivalent() = hasUnique(UniqueType.IsAncientRuinsEquivalent)
fun canBeBuiltOn(terrain: String): Boolean {
@ -77,6 +81,7 @@ class TileImprovement : RulesetStatsObject() {
/** Implements [UniqueParameterType.ImprovementFilter][com.unciv.models.ruleset.unique.UniqueParameterType.ImprovementFilter] */
@Readonly
fun matchesFilter(filter: String, tileState: GameContext? = null, multiFilter: Boolean = true): Boolean {
return if (multiFilter) MultiFilter.multiFilter(filter, {
matchesSingleFilter(it) ||
@ -88,6 +93,7 @@ class TileImprovement : RulesetStatsObject() {
tileState == null && hasTagUnique(filter)
}
@Readonly
private fun matchesSingleFilter(filter: String): Boolean {
return when (filter) {
"all", "All" -> true

View File

@ -8,6 +8,7 @@ import com.unciv.models.ruleset.tech.TechColumn
import com.unciv.models.ruleset.tech.Technology
import com.unciv.models.stats.INamed
import com.unciv.ui.components.extensions.toPercent
import yairm210.purity.annotations.Readonly
/**
* Common interface for all 'ruleset objects' that have Uniques, like BaseUnit, Nation, etc.
@ -48,12 +49,15 @@ interface IHasUniques : INamed {
fun getMatchingUniques(uniqueTag: String, state: GameContext = GameContext.EmptyState) =
uniqueMap.getMatchingUniques(uniqueTag, state)
@Readonly
fun hasUnique(uniqueType: UniqueType, state: GameContext? = null) =
uniqueMap.hasMatchingUnique(uniqueType, state ?: GameContext.EmptyState)
@Readonly
fun hasUnique(uniqueTag: String, state: GameContext? = null) =
uniqueMap.hasMatchingUnique(uniqueTag, state ?: GameContext.EmptyState)
@Readonly
fun hasTagUnique(tagUnique: String) =
uniqueMap.hasTagUnique(tagUnique)