Performance optimization: don't draw empty tile layers (#8538)

Co-authored-by: tunerzinc@gmail.com <vfylfhby>
This commit is contained in:
vegeta1k95 2023-02-02 08:05:48 +01:00 committed by GitHub
parent a84470c74e
commit daef1e0769
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 97 additions and 43 deletions

View File

@ -2,6 +2,7 @@ package com.unciv.ui.tilegroups
import com.unciv.UncivGame
import com.unciv.logic.city.City
import com.unciv.logic.civilization.Civilization
import com.unciv.logic.map.tile.Tile
import com.unciv.ui.images.ImageGetter
@ -14,8 +15,8 @@ class CityTileGroup(private val city: City, tile: Tile, tileSetStrings: TileSetS
layerMisc.setNewPopulationIcon(ImageGetter.getImage("OtherIcons/Star"))
}
fun update() {
super.update(city.civInfo, showResourcesAndImprovements = true, showTileYields = true)
override fun update(viewingCiv: Civilization?) {
super.update(city.civInfo)
when {

View File

@ -84,7 +84,7 @@ open class TileGroup(
layerOverlay.setFog(true)
}
open fun update(viewingCiv: Civilization? = null, showResourcesAndImprovements: Boolean = true, showTileYields: Boolean = true) {
open fun update(viewingCiv: Civilization? = null) {
layerOverlay.hideHighlight()
layerOverlay.hideCrosshair()
@ -110,13 +110,13 @@ open class TileGroup(
removeMissingModReferences()
layerTerrain.update(viewingCiv)
layerFeatures.update()
layerBorders.update()
layerFeatures.update(viewingCiv)
layerBorders.update(viewingCiv)
layerOverlay.update(viewingCiv)
layerMisc.update(viewingCiv, showResourcesAndImprovements, showTileYields)
layerMisc.update(viewingCiv)
layerUnitArt.update(viewingCiv)
layerUnitFlag.update(viewingCiv)
layerCityButton.update(viewingCiv)
}
private fun removeMissingModReferences() {

View File

@ -10,13 +10,12 @@ import com.unciv.ui.worldscreen.WorldScreen
class WorldTileGroup(internal val worldScreen: WorldScreen, tile: Tile, tileSetStrings: TileSetStrings)
: TileGroup(tile,tileSetStrings) {
fun update(viewingCiv: Civilization) {
override fun update(viewingCiv: Civilization?) {
layerMisc.removePopulationIcon()
val city = tile.getCity()
val tileIsViewable = isViewable(viewingCiv)
val showEntireMap = UncivGame.Current.viewEntireMapForDebug
val tileIsViewable = isViewable(viewingCiv!!)
// Show population icon overlay (if option is enabled)
if (tileIsViewable && tile.isWorked() && UncivGame.Current.settings.showWorkedTiles
@ -24,18 +23,7 @@ class WorldTileGroup(internal val worldScreen: WorldScreen, tile: Tile, tileSetS
layerMisc.setNewPopulationIcon()
}
// Update city buttons in explored tiles or entire map
// needs to be before the update so the units will be above the city button
if (showEntireMap || viewingCiv.hasExplored(tile) || viewingCiv.isSpectator()
|| (worldScreen.viewingCiv.isSpectator() && !worldScreen.fogOfWar)) {
layerCityButton.update(city, tileIsViewable || showEntireMap)
}
// Remove city buttons in unexplored tiles during spectating and fog of war enabled
else if (worldScreen.viewingCiv.isSpectator() && worldScreen.fogOfWar) {
layerCityButton.update(null, showEntireMap)
}
super.update(viewingCiv, UncivGame.Current.settings.showResourcesAndImprovements, UncivGame.Current.settings.showTileYields)
super.update(viewingCiv)
}

View File

@ -2,14 +2,13 @@ package com.unciv.ui.tilegroups.layers
import com.badlogic.gdx.scenes.scene2d.Group
import com.badlogic.gdx.scenes.scene2d.ui.Image
import com.unciv.UncivGame
import com.unciv.logic.civilization.Civilization
import com.unciv.logic.map.tile.Tile
import com.unciv.models.tilesets.TileSetCache
import com.unciv.ui.tilegroups.TileGroup
import com.unciv.ui.tilegroups.TileSetStrings
open class TileLayer(val tileGroup: TileGroup, size: Float) : Group() {
abstract class TileLayer(val tileGroup: TileGroup, size: Float) : Group() {
init {
isTransform = false
@ -31,4 +30,15 @@ open class TileLayer(val tileGroup: TileGroup, size: Float) : Group() {
fun isViewable(viewingCiv: Civilization) = tileGroup.isViewable(viewingCiv)
fun update(viewingCiv: Civilization?) {
doUpdate(viewingCiv)
determineVisibility()
}
protected open fun determineVisibility() {
isVisible = hasChildren()
}
protected abstract fun doUpdate(viewingCiv: Civilization?)
}

View File

@ -32,7 +32,7 @@ class TileLayerBorders(tileGroup: TileGroup, size: Float) : TileLayer(tileGroup,
}
}
fun update() {
private fun updateBorders() {
// This is longer than it could be, because of performance -
// before fixing, about half (!) the time of update() was wasted on
@ -135,4 +135,8 @@ class TileLayerBorders(tileGroup: TileGroup, size: Float) : TileLayer(tileGroup,
}
override fun doUpdate(viewingCiv: Civilization?) {
updateBorders()
}
}

View File

@ -4,10 +4,11 @@ import com.badlogic.gdx.graphics.g2d.Batch
import com.badlogic.gdx.scenes.scene2d.Actor
import com.badlogic.gdx.scenes.scene2d.Touchable
import com.badlogic.gdx.utils.Align
import com.unciv.logic.city.City
import com.unciv.logic.map.tile.Tile
import com.unciv.UncivGame
import com.unciv.logic.civilization.Civilization
import com.unciv.ui.tilegroups.CityButton
import com.unciv.ui.tilegroups.TileGroup
import com.unciv.ui.tilegroups.WorldTileGroup
class TileLayerCityButton(tileGroup: TileGroup, size: Float) : TileLayer(tileGroup, size) {
@ -42,7 +43,12 @@ class TileLayerCityButton(tileGroup: TileGroup, size: Float) : TileLayer(tileGro
cityButton?.moveButtonDown()
}
fun update(city: City?, viewable: Boolean) {
override fun doUpdate(viewingCiv: Civilization?) {
if (tileGroup !is WorldTileGroup)
return
val city = tile().getCity()
// There used to be a city here but it was razed
if (city == null && cityButton != null) {
@ -50,6 +56,12 @@ class TileLayerCityButton(tileGroup: TileGroup, size: Float) : TileLayer(tileGro
cityButton = null
}
if (viewingCiv == null)
return
val tileIsViewable = isViewable(viewingCiv)
val shouldShow = UncivGame.Current.viewEntireMapForDebug
// Create (if not yet) and update city button
if (city != null && tileGroup.tile.isCityCenter()) {
if (cityButton == null) {
@ -57,7 +69,7 @@ class TileLayerCityButton(tileGroup: TileGroup, size: Float) : TileLayer(tileGro
addActor(cityButton)
}
cityButton!!.update(viewable)
cityButton!!.update(shouldShow || tileIsViewable)
}
}

View File

@ -2,6 +2,7 @@ package com.unciv.ui.tilegroups.layers
import com.badlogic.gdx.scenes.scene2d.Actor
import com.badlogic.gdx.scenes.scene2d.ui.Image
import com.unciv.logic.civilization.Civilization
import com.unciv.logic.map.tile.RoadStatus
import com.unciv.logic.map.tile.Tile
import com.unciv.ui.images.ImageGetter
@ -68,7 +69,7 @@ class TileLayerFeatures(tileGroup: TileGroup, size: Float) : TileLayer(tileGroup
}
fun update() {
override fun doUpdate(viewingCiv: Civilization?) {
updateRoadImages()
}

View File

@ -17,6 +17,7 @@ import com.unciv.ui.tilegroups.YieldGroup
import com.unciv.ui.images.ImageGetter
import com.unciv.ui.tilegroups.TileGroup
import com.unciv.ui.tilegroups.TileSetStrings
import com.unciv.ui.tilegroups.WorldTileGroup
import com.unciv.ui.utils.extensions.center
import com.unciv.ui.utils.extensions.centerX
import com.unciv.ui.utils.extensions.darken
@ -46,7 +47,7 @@ class TileLayerMisc(tileGroup: TileGroup, size: Float) : TileLayer(tileGroup, si
override fun hit(x: Float, y: Float, touchable: Boolean): Actor? = null
private var yieldsInitialized = false
private var yields = YieldGroup()
private var yields = YieldGroup().apply { isVisible = false }
/** Array list of all arrows to draw from this tile on the next update. */
private val arrowsToDraw = ArrayList<MapArrow>()
@ -118,7 +119,7 @@ class TileLayerMisc(tileGroup: TileGroup, size: Float) : TileLayer(tileGroup, si
improvementIcon = icon
}
private fun updateResourceIcon(isVisible: Boolean) {
private fun updateResourceIcon(viewingCiv: Civilization?, isVisible: Boolean) {
// If resource has changed (e.g. tech researched) - add new icon
if (resourceName != tile().resource) {
@ -139,7 +140,8 @@ class TileLayerMisc(tileGroup: TileGroup, size: Float) : TileLayer(tileGroup, si
// This could happen on any turn, since resources need certain techs to reveal them
resourceIcon?.isVisible = when {
tileGroup.isForceVisible -> isVisible
isVisible && tile().hasViewableResource(UncivGame.Current.worldScreen!!.viewingCiv) -> true
isVisible && viewingCiv == null -> true
isVisible && tile().hasViewableResource(viewingCiv!!) -> true
else -> false
}
}
@ -282,17 +284,35 @@ class TileLayerMisc(tileGroup: TileGroup, size: Float) : TileLayer(tileGroup, si
yields.isVisible = isVisible
}
fun update(viewingCiv: Civilization?, showResourcesAndImprovements: Boolean, showTileYields: Boolean) {
override fun doUpdate(viewingCiv: Civilization?) {
var showResourcesAndImprovements = true
var showTileYields = true
if (tileGroup is WorldTileGroup) {
showResourcesAndImprovements = UncivGame.Current.settings.showResourcesAndImprovements
showTileYields = UncivGame.Current.settings.showTileYields
}
updateImprovementIcon(viewingCiv, showResourcesAndImprovements)
updateYieldIcon(viewingCiv, showTileYields)
updateResourceIcon(showResourcesAndImprovements)
updateResourceIcon(viewingCiv, showResourcesAndImprovements)
updateStartingLocationIcon(showResourcesAndImprovements)
updateArrows()
}
override fun determineVisibility() {
isVisible = yields.isVisible
|| resourceIcon?.isVisible == true
|| improvementIcon != null
|| populationIcon != null
|| arrows.isNotEmpty()
|| startingLocationIcons.isNotEmpty()
}
fun reset() {
updateImprovementIcon(null, false)
updateResourceIcon(false)
updateResourceIcon(null, false)
updateStartingLocationIcon(false)
}

View File

@ -32,30 +32,36 @@ class TileLayerOverlay(tileGroup: TileGroup, size: Float) : TileLayer(tileGroup,
fun showCrosshair(alpha: Float = 1f) {
crosshair.isVisible = true
crosshair.color.a = alpha
determineVisibility()
}
fun hideCrosshair() {
crosshair.isVisible = false
determineVisibility()
}
fun setFog(isVisible: Boolean) {
fog.isVisible = isVisible && !tileGroup.isForceVisible
determineVisibility()
}
fun showHighlight(color: Color, alpha: Float = 0.3f) {
highlight.isVisible = true
highlight.color = color.cpy().apply { a = alpha }
determineVisibility()
}
fun showHighlight() {
highlight.isVisible = true
determineVisibility()
}
fun hideHighlight() {
highlight.isVisible = false
determineVisibility()
}
fun update(viewingCiv: Civilization?) {
override fun doUpdate(viewingCiv: Civilization?) {
val isViewable = viewingCiv == null || isViewable(viewingCiv)
setFog(!isViewable)
@ -68,4 +74,8 @@ class TileLayerOverlay(tileGroup: TileGroup, size: Float) : TileLayer(tileGroup,
showHighlight(Color.RED)
}
override fun determineVisibility() {
isVisible = fog.isVisible || highlight.isVisible || crosshair.isVisible
}
}

View File

@ -182,7 +182,7 @@ class TileLayerTerrain(tileGroup: TileGroup, size: Float) : TileLayer(tileGroup,
}
}
fun update(viewingCiv: Civilization?) {
override fun doUpdate(viewingCiv: Civilization?) {
updateTileImage(viewingCiv)
updateRivers(tileGroup.tile.hasBottomRightRiver, tileGroup.tile.hasBottomRiver, tileGroup.tile.hasBottomLeftRiver)
updateTileColor(viewingCiv == null || isViewable(viewingCiv))

View File

@ -15,9 +15,12 @@ class TileLayerUnitArt(tileGroup: TileGroup, size: Float) : TileLayer(tileGroup,
private var locations = Array(2){""}
private var slot1: Group = Group()
private var slot2: Group = Group()
init {
addActor(Group())
addActor(Group())
addActor(slot1)
addActor(slot2)
}
private fun showMilitaryUnit(viewingCiv: Civilization) = tileGroup.isForceVisible
@ -36,7 +39,8 @@ class TileLayerUnitArt(tileGroup: TileGroup, size: Float) : TileLayer(tileGroup,
if (locations[index] != "$nationName$location") {
locations[index] = "$nationName$location"
val group: Group = getChild(index) as Group
val group: Group = if (index == 0) slot1 else slot2
group.clear()
if (location != "" && ImageGetter.imageExists(location)) {
@ -59,7 +63,7 @@ class TileLayerUnitArt(tileGroup: TileGroup, size: Float) : TileLayer(tileGroup,
color.a = 0.5f
}
fun update(viewingCiv: Civilization?) {
override fun doUpdate(viewingCiv: Civilization?) {
val slot1Unit = tileGroup.tile.civilianUnit
val slot2Unit = tileGroup.tile.militaryUnit
@ -75,6 +79,10 @@ class TileLayerUnitArt(tileGroup: TileGroup, size: Float) : TileLayer(tileGroup,
updateSlot(1, slot2Unit, isShown = isSlot2Shown)
}
override fun determineVisibility() {
isVisible = slot1.hasChildren() || slot2.hasChildren()
}
fun reset() {
updateSlot(0, null, false)
updateSlot(1, null, false)

View File

@ -134,7 +134,7 @@ class TileLayerUnitFlag(tileGroup: TileGroup, size: Float) : TileLayer(tileGroup
}
fun update(viewingCiv: Civilization?) {
override fun doUpdate(viewingCiv: Civilization?) {
clearSlots()
fillSlots(viewingCiv)