public SaveTransaction build() { return new SaveTransaction(privateEntityManager, deltaToSave, unloadedPlayers, loadedPlayers, globalStoreBuilder, unloadedChunks, loadedChunks, gameManifest, storeChunksInZips, storagePathProvider, worldDirectoryWriteLock, recordAndReplaySerializer, recordAndReplayUtils, recordAndReplayCurrentStatus); }
@Override public boolean isSaving() { return saveTransaction != null && saveTransaction.getResult() == null; }
@Override public void run() { if (isReplay()) { return; } try { if (Files.exists(storagePathProvider.getUnmergedChangesPath())) { // should not happen, as initialization should clean it up throw new IOException("Save rand while there were unmerged changes"); } saveTransactionHelper.cleanupSaveTransactionDirectory(); applyDeltaToPrivateEntityManager(); prepareChunksPlayersAndGlobalStore(); createPreviewImagesFolder(); createSaveTransactionDirectory(); writePlayerStores(); writeGlobalStore(); writeChunkStores(); saveGameManifest(); perpareChangesForMerge(); mergeChanges(); result = SaveTransactionResult.createSuccessResult(); logger.info("Save game finished"); saveRecordingData(); } catch (IOException | RuntimeException t) { logger.error("Save game creation failed", t); result = SaveTransactionResult.createFailureResult(t); } }
/** * @param unsavedEntities currently loaded persistent entities without owner that have not been saved yet. * This method removes entities it saves. */ private void prepareCompressedChunkBuilders(Set<EntityRef> unsavedEntities) { Map<Vector3i, Collection<EntityRef>> chunkPosToEntitiesMap = createChunkPosToUnsavedOwnerLessEntitiesMap(); allChunks = Maps.newHashMap(); allChunks.putAll(unloadedChunks); for (Map.Entry<Vector3i, ChunkImpl> chunkEntry : loadedChunks.entrySet()) { Collection<EntityRef> entitiesToStore = chunkPosToEntitiesMap.get(chunkEntry.getKey()); if (entitiesToStore == null) { entitiesToStore = Collections.emptySet(); } ChunkImpl chunk = chunkEntry.getValue(); unsavedEntities.removeAll(entitiesToStore); CompressedChunkBuilder compressedChunkBuilder = new CompressedChunkBuilder(privateEntityManager, chunk, entitiesToStore, false); unsavedEntities.removeAll(compressedChunkBuilder.getStoredEntities()); allChunks.put(chunkEntry.getKey(), compressedChunkBuilder); } }
private void checkSaveTransactionAndClearUpIfItIsDone() { if (saveTransaction != null) { SaveTransactionResult result = saveTransaction.getResult(); if (result != null) { Throwable t = saveTransaction.getResult().getCatchedThrowable(); if (t != null) { throw new RuntimeException("Saving failed", t); } saveTransaction = null; } unloadedAndSavingChunkMap.clear(); } }
private void waitForCompletionOfPreviousSave() { if (recordAndReplayCurrentStatus.getStatus() == RecordAndReplayStatus.REPLAY_FINISHED) { recordAndReplayUtils.setShutdownRequested(true); //Important to trigger complete serialization in a recording } if (saveTransaction != null && saveTransaction.getResult() == null) { saveThreadManager.shutdown(new ShutdownTask(), true); saveThreadManager.restart(); } checkSaveTransactionAndClearUpIfItIsDone(); }