From 2b0cc5cf90358f75cfb86e17bc08d20c5447928f Mon Sep 17 00:00:00 2001 From: yairm210 Date: Sun, 22 Dec 2024 21:40:06 +0200 Subject: [PATCH] Cache edge images for faster update()s on all tilegroups (e.g. unit click) --- .../components/tilegroups/TileSetStrings.kt | 2 +- .../tilegroups/layers/TileLayerTerrain.kt | 42 ++++++++++++++----- 2 files changed, 32 insertions(+), 12 deletions(-) diff --git a/core/src/com/unciv/ui/components/tilegroups/TileSetStrings.kt b/core/src/com/unciv/ui/components/tilegroups/TileSetStrings.kt index f6a2b776ba..57e7ba33fa 100644 --- a/core/src/com/unciv/ui/components/tilegroups/TileSetStrings.kt +++ b/core/src/com/unciv/ui/components/tilegroups/TileSetStrings.kt @@ -54,7 +54,7 @@ class TileSetStrings( // These need to be by lazy since the orFallback expects a tileset, which it may not get. val hexagon: String by lazy { orFallback { tileSetLocation + "Hexagon"} } - val hexagonList by lazy { listOf(hexagon) } + val hexagonList = listOf(hexagon) val crosshatchHexagon by lazy { orFallback { tileSetLocation + "CrosshatchHexagon" } } val unexploredTile by lazy { orFallback { tileSetLocation + "UnexploredTile" } } val crosshair by lazy { orFallback { getString(tileSetLocation, "Crosshair") } } 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 cc0cd7bf92..27723393c7 100644 --- a/core/src/com/unciv/ui/components/tilegroups/layers/TileLayerTerrain.kt +++ b/core/src/com/unciv/ui/components/tilegroups/layers/TileLayerTerrain.kt @@ -94,19 +94,33 @@ class TileLayerTerrain(tileGroup: TileGroup, size: Float) : TileLayer(tileGroup, } } + private class NeighborEdgeData(val neighbor: Tile, val direction: NeighborDirection?) { + var ourTerrains: Set = emptySet() + var neighborTerrains: Set = emptySet() + var edgeFiles: Sequence = emptySequence() + } + + private val neighborEdgeDataList: Sequence = if (!tile.isTilemapInitialized()) emptySequence() + else tile.neighbors.map { + val direction = NeighborDirection.fromVector(it.position.cpy().sub(tile.position)) + NeighborEdgeData(it, direction) + }.toList().asSequence() + + private fun getEdgeTileLocations(): Sequence { if (!tile.isTilemapInitialized()) // fake tile return emptySequence() - return tile.neighbors - .flatMap { getMatchingEdges(tile, it) } + return neighborEdgeDataList + .flatMap { getMatchingEdges(it) } } - private fun getMatchingEdges(originTile: Tile, neighborTile: Tile): Sequence{ - val vectorToNeighbor = neighborTile.position.cpy().sub(originTile.position) - val direction = NeighborDirection.fromVector(vectorToNeighbor) - ?: return emptySequence() + private fun getMatchingEdges(neighborEdgeData: NeighborEdgeData): Sequence{ + if (neighborEdgeData.ourTerrains == tile.cachedTerrainData.terrainNameSet + && neighborEdgeData.neighborTerrains == neighborEdgeData.neighbor.cachedTerrainData.terrainNameSet) + return neighborEdgeData.edgeFiles - val possibleEdgeImages = strings.edgeImagesByPosition[direction] ?: return emptySequence() + if (neighborEdgeData.direction == null) return emptySequence() + val possibleEdgeImages = strings.edgeImagesByPosition[neighborEdgeData.direction] ?: return emptySequence() // Required for performance - full matchesFilter is too expensive for something that needs to run every update() fun matchesFilterMinimal(originTile: Tile, filter: String): Boolean { @@ -115,11 +129,17 @@ class TileLayerTerrain(tileGroup: TileGroup, size: Float) : TileLayer(tileGroup, return false } - return possibleEdgeImages.asSequence().filter { - if (!matchesFilterMinimal(originTile, it.originTileFilter)) return@filter false - if (!matchesFilterMinimal(neighborTile, it.destinationTileFilter)) return@filter false + val cachedSequence = possibleEdgeImages.filter { + if (!matchesFilterMinimal(tile, it.originTileFilter)) return@filter false + if (!matchesFilterMinimal(neighborEdgeData.neighbor, it.destinationTileFilter)) return@filter false return@filter true - }.map { it.fileName } + }.map { it.fileName }.asSequence() + + neighborEdgeData.ourTerrains = tile.cachedTerrainData.terrainNameSet + neighborEdgeData.neighborTerrains = neighborEdgeData.neighbor.cachedTerrainData.terrainNameSet + neighborEdgeData.edgeFiles = cachedSequence + + return cachedSequence } private fun updateTileImage(viewingCiv: Civilization?) {