Converted RulesetObject unique checks to work against a map for efficiency

This commit is contained in:
Yair Morgenstern 2022-01-26 21:10:46 +02:00
parent 231963f050
commit a56874282b
7 changed files with 32 additions and 29 deletions

View File

@ -8,8 +8,7 @@ import com.unciv.models.ruleset.unique.UniqueTarget
import com.unciv.models.stats.INamed
import com.unciv.ui.utils.colorFromRGB
class Era : INamed, IHasUniques {
override var name: String = ""
class Era : RulesetObject(), IHasUniques {
var eraNumber: Int = -1
var researchAgreementCost = 300
var startingSettlerCount = 1
@ -32,10 +31,8 @@ class Era : INamed, IHasUniques {
val allyBonusObjects: Map<CityStateType, List<Unique>> by lazy { initBonuses(allyBonus) }
var iconRGB: List<Int>? = null
override var uniques: ArrayList<String> = arrayListOf()
override fun getUniqueTarget() = UniqueTarget.Era
override val uniqueObjects: List<Unique> by lazy { uniques.map { Unique(it,
getUniqueTarget(), name) } }
override fun makeLink() = "" // No own category on Civilopedia screen
private fun initBonuses(bonusMap: Map<String, List<String>>): Map<CityStateType, List<Unique>> {
val objectMap = HashMap<CityStateType, List<Unique>>()
@ -71,7 +68,4 @@ class Era : INamed, IHasUniques {
}
fun getHexColor() = "#" + getColor().toString().substring(0, 6)
/** This is used for display purposes in templates */
override fun toString() = name
}

View File

@ -5,7 +5,6 @@ import com.unciv.models.ruleset.unique.UniqueTarget
import com.unciv.models.ruleset.unique.UniqueType
class GlobalUniques: RulesetObject() {
override var name = ""
override fun getUniqueTarget() = UniqueTarget.Global
override fun makeLink() = "" // No own category on Civilopedia screen

View File

@ -11,7 +11,9 @@ import com.unciv.models.ruleset.unique.UniqueType
interface IHasUniques {
var uniques: ArrayList<String> // Can not be a hashset as that would remove doubles
// I bet there's a way of initializing these without having to override it everywhere...
val uniqueObjects: List<Unique>
val uniqueObjects: List<Unique>
val uniqueMap: Map<String, List<Unique>>
/** Technically not currently needed, since the unique target can be retrieved from every unique in the uniqueObjects,
* But making this a function is relevant for future "unify Unciv object" plans ;)
@ -19,14 +21,14 @@ interface IHasUniques {
fun getUniqueTarget(): UniqueTarget
fun getMatchingUniques(uniqueTemplate: String, stateForConditionals: StateForConditionals? = null) =
uniqueObjects.asSequence().filter { it.placeholderText == uniqueTemplate && it.conditionalsApply(stateForConditionals) }
fun getMatchingUniques(uniqueType: UniqueType, stateForConditionals: StateForConditionals? = null) =
uniqueObjects.asSequence().filter { it.isOfType(uniqueType) && it.conditionalsApply(stateForConditionals) }
fun hasUnique(uniqueTemplate: String, stateForConditionals: StateForConditionals? = null) =
uniqueObjects.any { it.placeholderText == uniqueTemplate && it.conditionalsApply(stateForConditionals) }
fun hasUnique(uniqueType: UniqueType, stateForConditionals: StateForConditionals? = null) =
uniqueObjects.any { it.isOfType(uniqueType) && it.conditionalsApply(stateForConditionals) }
uniqueMap[uniqueTemplate]?.asSequence() ?: sequenceOf()
fun getMatchingUniques(uniqueType: UniqueType, stateForConditionals: StateForConditionals? = null) =
getMatchingUniques(uniqueType.placeholderText, stateForConditionals)
fun hasUnique(uniqueTemplate: String, stateForConditionals: StateForConditionals? = null) =
getMatchingUniques(uniqueTemplate, stateForConditionals).any()
fun hasUnique(uniqueType: UniqueType, stateForConditionals: StateForConditionals? = null) =
getMatchingUniques(uniqueType.placeholderText, stateForConditionals).any()
}

View File

@ -55,6 +55,7 @@ class ModOptions : IHasUniques {
override var uniques = ArrayList<String>()
// If this is delegated with "by lazy", the mod download process crashes and burns
override var uniqueObjects: List<Unique> = listOf()
override var uniqueMap: Map<String, List<Unique>> = mapOf()
override fun getUniqueTarget() = UniqueTarget.ModOptions
val constants = ModConstants()
@ -164,6 +165,7 @@ class Ruleset {
modOptions.constants.maxXPfromBarbarians = modOptions.constants.maxXPfromBarbarians
} catch (ex: Exception) {}
modOptions.uniqueObjects = modOptions.uniques.map { Unique(it, UniqueTarget.ModOptions) }
modOptions.uniqueMap = modOptions.uniqueObjects.groupBy { it.placeholderText }
}
val techFile = folderHandle.child("Techs.json")

View File

@ -9,12 +9,16 @@ import com.unciv.ui.civilopedia.ICivilopediaText
interface IRulesetObject:INamed, IHasUniques, ICivilopediaText
abstract class RulesetObject: IRulesetObject {
override lateinit var name: String
override var name = ""
override var uniques = ArrayList<String>() // Can not be a hashset as that would remove doubles
@delegate:Transient
override val uniqueObjects: List<Unique> by lazy {
uniques.map { Unique(it, getUniqueTarget(), name) }
}
@delegate:Transient
override val uniqueMap: Map<String, List<Unique>> by lazy {
uniqueObjects.groupBy { it.placeholderText }
}
override var civilopediaText = listOf<FormattedLine>()
override fun toString() = name
}
@ -26,5 +30,9 @@ abstract class RulesetStatsObject: NamedStats(), IRulesetObject {
override val uniqueObjects: List<Unique> by lazy {
uniques.map { Unique(it, getUniqueTarget(), name) }
}
@delegate:Transient
override val uniqueMap: Map<String, List<Unique>> by lazy {
uniqueObjects.groupBy { it.placeholderText }
}
override var civilopediaText = listOf<FormattedLine>()
}

View File

@ -1,6 +1,7 @@
package com.unciv.models.ruleset.unit
import com.unciv.models.ruleset.IHasUniques
import com.unciv.models.ruleset.RulesetObject
import com.unciv.models.ruleset.unique.Unique
import com.unciv.models.ruleset.unique.UniqueTarget
import com.unciv.models.stats.INamed
@ -18,16 +19,13 @@ enum class UnitMovementType { // The types of tiles the unit can by default ente
Air // Only city tiles and carrying units
}
class UnitType() : INamed, IHasUniques {
override lateinit var name: String
class UnitType() : RulesetObject() {
private var movementType: String? = null
private val unitMovementType: UnitMovementType? by lazy { if (movementType == null) null else UnitMovementType.valueOf(movementType!!) }
override var uniques: ArrayList<String> = ArrayList()
override fun getUniqueTarget() = UniqueTarget.UnitType
override val uniqueObjects: List<Unique> by lazy { uniques.map { Unique(it,
getUniqueTarget(), name) } }
override fun makeLink() = "" // No own category on Civilopedia screen
constructor(name: String, domain: String? = null) : this() {
this.name = name
this.movementType = domain

View File

@ -41,7 +41,7 @@ class LoadGameScreen(previousScreen:BaseScreen) : PickerScreen(disableScroll = t
val loadingPopup = Popup( this)
loadingPopup.addGoodSizedLabel("Loading...")
loadingPopup.open()
crashHandlingThread {
crashHandlingThread(name = "Load Game") {
try {
// This is what can lead to ANRs - reading the file and setting the transients, that's why this is in another thread
val loadedGame = GameSaver.loadGameByName(selectedSave)