Resolved new game ANRs in a better way

This commit is contained in:
yairm210 2024-10-08 13:23:03 +03:00
parent bf8ccee943
commit 7632e681e7

View File

@ -107,10 +107,18 @@ class NewGameScreen(
} }
rightSideButton.setText("Start game!".tr()) rightSideButton.setText("Start game!".tr())
rightSideButton.onClick(this::onStartGameClicked) rightSideButton.onClick(this::startGameAvoidANRs)
} }
private fun onStartGameClicked() { private fun startGameAvoidANRs(){
// Don't allow players to click the game while we're checking if it's ok
Gdx.input.inputProcessor = null
val success = startGame()
// if it is successful, the player should wait for the new screen, not touch the old one
if (!success) Gdx.input.inputProcessor = stage
}
private fun startGame(): Boolean {
mapOptionsTable.cancelBackgroundJobs() mapOptionsTable.cancelBackgroundJobs()
if (gameSetupInfo.gameParameters.isOnlineMultiplayer) { if (gameSetupInfo.gameParameters.isOnlineMultiplayer) {
if (!checkConnectionToMultiplayerServer()) { if (!checkConnectionToMultiplayerServer()) {
@ -119,7 +127,7 @@ class NewGameScreen(
noInternetConnectionPopup.addGoodSizedLabel(label.tr()).row() noInternetConnectionPopup.addGoodSizedLabel(label.tr()).row()
noInternetConnectionPopup.addCloseButton() noInternetConnectionPopup.addCloseButton()
noInternetConnectionPopup.open() noInternetConnectionPopup.open()
return return false
} }
for (player in gameSetupInfo.gameParameters.players.filter { it.playerType == PlayerType.Human }) { for (player in gameSetupInfo.gameParameters.players.filter { it.playerType == PlayerType.Human }) {
@ -130,7 +138,7 @@ class NewGameScreen(
invalidPlayerIdPopup.addGoodSizedLabel("Invalid player ID!".tr()).row() invalidPlayerIdPopup.addGoodSizedLabel("Invalid player ID!".tr()).row()
invalidPlayerIdPopup.addCloseButton() invalidPlayerIdPopup.addCloseButton()
invalidPlayerIdPopup.open() invalidPlayerIdPopup.open()
return return false
} }
} }
@ -140,7 +148,7 @@ class NewGameScreen(
notAllowedToSpectate.addGoodSizedLabel("You are not allowed to spectate!".tr()).row() notAllowedToSpectate.addGoodSizedLabel("You are not allowed to spectate!".tr()).row()
notAllowedToSpectate.addCloseButton() notAllowedToSpectate.addCloseButton()
notAllowedToSpectate.open() notAllowedToSpectate.open()
return return false
} }
} }
} }
@ -154,7 +162,7 @@ class NewGameScreen(
noHumanPlayersPopup.addGoodSizedLabel("No human players selected!".tr()).row() noHumanPlayersPopup.addGoodSizedLabel("No human players selected!".tr()).row()
noHumanPlayersPopup.addCloseButton() noHumanPlayersPopup.addCloseButton()
noHumanPlayersPopup.open() noHumanPlayersPopup.open()
return return false
} }
if (gameSetupInfo.gameParameters.victoryTypes.isEmpty()) { if (gameSetupInfo.gameParameters.victoryTypes.isEmpty()) {
@ -162,7 +170,7 @@ class NewGameScreen(
noVictoryTypesPopup.addGoodSizedLabel("No victory conditions were selected!".tr()).row() noVictoryTypesPopup.addGoodSizedLabel("No victory conditions were selected!".tr()).row()
noVictoryTypesPopup.addCloseButton() noVictoryTypesPopup.addCloseButton()
noVictoryTypesPopup.open() noVictoryTypesPopup.open()
return return false
} }
val modCheckResult = newGameOptionsTable.modCheckboxes.savedModcheckResult val modCheckResult = newGameOptionsTable.modCheckboxes.savedModcheckResult
@ -173,22 +181,19 @@ class NewGameScreen(
restoreDefault = { newGameOptionsTable.resetRuleset() }, restoreDefault = { newGameOptionsTable.resetRuleset() },
action = { action = {
gameSetupInfo.gameParameters.acceptedModCheckErrors = modCheckResult gameSetupInfo.gameParameters.acceptedModCheckErrors = modCheckResult
onStartGameClicked() startGameAvoidANRs()
} }
) )
return return false
} }
Gdx.input.inputProcessor = null // remove input processing - nothing will be clicked!
if (mapOptionsTable.mapTypeSelectBox.selected.value == MapGeneratedMainType.custom) { if (mapOptionsTable.mapTypeSelectBox.selected.value == MapGeneratedMainType.custom) {
val map = try { val map = try {
MapSaver.loadMap(gameSetupInfo.mapFile!!) MapSaver.loadMap(gameSetupInfo.mapFile!!)
} catch (ex: Throwable) { } catch (ex: Throwable) {
Log.error("Could not load map", ex) Log.error("Could not load map", ex)
Gdx.input.inputProcessor = stage
ToastPopup("Could not load map!", this) ToastPopup("Could not load map!", this)
return return false
} }
val rulesetIncompatibilities = map.getRulesetIncompatibility(ruleset) val rulesetIncompatibilities = map.getRulesetIncompatibility(ruleset)
@ -199,8 +204,7 @@ class NewGameScreen(
incompatibleMap.addGoodSizedLabel(incompatibility).row() incompatibleMap.addGoodSizedLabel(incompatibility).row()
incompatibleMap.addCloseButton() incompatibleMap.addCloseButton()
incompatibleMap.open() incompatibleMap.open()
Gdx.input.inputProcessor = stage return false
return
} }
} else { } else {
// Generated map - check for sensible dimensions and if exceeded correct them and notify user // Generated map - check for sensible dimensions and if exceeded correct them and notify user
@ -213,8 +217,7 @@ class NewGameScreen(
customMapWidth.text = mapSize.width.tr() customMapWidth.text = mapSize.width.tr()
customMapHeight.text = mapSize.height.tr() customMapHeight.text = mapSize.height.tr()
} }
Gdx.input.inputProcessor = stage return false
return
} }
} }
@ -226,6 +229,7 @@ class NewGameScreen(
Concurrency.runOnNonDaemonThreadPool("NewGame") { Concurrency.runOnNonDaemonThreadPool("NewGame") {
startNewGame() startNewGame()
} }
return true
} }
/** Subtables may need an upper limit to their width - they can ask this function. */ /** Subtables may need an upper limit to their width - they can ask this function. */
@ -277,7 +281,6 @@ class NewGameScreen(
} }
private fun checkConnectionToMultiplayerServer(): Boolean { private fun checkConnectionToMultiplayerServer(): Boolean {
Gdx.input.inputProcessor = null // To avoid ANRs
return try { return try {
val multiplayerServer = UncivGame.Current.settings.multiplayer.server val multiplayerServer = UncivGame.Current.settings.multiplayer.server
val u = URL(if (Multiplayer.usesDropbox()) "https://content.dropboxapi.com" else multiplayerServer) val u = URL(if (Multiplayer.usesDropbox()) "https://content.dropboxapi.com" else multiplayerServer)
@ -289,9 +292,6 @@ class NewGameScreen(
} catch(_: Throwable) { } catch(_: Throwable) {
false false
} }
finally {
Gdx.input.inputProcessor = stage
}
} }
private suspend fun startNewGame() = coroutineScope { private suspend fun startNewGame() = coroutineScope {