perf(tile-update): cache base data for tile rendering to only recompute when base data changes

This commit is contained in:
yairm210 2024-12-15 12:22:46 +02:00
parent ec2950305d
commit 16f0a9844c
2 changed files with 36 additions and 6 deletions

View File

@ -14,6 +14,7 @@ import com.unciv.utils.DebugUtils
class TileLayerCityButton(tileGroup: TileGroup, size: Float) : TileLayer(tileGroup, size) {
private var cityButton: CityButton? = null
val tile = tileGroup.tile
init {
touchable = Touchable.childrenOnly
@ -21,18 +22,18 @@ class TileLayerCityButton(tileGroup: TileGroup, size: Float) : TileLayer(tileGro
}
override fun act(delta: Float) {
if (tileGroup.tile.isCityCenter())
if (tile.isCityCenter())
super.act(delta)
}
override fun hit(x: Float, y: Float, touchable: Boolean): Actor? {
if (tileGroup.tile.isCityCenter())
if (tile.isCityCenter())
return super.hit(x, y, touchable)
return null
}
override fun draw(batch: Batch?, parentAlpha: Float) {
if (tileGroup.tile.isCityCenter())
if (tile.isCityCenter())
super.draw(batch, parentAlpha)
}
@ -47,7 +48,7 @@ class TileLayerCityButton(tileGroup: TileGroup, size: Float) : TileLayer(tileGro
override fun doUpdate(viewingCiv: Civilization?, localUniqueCache: LocalUniqueCache) {
if (tileGroup !is WorldTileGroup) return
val city = tile().getCity()
val city = tile.getCity()
// There used to be a city here but it was razed
if (city == null && cityButton != null) {
@ -56,7 +57,7 @@ class TileLayerCityButton(tileGroup: TileGroup, size: Float) : TileLayer(tileGro
}
if (viewingCiv == null) return
if (city == null || !tileGroup.tile.isCityCenter()) return
if (city == null || !tile.isCityCenter()) return
// Create (if not yet) and update city button
if (cityButton == null) {

View File

@ -47,6 +47,7 @@ class TileLayerTerrain(tileGroup: TileGroup, size: Float) : TileLayer(tileGroup,
return ImageGetter.imageExists(strings().getTile("$shownImprovement-Pillaged"))
}
var previousTileImageLocationData: TileImageLocationData? = null
private fun getTileBaseImageLocations(viewingCiv: Civilization?): List<String> {
val isForceVisible = tileGroup.isForceVisible
@ -75,6 +76,20 @@ class TileLayerTerrain(tileGroup: TileGroup, size: Float) : TileLayer(tileGroup,
}
}
// Anything that, if changed, would change the terrain images - optimization to avoid unnecessary work
val tileImageLocationData = TileImageLocationData(
viewingCiv,
isForceVisible,
shownImprovement,
shouldShowImprovement,
shouldShowResource,
tile.baseTerrain,
tile.naturalWonder,
tile.terrainFeatures,
)
if (previousTileImageLocationData == tileImageLocationData) return tileImageIdentifiers
else previousTileImageLocationData = tileImageLocationData
val terrainImages = if (tile.naturalWonder != null)
sequenceOf(tile.baseTerrain, tile.naturalWonder!!)
else sequenceOf(tile.baseTerrain) + tile.terrainFeatures.asSequence()
@ -88,7 +103,8 @@ class TileLayerTerrain(tileGroup: TileGroup, size: Float) : TileLayer(tileGroup,
return when {
strings().tileSetConfig.ruleVariants[allTogether] != null -> baseHexagon +
strings().tileSetConfig.ruleVariants[allTogether]!!.map { strings().getTile(it) } + edgeImages
ImageGetter.imageExists(allTogetherLocation) -> baseHexagon + allTogetherLocation + edgeImages
ImageGetter.imageExists(allTogetherLocation) ->
baseHexagon + allTogetherLocation + edgeImages
tile.naturalWonder != null -> getNaturalWonderBackupImage(baseHexagon) + edgeImages
else -> baseHexagon + getTerrainImageLocations(terrainImages) + edgeImages + getImprovementAndResourceImages(resourceAndImprovementSequence)
}
@ -121,8 +137,21 @@ class TileLayerTerrain(tileGroup: TileGroup, size: Float) : TileLayer(tileGroup,
return@filter true
}.map { it.fileName }
}
data class TileImageLocationData(
val viewingCiv: Civilization?,
val isForceVisible: Boolean,
val shownImprovement: String?,
val shouldShowImprovement: Boolean,
val shouldShowResource: Boolean,
val baseTerrain: String,
val naturalWonder: String?,
val terrainFeatures: List<String>,
)
private fun updateTileImage(viewingCiv: Civilization?) {
val tileBaseImageLocations = getTileBaseImageLocations(viewingCiv)
if (tileBaseImageLocations.size == tileImageIdentifiers.size) {