World screen resize delayed (#11015)

* Coalesce repeated WorldScreen resize events to avoid multiple concurrent loadGame coroutines

* Remove resize instrumentation
This commit is contained in:
SomeTroglodyte
2024-01-28 10:10:59 +01:00
committed by GitHub
parent 3a80db2604
commit 259b388214

View File

@ -69,6 +69,8 @@ import com.unciv.utils.launchOnThreadPool
import com.unciv.utils.withGLContext
import kotlinx.coroutines.Job
import kotlinx.coroutines.coroutineScope
import java.util.Timer
import kotlin.concurrent.timer
/**
* Do not create this screen without seriously thinking about the implications: this is the single most memory-intensive class in the application.
@ -216,6 +218,7 @@ class WorldScreen(
}
override fun dispose() {
resizeDeferTimer?.cancel()
events.stopReceiving()
statusButtons.dispose()
super.dispose()
@ -715,17 +718,23 @@ class WorldScreen(
}
}
private var resizeDeferTimer: Timer? = null
override fun resize(width: Int, height: Int) {
if (stage.viewport.screenWidth != width || stage.viewport.screenHeight != height) {
resizeDeferTimer?.cancel()
if (resizeDeferTimer == null && stage.viewport.screenWidth == width && stage.viewport.screenHeight == height) return
resizeDeferTimer = timer("Resize", daemon = true, 500L, Long.MAX_VALUE) {
resizeDeferTimer?.cancel()
resizeDeferTimer = null
startNewScreenJob(gameInfo, true) // start over
}
}
override fun render(delta: Float) {
// This is so that updates happen in the MAIN THREAD, where there is a GL Context,
// otherwise images will not load properly!
if (shouldUpdate) {
if (shouldUpdate && resizeDeferTimer == null) {
shouldUpdate = false
// Since updating the worldscreen can take a long time, *especially* the first time, we disable input processing to avoid ANRs
@ -735,12 +744,11 @@ class WorldScreen(
if (Gdx.input.inputProcessor == null) // Update may have replaced the worldscreen with a GreatPersonPickerScreen etc, so the input would already be set
Gdx.input.inputProcessor = stage
}
// topBar.selectedCivLabel.setText(Gdx.graphics.framesPerSecond) // for framerate testing
super.render(delta)
}
private fun showTutorialsOnNextTurn() {
if (!game.settings.showTutorials) return
displayTutorial(TutorialTrigger.SlowStart)
@ -799,7 +807,7 @@ class WorldScreen(
}
/** This exists so that no reference to the current world screen remains, so the old world screen can get garbage collected during [UncivGame.loadGame]. */
private fun startNewScreenJob(gameInfo: GameInfo, autosaveDisabled:Boolean = false) {
private fun startNewScreenJob(gameInfo: GameInfo, autosaveDisabled: Boolean = false) {
Concurrency.run {
val newWorldScreen = try {
UncivGame.Current.loadGame(gameInfo)