auto save on dispose (#774)

* auto save on dispose

* auto save: clone game info outside the save-game thread

* keep autosaves for the last 10 turns
This commit is contained in:
sulai 2019-05-21 07:18:34 +02:00 committed by Yair Morgenstern
parent fd4123e15f
commit b5138b6527
3 changed files with 27 additions and 11 deletions

View File

@ -84,6 +84,10 @@ class UnCivGame(val version: String) : Game() {
resume() resume()
} }
override fun dispose() {
GameSaver().autoSave(gameInfo)
}
companion object { companion object {
lateinit var Current: UnCivGame lateinit var Current: UnCivGame
} }

View File

@ -7,6 +7,7 @@ import com.unciv.GameSettings
import com.unciv.logic.map.TileMap import com.unciv.logic.map.TileMap
import com.unciv.ui.saves.Gzip import com.unciv.ui.saves.Gzip
import com.unciv.ui.utils.ImageGetter import com.unciv.ui.utils.ImageGetter
import java.io.File
class GameSaver { class GameSaver {
private val saveFilesFolder = "SaveFiles" private val saveFilesFolder = "SaveFiles"
@ -66,4 +67,24 @@ class GameSaver {
fun setGeneralSettings(gameSettings: GameSettings){ fun setGeneralSettings(gameSettings: GameSettings){
getGeneralSettingsFile().writeString(json().toJson(gameSettings), false) getGeneralSettingsFile().writeString(json().toJson(gameSettings), false)
} }
fun autoSave(gameInfo: GameInfo, postRunnable: () -> Unit = {}) {
val gameInfoClone = gameInfo.clone()
kotlin.concurrent.thread {
// the save takes a long time (up to a second!) and we can do it while the player continues his game.
// On the other hand if we alter the game data while it's being serialized we could get a concurrent modification exception.
// So what we do is we clone all the game data and serialize the clone.
saveGame(gameInfoClone, "Autosave")
// keep auto-saves for the last 10 turns for debugging purposes
// eg turn 238 is saved as "Autosave-8"
getSave("Autosave").copyTo(Gdx.files.local(saveFilesFolder + File.separator + "Autosave-${gameInfoClone.turns%10}"))
// do this on main thread
Gdx.app.postRunnable {
postRunnable()
}
}
}
} }

View File

@ -262,20 +262,11 @@ class WorldScreen : CameraStageBaseScreen() {
throw ex throw ex
} }
val gameInfoClone = gameInfo.clone() if(gameInfo.turns % game.settings.turnsBetweenAutosaves == 0) {
kotlin.concurrent.thread { GameSaver().autoSave(gameInfo) {
// the save takes a long time (up to a second!) and we can do it while the player continues his game.
// On the other hand if we alter the game data while it's being serialized we could get a concurrent modification exception.
// So what we do is we clone all the game data and serialize the clone.
if(gameInfo.turns % game.settings.turnsBetweenAutosaves == 0)
GameSaver().saveGame(gameInfoClone, "Autosave")
// do this on main thread
Gdx.app.postRunnable {
nextTurnButton.enable() // only enable the user to next turn once we've saved the current one nextTurnButton.enable() // only enable the user to next turn once we've saved the current one
updateNextTurnButton() updateNextTurnButton()
} }
} }
// If we put this BEFORE the save game, then we try to save the game... // If we put this BEFORE the save game, then we try to save the game...