From c56b1055d77a70a1d5bda7f14efb058bd68941c5 Mon Sep 17 00:00:00 2001 From: minjaesong Date: Sat, 22 Jan 2022 14:43:31 +0900 Subject: [PATCH] autosave is back --- .../internal_variable.tga | 2 +- .../terrarum/modulebasegame/TerrarumIngame.kt | 39 +++++++++++++----- .../terrarum/serialise/WriteSavegame.kt | 40 +++---------------- 3 files changed, 35 insertions(+), 46 deletions(-) diff --git a/assets/graphics/fonts/terrarum-sans-bitmap/internal_variable.tga b/assets/graphics/fonts/terrarum-sans-bitmap/internal_variable.tga index bda762815..41eb7a99b 100644 --- a/assets/graphics/fonts/terrarum-sans-bitmap/internal_variable.tga +++ b/assets/graphics/fonts/terrarum-sans-bitmap/internal_variable.tga @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c3a002c1376e778a9c3f166be37c05509265b4fa44c36ea257a39acba478e02e +oid sha256:ad3b0ddd391eae7ea32afef5f016cf93858f0d2c222f598c8dc70b98288dbfad size 327698 diff --git a/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt b/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt index b16963ca6..a47b5803c 100644 --- a/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt +++ b/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt @@ -371,6 +371,9 @@ open class TerrarumIngame(batch: SpriteBatch) : IngameInstance(batch) { makeSavegameBackupCopy(getPlayerSaveFiledesc(playerSavefileName)) } + private val autosaveOnErrorAction = { e: Throwable -> uiAutosaveNotifier.setAsError() } + + private fun postInitForNewGame() { worldSavefileName = LoadSavegame.getWorldSavefileName(savegameNickname, world) playerSavefileName = LoadSavegame.getPlayerSavefileName(actorGamer) @@ -395,18 +398,16 @@ open class TerrarumIngame(batch: SpriteBatch) : IngameInstance(batch) { ) actorGamer.backupPlayerProps(isMultiplayer) - val onError = { e: Throwable -> uiAutosaveNotifier.setAsError() } - // make initial savefile // we're not writing multiple files at one go because: // 1. lighten the IO burden // 2. cannot sync up the "counter" to determine whether both are finished uiAutosaveNotifier.setAsOpen() val saveTime_t = App.getTIME_T() - WriteSavegame.immediate(saveTime_t, WriteSavegame.SaveMode.PLAYER, playerDisk, getPlayerSaveFiledesc(playerSavefileName), this, true, onError) { + WriteSavegame.immediate(saveTime_t, WriteSavegame.SaveMode.PLAYER, playerDisk, getPlayerSaveFiledesc(playerSavefileName), this, true, autosaveOnErrorAction) { makeSavegameBackupCopy(getPlayerSaveFiledesc(playerSavefileName)) - WriteSavegame.immediate(saveTime_t, WriteSavegame.SaveMode.WORLD, worldDisk, getWorldSaveFiledesc(worldSavefileName), this, true, onError) { + WriteSavegame.immediate(saveTime_t, WriteSavegame.SaveMode.WORLD, worldDisk, getWorldSaveFiledesc(worldSavefileName), this, true, autosaveOnErrorAction) { makeSavegameBackupCopy(getWorldSaveFiledesc(worldSavefileName)) // don't put it on the postInit() or render(); must be called using callback uiAutosaveNotifier.setAsClose() } @@ -1083,13 +1084,31 @@ open class TerrarumIngame(batch: SpriteBatch) : IngameInstance(batch) { fun queueAutosave() { val start = System.nanoTime() - /*uiAutosaveNotifier.setAsOpen() - makeSavegameBackupCopy() - WriteSavegame.quick(savegameArchive, getSaveFileMain(), this, true) { - uiAutosaveNotifier.setAsClose() + uiAutosaveNotifier.setAsOpen() + + val saveTime_t = App.getTIME_T() + val playerSavefile = getPlayerSaveFiledesc(INGAME.playerSavefileName) + val worldSavefile = getWorldSaveFiledesc(INGAME.worldSavefileName) + + INGAME.makeSavegameBackupCopy(playerSavefile) + WriteSavegame(saveTime_t, WriteSavegame.SaveMode.PLAYER, INGAME.playerDisk, playerSavefile, INGAME as TerrarumIngame, true, autosaveOnErrorAction) { + + INGAME.makeSavegameBackupCopy(worldSavefile) + WriteSavegame(saveTime_t, WriteSavegame.SaveMode.QUICK_WORLD, INGAME.worldDisk, worldSavefile, INGAME as TerrarumIngame, true, autosaveOnErrorAction) { + // callback: + // rebuild the disk skimmers + INGAME.actorContainerActive.filterIsInstance().forEach { + printdbg(this, "Game Save callback -- rebuilding the disk skimmer for IngamePlayer ${it.actorValue.getAsString(AVKey.NAME)}") + it.rebuildingDiskSkimmer?.rebuild() + } + + // return to normal state + uiAutosaveNotifier.setAsClose() + + debugTimers.put("Last Autosave Duration", System.nanoTime() - start) + } + } - debugTimers.put("Last Autosave Duration", System.nanoTime() - start) - }*/ } diff --git a/src/net/torvald/terrarum/serialise/WriteSavegame.kt b/src/net/torvald/terrarum/serialise/WriteSavegame.kt index 35f4ad08b..f46dba041 100644 --- a/src/net/torvald/terrarum/serialise/WriteSavegame.kt +++ b/src/net/torvald/terrarum/serialise/WriteSavegame.kt @@ -26,7 +26,7 @@ import java.util.logging.Level object WriteSavegame { enum class SaveMode { - META, PLAYER, WORLD, SHARED, QUICK_PLAYER, QUICK_WORLD + META, PLAYER, WORLD, SHARED, QUICK_WORLD } @Volatile var savingStatus = -1 // -1: not started, 0: saving in progress, 255: saving finished @@ -36,13 +36,13 @@ object WriteSavegame { private fun getSaveThread(time_t: Long, mode: SaveMode, disk: VirtualDisk, outFile: File, ingame: TerrarumIngame, hasThumbnail: Boolean, isAuto: Boolean, errorHandler: (Throwable) -> Unit, callback: () -> Unit) = when (mode) { SaveMode.WORLD -> WorldSavingThread(time_t, disk, outFile, ingame, hasThumbnail, isAuto, callback, errorHandler) SaveMode.PLAYER -> PlayerSavingThread(time_t, disk, outFile, ingame, hasThumbnail, isAuto, callback, errorHandler) - SaveMode.QUICK_PLAYER -> QuickSingleplayerWorldSavingThread(time_t, disk, outFile, ingame, hasThumbnail, isAuto, callback, errorHandler) + SaveMode.QUICK_WORLD -> QuickSingleplayerWorldSavingThread(time_t, disk, outFile, ingame, hasThumbnail, isAuto, callback, errorHandler) else -> throw IllegalArgumentException("$mode") } operator fun invoke(time_t: Long, mode: SaveMode, disk: VirtualDisk, outFile: File, ingame: TerrarumIngame, isAuto: Boolean, errorHandler: (Throwable) -> Unit, callback: () -> Unit) { savingStatus = 0 - val hasThumbnail = (mode == SaveMode.WORLD) + val hasThumbnail = (mode == SaveMode.WORLD || mode == SaveMode.QUICK_WORLD) printdbg(this, "Save queued") if (hasThumbnail) { @@ -70,7 +70,7 @@ object WriteSavegame { savingThread.start() // it is caller's job to keep the game paused or keep a "save in progress" ui up - // use field 'savingStatus' to know when the saving is done + // use callback to fire the after-the-saving-progress job } @@ -84,39 +84,9 @@ object WriteSavegame { savingThread.start() // it is caller's job to keep the game paused or keep a "save in progress" ui up - // use field 'savingStatus' to know when the saving is done + // use callback to fire the after-the-saving-progress job } - fun quick(time_t: Long, mode: SaveMode, disk: VirtualDisk, outFile: File, ingame: TerrarumIngame, isAuto: Boolean, callback: () -> Unit, errorHandler: (Throwable) -> Unit) { - if (ingame.isMultiplayer) TODO() - - return // TODO // - - savingStatus = 0 - - printdbg(this, "Quicksave queued") - - IngameRenderer.screencapExportCallback = { - printdbg(this, "Generating thumbnail...") - - val w = 960 - val h = 640 - val p = Pixmap.createFromFrameBuffer((it.width - w).ushr(1), (it.height - h).ushr(1), w, h) - IngameRenderer.fboRGBexport = p - //PixmapIO2._writeTGA(gzout, p, true, true) - //p.dispose() - IngameRenderer.fboRGBexportedLatch = true - - printdbg(this, "Done thumbnail generation") - } - IngameRenderer.screencapRequested = true - - val savingThread = Thread(getSaveThread(time_t, mode, disk, outFile, ingame, false, isAuto, errorHandler, callback), "TerrarumBasegameGameSaveThread") - savingThread.start() - - // it is caller's job to keep the game paused or keep a "save in progress" ui up - // use field 'savingStatus' to know when the saving is done - } }