From 16f0a9844c0dcfd5d54922ec6a2cef022b77a486 Mon Sep 17 00:00:00 2001 From: yairm210 Date: Sun, 15 Dec 2024 12:22:46 +0200 Subject: [PATCH] perf(tile-update): cache base data for tile rendering to only recompute when base data changes --- .../tilegroups/layers/TileLayerCityButton.kt | 11 ++++--- .../tilegroups/layers/TileLayerTerrain.kt | 31 ++++++++++++++++++- 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/core/src/com/unciv/ui/components/tilegroups/layers/TileLayerCityButton.kt b/core/src/com/unciv/ui/components/tilegroups/layers/TileLayerCityButton.kt index 6941f5f028..5a1ac595b3 100644 --- a/core/src/com/unciv/ui/components/tilegroups/layers/TileLayerCityButton.kt +++ b/core/src/com/unciv/ui/components/tilegroups/layers/TileLayerCityButton.kt @@ -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) { diff --git a/core/src/com/unciv/ui/components/tilegroups/layers/TileLayerTerrain.kt b/core/src/com/unciv/ui/components/tilegroups/layers/TileLayerTerrain.kt index e6686ba37f..2c2d77ce62 100644 --- a/core/src/com/unciv/ui/components/tilegroups/layers/TileLayerTerrain.kt +++ b/core/src/com/unciv/ui/components/tilegroups/layers/TileLayerTerrain.kt @@ -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 { 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, + + ) private fun updateTileImage(viewingCiv: Civilization?) { + val tileBaseImageLocations = getTileBaseImageLocations(viewingCiv) if (tileBaseImageLocations.size == tileImageIdentifiers.size) {