Main menu cancels background map creation when obsolete (#9072)

This commit is contained in:
SomeTroglodyte 2023-03-30 09:22:37 +02:00 committed by GitHub
parent 6fa1d61f4f
commit c5d0de8144
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 76 additions and 46 deletions

View File

@ -21,6 +21,8 @@ import com.unciv.ui.screens.mapeditorscreen.MapGeneratorSteps
import com.unciv.ui.screens.mapeditorscreen.TileInfoNormalizer import com.unciv.ui.screens.mapeditorscreen.TileInfoNormalizer
import com.unciv.utils.Log import com.unciv.utils.Log
import com.unciv.utils.debug import com.unciv.utils.debug
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.isActive
import kotlin.math.abs import kotlin.math.abs
import kotlin.math.max import kotlin.math.max
import kotlin.math.pow import kotlin.math.pow
@ -31,7 +33,8 @@ import kotlin.math.ulp
import kotlin.random.Random import kotlin.random.Random
class MapGenerator(val ruleset: Ruleset) { class MapGenerator(val ruleset: Ruleset, private val coroutineScope: CoroutineScope? = null) {
companion object { companion object {
private const val consoleTimings = false private const val consoleTimings = false
} }
@ -202,6 +205,7 @@ class MapGenerator(val ruleset: Ruleset) {
private fun runAndMeasure(text: String, action: ()->Unit) { private fun runAndMeasure(text: String, action: ()->Unit) {
if (coroutineScope?.isActive == false) return
if (!consoleTimings) return action() if (!consoleTimings) return action()
val startNanos = System.nanoTime() val startNanos = System.nanoTime()
action() action()

View File

@ -52,7 +52,8 @@ import com.unciv.ui.screens.worldscreen.WorldScreen
import com.unciv.ui.screens.worldscreen.mainmenu.WorldScreenMenuPopup import com.unciv.ui.screens.worldscreen.mainmenu.WorldScreenMenuPopup
import com.unciv.utils.concurrency.Concurrency import com.unciv.utils.concurrency.Concurrency
import com.unciv.utils.concurrency.launchOnGLThread import com.unciv.utils.concurrency.launchOnGLThread
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Job
import kotlinx.coroutines.isActive
import kotlin.math.min import kotlin.math.min
@ -63,6 +64,8 @@ class MainMenuScreen: BaseScreen(), RecreateOnResize {
private val singleColumn = isCrampedPortrait() private val singleColumn = isCrampedPortrait()
private var easterEggRuleset: Ruleset? = null // Cache it so the next 'egg' can be found in Civilopedia private var easterEggRuleset: Ruleset? = null // Cache it so the next 'egg' can be found in Civilopedia
private var backgroundMapGenerationJob: Job? = null
/** Create one **Main Menu Button** including onClick/key binding /** Create one **Main Menu Button** including onClick/key binding
* @param text The text to display on the button * @param text The text to display on the button
* @param icon The path of the icon to display on the button * @param icon The path of the icon to display on the button
@ -86,7 +89,10 @@ class MainMenuScreen: BaseScreen(), RecreateOnResize {
table.add(text.toLabel(fontSize = 30, alignment = Align.left)).expand().left().minWidth(200f) table.add(text.toLabel(fontSize = 30, alignment = Align.left)).expand().left().minWidth(200f)
table.touchable = Touchable.enabled table.touchable = Touchable.enabled
table.onActivation(function) table.onActivation {
stopBackgroundMapGeneration()
function()
}
if (key != null) { if (key != null) {
if (!keyVisualOnly) if (!keyVisualOnly)
@ -110,9 +116,7 @@ class MainMenuScreen: BaseScreen(), RecreateOnResize {
// guard in UncivGame.create, simply omit the background so the user can at least get to options // guard in UncivGame.create, simply omit the background so the user can at least get to options
// (let him crash when loading a game but avoid locking him out entirely) // (let him crash when loading a game but avoid locking him out entirely)
if (game.settings.tileSet in TileSetCache) if (game.settings.tileSet in TileSetCache)
Concurrency.run("ShowMapBackground") { startBackgroundMapGeneration()
showMapBackground()
}
val column1 = Table().apply { defaults().pad(10f).fillX() } val column1 = Table().apply { defaults().pad(10f).fillX() }
val column2 = if (singleColumn) column1 else Table().apply { defaults().pad(10f).fillX() } val column2 = if (singleColumn) column1 else Table().apply { defaults().pad(10f).fillX() }
@ -185,7 +189,9 @@ class MainMenuScreen: BaseScreen(), RecreateOnResize {
stage.addActor(helpButton) stage.addActor(helpButton)
} }
private fun CoroutineScope.showMapBackground() { private fun startBackgroundMapGeneration() {
stopBackgroundMapGeneration() // shouldn't be necessary as resize re-instantiates this class
backgroundMapGenerationJob = Concurrency.run("ShowMapBackground") {
var scale = 1f var scale = 1f
var mapWidth = stage.width / TileGroupMap.groupHorizontalAdvance var mapWidth = stage.width / TileGroupMap.groupHorizontalAdvance
var mapHeight = stage.height / TileGroupMap.groupSize var mapHeight = stage.height / TileGroupMap.groupSize
@ -202,12 +208,12 @@ class MainMenuScreen: BaseScreen(), RecreateOnResize {
} }
val mapRuleset = if (game.settings.enableEasterEggs) easterEggRuleset ?: baseRuleset else baseRuleset val mapRuleset = if (game.settings.enableEasterEggs) easterEggRuleset ?: baseRuleset else baseRuleset
val newMap = MapGenerator(mapRuleset) val newMap = MapGenerator(mapRuleset, this)
.generateMap(MapParameters().apply { .generateMap(MapParameters().apply {
shape = MapShape.rectangular shape = MapShape.rectangular
mapSize = MapSizeNew(MapSize.Small) mapSize = MapSizeNew(MapSize.Small)
type = MapType.pangaea type = MapType.pangaea
temperatureExtremeness = 0.7f temperatureExtremeness = .7f
waterThreshold = -0.1f // mainly land, gets about 30% water waterThreshold = -0.1f // mainly land, gets about 30% water
modifyForEasterEgg() modifyForEasterEgg()
}) })
@ -219,15 +225,31 @@ class MainMenuScreen: BaseScreen(), RecreateOnResize {
newMap newMap
) {} ) {}
mapHolder.setScale(scale) mapHolder.setScale(scale)
backgroundTable.addAction(Actions.sequence( backgroundTable.addAction(Actions.sequence(
Actions.fadeOut(0f), Actions.fadeOut(0f),
Actions.run { Actions.run {
backgroundTable.clearChildren()
backgroundTable.addActor(mapHolder) backgroundTable.addActor(mapHolder)
mapHolder.center(backgroundTable) mapHolder.center(backgroundTable)
}, },
Actions.fadeIn(0.3f) Actions.fadeIn(0.3f)
)) ))
} }
}.apply {
invokeOnCompletion {
backgroundMapGenerationJob = null
}
}
}
private fun stopBackgroundMapGeneration() {
val currentJob = backgroundMapGenerationJob
?: return
backgroundMapGenerationJob = null
if (currentJob.isCancelled) return
currentJob.cancel()
backgroundTable.clearActions()
} }
private fun resumeGame() { private fun resumeGame() {
@ -293,6 +315,7 @@ class MainMenuScreen: BaseScreen(), RecreateOnResize {
} }
private fun openCivilopedia() { private fun openCivilopedia() {
stopBackgroundMapGeneration()
val rulesetParameters = game.settings.lastGameSetup?.gameParameters val rulesetParameters = game.settings.lastGameSetup?.gameParameters
val ruleset = easterEggRuleset ?: val ruleset = easterEggRuleset ?:
if (rulesetParameters == null) if (rulesetParameters == null)
@ -304,5 +327,8 @@ class MainMenuScreen: BaseScreen(), RecreateOnResize {
game.pushScreen(CivilopediaScreen(ruleset)) game.pushScreen(CivilopediaScreen(ruleset))
} }
override fun recreate(): BaseScreen = MainMenuScreen() override fun recreate(): BaseScreen {
stopBackgroundMapGeneration()
return MainMenuScreen()
}
} }