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,51 +189,69 @@ class MainMenuScreen: BaseScreen(), RecreateOnResize {
stage.addActor(helpButton) stage.addActor(helpButton)
} }
private fun CoroutineScope.showMapBackground() { private fun startBackgroundMapGeneration() {
var scale = 1f stopBackgroundMapGeneration() // shouldn't be necessary as resize re-instantiates this class
var mapWidth = stage.width / TileGroupMap.groupHorizontalAdvance backgroundMapGenerationJob = Concurrency.run("ShowMapBackground") {
var mapHeight = stage.height / TileGroupMap.groupSize var scale = 1f
if (mapWidth * mapHeight > 3000f) { // 3000 as max estimated number of tiles is arbitrary (we had typically 721 before) var mapWidth = stage.width / TileGroupMap.groupHorizontalAdvance
scale = mapWidth * mapHeight / 3000f var mapHeight = stage.height / TileGroupMap.groupSize
mapWidth /= scale if (mapWidth * mapHeight > 3000f) { // 3000 as max estimated number of tiles is arbitrary (we had typically 721 before)
mapHeight /= scale scale = mapWidth * mapHeight / 3000f
scale = min(scale, 20f) mapWidth /= scale
} mapHeight /= scale
scale = min(scale, 20f)
}
val baseRuleset = RulesetCache.getVanillaRuleset() val baseRuleset = RulesetCache.getVanillaRuleset()
easterEggRuleset = EasterEggRulesets.getTodayEasterEggRuleset()?.let { easterEggRuleset = EasterEggRulesets.getTodayEasterEggRuleset()?.let {
RulesetCache.getComplexRuleset(baseRuleset, listOf(it)) RulesetCache.getComplexRuleset(baseRuleset, listOf(it))
} }
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()
}) })
launchOnGLThread { // for GL context launchOnGLThread { // for GL context
ImageGetter.setNewRuleset(mapRuleset) ImageGetter.setNewRuleset(mapRuleset)
val mapHolder = EditorMapHolder( val mapHolder = EditorMapHolder(
this@MainMenuScreen, this@MainMenuScreen,
newMap newMap
) {} ) {}
mapHolder.setScale(scale) mapHolder.setScale(scale)
backgroundTable.addAction(Actions.sequence(
Actions.fadeOut(0f), backgroundTable.addAction(Actions.sequence(
Actions.run { Actions.fadeOut(0f),
backgroundTable.addActor(mapHolder) Actions.run {
mapHolder.center(backgroundTable) backgroundTable.clearChildren()
}, backgroundTable.addActor(mapHolder)
Actions.fadeIn(0.3f) mapHolder.center(backgroundTable)
)) },
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() {
if (GUI.isWorldLoaded()) { if (GUI.isWorldLoaded()) {
val currentTileSet = GUI.getMap().currentTileSetStrings val currentTileSet = GUI.getMap().currentTileSetStrings
@ -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()
}
} }