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.utils.Log
import com.unciv.utils.debug
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.isActive
import kotlin.math.abs
import kotlin.math.max
import kotlin.math.pow
@ -31,7 +33,8 @@ import kotlin.math.ulp
import kotlin.random.Random
class MapGenerator(val ruleset: Ruleset) {
class MapGenerator(val ruleset: Ruleset, private val coroutineScope: CoroutineScope? = null) {
companion object {
private const val consoleTimings = false
}
@ -202,6 +205,7 @@ class MapGenerator(val ruleset: Ruleset) {
private fun runAndMeasure(text: String, action: ()->Unit) {
if (coroutineScope?.isActive == false) return
if (!consoleTimings) return action()
val startNanos = System.nanoTime()
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.utils.concurrency.Concurrency
import com.unciv.utils.concurrency.launchOnGLThread
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.isActive
import kotlin.math.min
@ -63,6 +64,8 @@ class MainMenuScreen: BaseScreen(), RecreateOnResize {
private val singleColumn = isCrampedPortrait()
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
* @param text The text 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.touchable = Touchable.enabled
table.onActivation(function)
table.onActivation {
stopBackgroundMapGeneration()
function()
}
if (key != null) {
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
// (let him crash when loading a game but avoid locking him out entirely)
if (game.settings.tileSet in TileSetCache)
Concurrency.run("ShowMapBackground") {
showMapBackground()
}
startBackgroundMapGeneration()
val column1 = 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)
}
private fun CoroutineScope.showMapBackground() {
var scale = 1f
var mapWidth = stage.width / TileGroupMap.groupHorizontalAdvance
var mapHeight = stage.height / TileGroupMap.groupSize
if (mapWidth * mapHeight > 3000f) { // 3000 as max estimated number of tiles is arbitrary (we had typically 721 before)
scale = mapWidth * mapHeight / 3000f
mapWidth /= scale
mapHeight /= scale
scale = min(scale, 20f)
}
private fun startBackgroundMapGeneration() {
stopBackgroundMapGeneration() // shouldn't be necessary as resize re-instantiates this class
backgroundMapGenerationJob = Concurrency.run("ShowMapBackground") {
var scale = 1f
var mapWidth = stage.width / TileGroupMap.groupHorizontalAdvance
var mapHeight = stage.height / TileGroupMap.groupSize
if (mapWidth * mapHeight > 3000f) { // 3000 as max estimated number of tiles is arbitrary (we had typically 721 before)
scale = mapWidth * mapHeight / 3000f
mapWidth /= scale
mapHeight /= scale
scale = min(scale, 20f)
}
val baseRuleset = RulesetCache.getVanillaRuleset()
easterEggRuleset = EasterEggRulesets.getTodayEasterEggRuleset()?.let {
RulesetCache.getComplexRuleset(baseRuleset, listOf(it))
}
val mapRuleset = if (game.settings.enableEasterEggs) easterEggRuleset ?: baseRuleset else baseRuleset
val baseRuleset = RulesetCache.getVanillaRuleset()
easterEggRuleset = EasterEggRulesets.getTodayEasterEggRuleset()?.let {
RulesetCache.getComplexRuleset(baseRuleset, listOf(it))
}
val mapRuleset = if (game.settings.enableEasterEggs) easterEggRuleset ?: baseRuleset else baseRuleset
val newMap = MapGenerator(mapRuleset)
.generateMap(MapParameters().apply {
shape = MapShape.rectangular
mapSize = MapSizeNew(MapSize.Small)
type = MapType.pangaea
temperatureExtremeness = 0.7f
waterThreshold = -0.1f // mainly land, gets about 30% water
modifyForEasterEgg()
})
val newMap = MapGenerator(mapRuleset, this)
.generateMap(MapParameters().apply {
shape = MapShape.rectangular
mapSize = MapSizeNew(MapSize.Small)
type = MapType.pangaea
temperatureExtremeness = .7f
waterThreshold = -0.1f // mainly land, gets about 30% water
modifyForEasterEgg()
})
launchOnGLThread { // for GL context
ImageGetter.setNewRuleset(mapRuleset)
val mapHolder = EditorMapHolder(
this@MainMenuScreen,
newMap
) {}
mapHolder.setScale(scale)
backgroundTable.addAction(Actions.sequence(
Actions.fadeOut(0f),
Actions.run {
backgroundTable.addActor(mapHolder)
mapHolder.center(backgroundTable)
},
Actions.fadeIn(0.3f)
))
launchOnGLThread { // for GL context
ImageGetter.setNewRuleset(mapRuleset)
val mapHolder = EditorMapHolder(
this@MainMenuScreen,
newMap
) {}
mapHolder.setScale(scale)
backgroundTable.addAction(Actions.sequence(
Actions.fadeOut(0f),
Actions.run {
backgroundTable.clearChildren()
backgroundTable.addActor(mapHolder)
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() {
if (GUI.isWorldLoaded()) {
val currentTileSet = GUI.getMap().currentTileSetStrings
@ -293,6 +315,7 @@ class MainMenuScreen: BaseScreen(), RecreateOnResize {
}
private fun openCivilopedia() {
stopBackgroundMapGeneration()
val rulesetParameters = game.settings.lastGameSetup?.gameParameters
val ruleset = easterEggRuleset ?:
if (rulesetParameters == null)
@ -304,5 +327,8 @@ class MainMenuScreen: BaseScreen(), RecreateOnResize {
game.pushScreen(CivilopediaScreen(ruleset))
}
override fun recreate(): BaseScreen = MainMenuScreen()
override fun recreate(): BaseScreen {
stopBackgroundMapGeneration()
return MainMenuScreen()
}
}