mirror of
https://github.com/yairm210/Unciv.git
synced 2025-07-21 05:09:25 +07:00
Improving MultiplayerScreen loading speed (#3527)
* Improve MultiplayerScreen Loading Speed * Refactoring - renamed multiplayerGameList to multiplayerGames because it's not a List - changed content of map from <GameId, Filehandle> to <FileHandle, GameInfo> because GameId is an expensive Key * i do as yairm guides
This commit is contained in:
@ -17,9 +17,8 @@ import kotlin.concurrent.thread
|
|||||||
|
|
||||||
class MultiplayerScreen(previousScreen: CameraStageBaseScreen) : PickerScreen() {
|
class MultiplayerScreen(previousScreen: CameraStageBaseScreen) : PickerScreen() {
|
||||||
|
|
||||||
private lateinit var selectedGame: GameInfo
|
private lateinit var selectedGameFile: FileHandle
|
||||||
private lateinit var selectedGameName: String
|
private var multiplayerGames = mutableMapOf<FileHandle, GameInfo>()
|
||||||
private var multiplayerGameList = mutableMapOf<String, FileHandle>()
|
|
||||||
private val rightSideTable = Table()
|
private val rightSideTable = Table()
|
||||||
private val leftSideTable = Table()
|
private val leftSideTable = Table()
|
||||||
|
|
||||||
@ -87,15 +86,21 @@ class MultiplayerScreen(previousScreen: CameraStageBaseScreen) : PickerScreen()
|
|||||||
rightSideTable.add(copyUserIdButton).padBottom(30f).row()
|
rightSideTable.add(copyUserIdButton).padBottom(30f).row()
|
||||||
|
|
||||||
copyGameIdButton.onClick {
|
copyGameIdButton.onClick {
|
||||||
Gdx.app.clipboard.contents = selectedGame.gameId
|
val gameInfo = multiplayerGames[selectedGameFile]
|
||||||
ToastPopup("GameID copied to clipboard".tr(), this)
|
if (gameInfo != null) {
|
||||||
|
Gdx.app.clipboard.contents = gameInfo.gameId
|
||||||
|
ToastPopup("GameID copied to clipboard".tr(), this)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
rightSideTable.add(copyGameIdButton).row()
|
rightSideTable.add(copyGameIdButton).row()
|
||||||
|
|
||||||
editButton.onClick {
|
editButton.onClick {
|
||||||
game.setScreen(EditMultiplayerGameInfoScreen(selectedGame, selectedGameName, this))
|
val gameInfo = multiplayerGames[selectedGameFile]
|
||||||
//game must be unselected in case the game gets deleted inside the EditScreen
|
if (gameInfo != null) {
|
||||||
unselectGame()
|
game.setScreen(EditMultiplayerGameInfoScreen(gameInfo, selectedGameFile.name(), this))
|
||||||
|
//game must be unselected in case the game gets deleted inside the EditScreen
|
||||||
|
unselectGame()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
rightSideTable.add(editButton).row()
|
rightSideTable.add(editButton).row()
|
||||||
|
|
||||||
@ -169,7 +174,7 @@ class MultiplayerScreen(previousScreen: CameraStageBaseScreen) : PickerScreen()
|
|||||||
//the game will be downloaded opon joining it anyway
|
//the game will be downloaded opon joining it anyway
|
||||||
private fun joinMultiplaerGame(){
|
private fun joinMultiplaerGame(){
|
||||||
try {
|
try {
|
||||||
game.loadGame(selectedGame)
|
game.loadGame(multiplayerGames[selectedGameFile]!!)
|
||||||
} catch (ex: Exception) {
|
} catch (ex: Exception) {
|
||||||
val errorPopup = Popup(this)
|
val errorPopup = Popup(this)
|
||||||
errorPopup.addGoodSizedLabel("Could not download game!".tr())
|
errorPopup.addGoodSizedLabel("Could not download game!".tr())
|
||||||
@ -180,7 +185,10 @@ class MultiplayerScreen(previousScreen: CameraStageBaseScreen) : PickerScreen()
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun gameIsAlreadySavedAsMultiplayer(gameId: String) : Boolean{
|
private fun gameIsAlreadySavedAsMultiplayer(gameId: String) : Boolean{
|
||||||
return multiplayerGameList.containsKey(gameId)
|
val games = multiplayerGames.filterValues { it.gameId == gameId }
|
||||||
|
if (games.isNotEmpty())
|
||||||
|
return true
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
//reloads all gameFiles to refresh UI
|
//reloads all gameFiles to refresh UI
|
||||||
@ -203,34 +211,47 @@ class MultiplayerScreen(previousScreen: CameraStageBaseScreen) : PickerScreen()
|
|||||||
for (gameSaveFile in savedGames) {
|
for (gameSaveFile in savedGames) {
|
||||||
try {
|
try {
|
||||||
val gameTable = Table()
|
val gameTable = Table()
|
||||||
val game = gameSaver.loadGameFromFile(gameSaveFile)
|
val turnIndicator = Table()
|
||||||
|
turnIndicator.add(ImageGetter.getImage("EmojiIcons/Turn"))
|
||||||
//Add games to list so saves don't have to be loaded as Files so often
|
gameTable.add(turnIndicator)
|
||||||
if (!gameIsAlreadySavedAsMultiplayer(game.gameId))
|
|
||||||
multiplayerGameList[game.gameId] = gameSaveFile
|
|
||||||
|
|
||||||
if (isUsersTurn(game)) {
|
|
||||||
gameTable.add(ImageGetter.getNationIndicator(game.currentPlayerCiv.nation, 50f))
|
|
||||||
} else {
|
|
||||||
gameTable.add()
|
|
||||||
}
|
|
||||||
|
|
||||||
val lastModifiedMillis = gameSaveFile.lastModified()
|
val lastModifiedMillis = gameSaveFile.lastModified()
|
||||||
val gameButton = gameSaveFile.name().toTextButton()
|
val gameButton = gameSaveFile.name().toTextButton()
|
||||||
|
var currentTurnUser = ""
|
||||||
|
|
||||||
gameButton.onClick {
|
gameButton.onClick {
|
||||||
selectedGame = game
|
selectedGameFile = gameSaveFile
|
||||||
selectedGameName = gameSaveFile.name()
|
if (multiplayerGames[gameSaveFile] != null){
|
||||||
copyGameIdButton.enable()
|
copyGameIdButton.enable()
|
||||||
editButton.enable()
|
editButton.enable()
|
||||||
|
}
|
||||||
rightSideButton.enable()
|
rightSideButton.enable()
|
||||||
|
|
||||||
//get Minutes since last modified
|
//get Minutes since last modified
|
||||||
val lastSavedMinutesAgo = (System.currentTimeMillis() - lastModifiedMillis) / 60000
|
val lastSavedMinutesAgo = (System.currentTimeMillis() - lastModifiedMillis) / 60000
|
||||||
var descriptionText = "Last refresh: [$lastSavedMinutesAgo] minutes ago".tr() + "\r\n"
|
var descriptionText = "Last refresh: [$lastSavedMinutesAgo] minutes ago".tr() + "\r\n"
|
||||||
descriptionText += "Current Turn:".tr() + " ${selectedGame.currentPlayer}\r\n"
|
descriptionText += "Current Turn:".tr() + " ${currentTurnUser}\r\n"
|
||||||
descriptionLabel.setText(descriptionText)
|
descriptionLabel.setText(descriptionText)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
thread {
|
||||||
|
val game = gameSaver.loadGameFromFile(gameSaveFile)
|
||||||
|
|
||||||
|
//Add games to list so saves don't have to be loaded as Files so often
|
||||||
|
if (!gameIsAlreadySavedAsMultiplayer(game.gameId)) {
|
||||||
|
multiplayerGames[gameSaveFile] = game
|
||||||
|
}
|
||||||
|
|
||||||
|
Gdx.app.postRunnable {
|
||||||
|
turnIndicator.clear()
|
||||||
|
if (isUsersTurn(game)) {
|
||||||
|
turnIndicator.add(ImageGetter.getNationIndicator(game.currentPlayerCiv.nation, 50f))
|
||||||
|
}
|
||||||
|
//set variable so it can be displayed when gameButton.onClick gets called
|
||||||
|
currentTurnUser = game.currentPlayer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
gameTable.add(gameButton).pad(5f).row()
|
gameTable.add(gameButton).pad(5f).row()
|
||||||
leftSubTable.add(gameTable).row()
|
leftSubTable.add(gameTable).row()
|
||||||
} catch (ex: Exception) {
|
} catch (ex: Exception) {
|
||||||
@ -239,6 +260,7 @@ class MultiplayerScreen(previousScreen: CameraStageBaseScreen) : PickerScreen()
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
leftSideTable.clear()
|
leftSideTable.clear()
|
||||||
leftSideTable.add(leftSubTable)
|
leftSideTable.add(leftSubTable)
|
||||||
}
|
}
|
||||||
@ -252,15 +274,15 @@ class MultiplayerScreen(previousScreen: CameraStageBaseScreen) : PickerScreen()
|
|||||||
|
|
||||||
//One thread for all downloads
|
//One thread for all downloads
|
||||||
thread (name = "multiplayerGameDownload") {
|
thread (name = "multiplayerGameDownload") {
|
||||||
for (gameId in multiplayerGameList.keys) {
|
for (entry in multiplayerGames) {
|
||||||
try {
|
try {
|
||||||
val game = OnlineMultiplayer().tryDownloadGame(gameId)
|
val game = OnlineMultiplayer().tryDownloadGame(entry.value.gameId)
|
||||||
GameSaver.saveGame(game, multiplayerGameList.getValue(gameId).name(), true)
|
GameSaver.saveGame(game, entry.key.name(), true)
|
||||||
} catch (ex: Exception) {
|
} catch (ex: Exception) {
|
||||||
//skipping one is not fatal
|
//skipping one is not fatal
|
||||||
//Trying to use as many prev. used strings as possible
|
//Trying to use as many prev. used strings as possible
|
||||||
Gdx.app.postRunnable {
|
Gdx.app.postRunnable {
|
||||||
ToastPopup("Could not download game!".tr() + " ${multiplayerGameList.getValue(gameId)}", this)
|
ToastPopup("Could not download game!".tr() + " ${entry.key.name()}", this)
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -316,8 +338,10 @@ class MultiplayerScreen(previousScreen: CameraStageBaseScreen) : PickerScreen()
|
|||||||
return (gameInfo.currentPlayerCiv.playerId == game.settings.userId)
|
return (gameInfo.currentPlayerCiv.playerId == game.settings.userId)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun removeFromList(gameId: String){
|
fun removeFromList(gameInfo: GameInfo){
|
||||||
multiplayerGameList.remove(gameId)
|
val games = multiplayerGames.filterValues { it == gameInfo }.keys
|
||||||
|
if (games.isNotEmpty())
|
||||||
|
multiplayerGames.remove(games.first())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -367,7 +391,7 @@ class EditMultiplayerGameInfoScreen(game: GameInfo, gameName: String, backScreen
|
|||||||
rightSideButton.onClick {
|
rightSideButton.onClick {
|
||||||
rightSideButton.setText("Saving...".tr())
|
rightSideButton.setText("Saving...".tr())
|
||||||
try {
|
try {
|
||||||
backScreen.removeFromList(game.gameId)
|
backScreen.removeFromList(game)
|
||||||
//using addMultiplayerGame will download the game from Dropbox so the descriptionLabel displays the right things
|
//using addMultiplayerGame will download the game from Dropbox so the descriptionLabel displays the right things
|
||||||
backScreen.addMultiplayerGame(game.gameId, textField.text)
|
backScreen.addMultiplayerGame(game.gameId, textField.text)
|
||||||
GameSaver.deleteSave(gameName, true)
|
GameSaver.deleteSave(gameName, true)
|
||||||
|
Reference in New Issue
Block a user