aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Tkachev2016-06-18 19:35:57 +0600
committerAlexander Tkachev2016-08-24 16:07:55 +0600
commit65e87c6c70fc1e5af8f0c3fb762ca13e6aa6a8e4 (patch)
treee209c6d22539fedd3456f954394c2d6cf73113cb
parentaee713141b3a401f08e63cd9ccf5ce3dfe1cb06e (diff)
downloadscummvm-rg350-65e87c6c70fc1e5af8f0c3fb762ca13e6aa6a8e4.tar.gz
scummvm-rg350-65e87c6c70fc1e5af8f0c3fb762ca13e6aa6a8e4.tar.bz2
scummvm-rg350-65e87c6c70fc1e5af8f0c3fb762ca13e6aa6a8e4.zip
CLOUD: Update save's timestamp on rewrite
This commit moves save/load timestamps static methods into DefaultSaveFileManager and fixes a few related bugs.
-rw-r--r--backends/cloud/savessyncrequest.cpp133
-rw-r--r--backends/cloud/savessyncrequest.h8
-rw-r--r--backends/saves/default/default-saves.cpp109
-rw-r--r--backends/saves/default/default-saves.h14
4 files changed, 142 insertions, 122 deletions
diff --git a/backends/cloud/savessyncrequest.cpp b/backends/cloud/savessyncrequest.cpp
index f059e29a8d..4d18647911 100644
--- a/backends/cloud/savessyncrequest.cpp
+++ b/backends/cloud/savessyncrequest.cpp
@@ -29,11 +29,10 @@
#include "common/savefile.h"
#include "common/system.h"
#include "gui/saveload-dialog.h"
+#include <backends/saves/default/default-saves.h>
namespace Cloud {
-const char *SavesSyncRequest::TIMESTAMPS_FILENAME = "timestamps";
-
SavesSyncRequest::SavesSyncRequest(Storage *storage, Storage::BoolCallback callback, Networking::ErrorCallback ecb):
Request(nullptr, ecb), CommandSender(nullptr), _storage(storage), _boolCallback(callback),
_workingRequest(nullptr), _ignoreCallback(false) {
@@ -59,7 +58,7 @@ void SavesSyncRequest::start() {
_ignoreCallback = false;
//load timestamps
- loadTimestamps();
+ _localFilesTimestamps = DefaultSaveFileManager::loadTimestamps();
//list saves directory
Common::String dir = _storage->savesDirectoryPath();
@@ -90,25 +89,23 @@ void SavesSyncRequest::directoryListedCallback(Storage::ListDirectoryResponse re
StorageFile &file = remoteFiles[i];
if (file.isDirectory()) continue;
totalSize += file.size();
- if (file.name() == TIMESTAMPS_FILENAME) continue;
+ if (file.name() == DefaultSaveFileManager::TIMESTAMPS_FILENAME) continue;
Common::String name = file.name();
if (!_localFilesTimestamps.contains(name))
_filesToDownload.push_back(file);
else {
localFileNotAvailableInCloud[name] = false;
-
- if (_localFilesTimestamps[name] != INVALID_TIMESTAMP) {
- if (_localFilesTimestamps[name] == file.timestamp())
- continue;
-
- //we actually can have some files not only with timestamp < remote
- //but also with timestamp > remote (when we have been using ANOTHER CLOUD and then switched back)
- if (_localFilesTimestamps[name] < file.timestamp())
- _filesToDownload.push_back(file);
- else
- _filesToUpload.push_back(file.name());
- }
+
+ if (_localFilesTimestamps[name] == file.timestamp())
+ continue;
+
+ //we actually can have some files not only with timestamp < remote
+ //but also with timestamp > remote (when we have been using ANOTHER CLOUD and then switched back)
+ if (_localFilesTimestamps[name] > file.timestamp() || _localFilesTimestamps[name] == DefaultSaveFileManager::INVALID_TIMESTAMP)
+ _filesToUpload.push_back(file.name());
+ else
+ _filesToDownload.push_back(file);
}
}
@@ -116,7 +113,7 @@ void SavesSyncRequest::directoryListedCallback(Storage::ListDirectoryResponse re
//upload files which are unavailable in cloud
for (Common::HashMap<Common::String, bool>::iterator i = localFileNotAvailableInCloud.begin(); i != localFileNotAvailableInCloud.end(); ++i) {
- if (i->_key == TIMESTAMPS_FILENAME) continue;
+ if (i->_key == DefaultSaveFileManager::TIMESTAMPS_FILENAME) continue;
if (i->_value) _filesToUpload.push_back(i->_key);
}
@@ -234,7 +231,7 @@ void SavesSyncRequest::downloadNextFile() {
///////
debug("downloading %s (%d %%)", _currentDownloadingFile.name().c_str(), (int)(getProgress() * 100));
///////
- _workingRequest = _storage->downloadById(_currentDownloadingFile.id(), concatWithSavesPath(_currentDownloadingFile.name()),
+ _workingRequest = _storage->downloadById(_currentDownloadingFile.id(), DefaultSaveFileManager::concatWithSavesPath(_currentDownloadingFile.name()),
new Common::Callback<SavesSyncRequest, Storage::BoolResponse>(this, &SavesSyncRequest::fileDownloadedCallback),
new Common::Callback<SavesSyncRequest, Networking::ErrorResponse>(this, &SavesSyncRequest::fileDownloadedErrorCallback)
);
@@ -252,7 +249,9 @@ void SavesSyncRequest::fileDownloadedCallback(Storage::BoolResponse response) {
}
//update local timestamp for downloaded file
+ _localFilesTimestamps = DefaultSaveFileManager::loadTimestamps();
_localFilesTimestamps[_currentDownloadingFile.name()] = _currentDownloadingFile.timestamp();
+ DefaultSaveFileManager::saveTimestamps(_localFilesTimestamps);
//continue downloading files
downloadNextFile();
@@ -290,7 +289,9 @@ void SavesSyncRequest::fileUploadedCallback(Storage::UploadResponse response) {
if (_ignoreCallback) return;
//update local timestamp for the uploaded file
+ _localFilesTimestamps = DefaultSaveFileManager::loadTimestamps();
_localFilesTimestamps[_currentUploadingFile] = response.value.timestamp();
+ DefaultSaveFileManager::saveTimestamps(_localFilesTimestamps);
//continue uploading files
uploadNextFile();
@@ -342,112 +343,16 @@ Common::Array<Common::String> SavesSyncRequest::getFilesToDownload() {
void SavesSyncRequest::finishError(Networking::ErrorResponse error) {
debug("SavesSync::finishError");
- //save updated timestamps (even if Request failed, there would be only valid timestamps)
- saveTimestamps();
-
Request::finishError(error);
}
void SavesSyncRequest::finishSuccess(bool success) {
Request::finishSuccess();
- //save updated timestamps (even if Request failed, there would be only valid timestamps)
- saveTimestamps();
-
//update last successful sync date
CloudMan.setStorageLastSync(CloudMan.getStorageIndex(), _date);
if (_boolCallback) (*_boolCallback)(Storage::BoolResponse(this, success));
}
-void SavesSyncRequest::loadTimestamps() {
- //refresh the files list
- Common::Array<Common::String> files;
- g_system->getSavefileManager()->updateSavefilesList(files);
-
- //start with listing all the files in saves/ directory and setting invalid timestamp to them
- Common::StringArray localFiles = g_system->getSavefileManager()->listSavefiles("*");
- for (uint32 i = 0; i < localFiles.size(); ++i)
- _localFilesTimestamps[localFiles[i]] = INVALID_TIMESTAMP;
-
- //now actually load timestamps from file
- Common::InSaveFile *file = g_system->getSavefileManager()->openRawFile(TIMESTAMPS_FILENAME);
- if (!file) {
- warning("SavesSyncRequest: failed to open '%s' file to load timestamps", TIMESTAMPS_FILENAME);
- return;
- }
-
- while (!file->eos()) {
- //read filename into buffer (reading until the first ' ')
- Common::String buffer;
- while (!file->eos()) {
- byte b = file->readByte();
- if (b == ' ') break;
- buffer += (char)b;
- }
-
- //read timestamp info buffer (reading until ' ' or some line ending char)
- Common::String filename = buffer;
- bool lineEnded = false;
- buffer = "";
- while (!file->eos()) {
- byte b = file->readByte();
- if (b == ' ' || b == '\n' || b == '\r') {
- lineEnded = (b == '\n');
- break;
- }
- buffer += (char)b;
- }
-
- //parse timestamp
- uint timestamp = atol(buffer.c_str());
- if (buffer == "" || timestamp == 0) break;
- _localFilesTimestamps[filename] = timestamp;
-
- //read until the end of the line
- if (!lineEnded) {
- while (!file->eos()) {
- byte b = file->readByte();
- if (b == '\n') break;
- }
- }
- }
-
- delete file;
-}
-
-void SavesSyncRequest::saveTimestamps() {
- Common::DumpFile f;
- Common::String filename = concatWithSavesPath(TIMESTAMPS_FILENAME);
- if (!f.open(filename, true)) {
- warning("SavesSyncRequest: failed to open '%s' file to save timestamps", filename.c_str());
- return;
- }
-
- for (Common::HashMap<Common::String, uint32>::iterator i = _localFilesTimestamps.begin(); i != _localFilesTimestamps.end(); ++i) {
- Common::String data = i->_key + Common::String::format(" %u\n", i->_value);
- if (f.write(data.c_str(), data.size()) != data.size()) {
- warning("SavesSyncRequest: failed to write timestamps data into '%s'", filename.c_str());
- return;
- }
- }
-
- f.close();
-}
-
-Common::String SavesSyncRequest::concatWithSavesPath(Common::String name) {
- Common::String path = ConfMan.get("savepath");
- if (path.size() > 0 && (path.lastChar() == '/' || path.lastChar() == '\\'))
- return path + name;
-
- //simple heuristic to determine which path separator to use
- int backslashes = 0;
- for (uint32 i = 0; i < path.size(); ++i)
- if (path[i] == '/') --backslashes;
- else if (path[i] == '\\') ++backslashes;
-
- if (backslashes) return path + '\\' + name;
- return path + '/' + name;
-}
-
} // End of namespace Cloud
diff --git a/backends/cloud/savessyncrequest.h b/backends/cloud/savessyncrequest.h
index 105d7f7f65..19e67d9dd8 100644
--- a/backends/cloud/savessyncrequest.h
+++ b/backends/cloud/savessyncrequest.h
@@ -28,14 +28,10 @@
#include "common/hashmap.h"
#include "common/hash-str.h"
#include "gui/object.h"
-#include <limits.h>
namespace Cloud {
class SavesSyncRequest: public Networking::Request, public GUI::CommandSender {
- const uint32 INVALID_TIMESTAMP = UINT_MAX;
- static const char *TIMESTAMPS_FILENAME;
-
Storage *_storage;
Storage::BoolCallback _boolCallback;
Common::HashMap<Common::String, uint32> _localFilesTimestamps;
@@ -61,9 +57,7 @@ class SavesSyncRequest: public Networking::Request, public GUI::CommandSender {
void uploadNextFile();
virtual void finishError(Networking::ErrorResponse error);
void finishSuccess(bool success);
- void loadTimestamps();
- void saveTimestamps();
- Common::String concatWithSavesPath(Common::String name);
+
public:
SavesSyncRequest(Storage *storage, Storage::BoolCallback callback, Networking::ErrorCallback ecb);
virtual ~SavesSyncRequest();
diff --git a/backends/saves/default/default-saves.cpp b/backends/saves/default/default-saves.cpp
index e20ce31d18..54dc1c2966 100644
--- a/backends/saves/default/default-saves.cpp
+++ b/backends/saves/default/default-saves.cpp
@@ -29,6 +29,7 @@
#ifdef USE_CLOUD
#include "backends/cloud/cloudmanager.h"
+#include "common/file.h"
#endif
#if !defined(DISABLE_DEFAULT_SAVEFILEMANAGER)
@@ -46,6 +47,10 @@
#include <errno.h> // for removeSavefile()
#endif
+#ifdef USE_CLOUD
+const char *DefaultSaveFileManager::TIMESTAMPS_FILENAME = "timestamps";
+#endif
+
DefaultSaveFileManager::DefaultSaveFileManager() {
}
@@ -142,6 +147,13 @@ Common::OutSaveFile *DefaultSaveFileManager::openForSaving(const Common::String
}
}
+#ifdef USE_CLOUD
+ // Update file's timestamp
+ Common::HashMap<Common::String, uint32> timestamps = loadTimestamps();
+ timestamps[filename] = INVALID_TIMESTAMP;
+ saveTimestamps(timestamps);
+#endif
+
// Obtain node.
SaveFileCache::const_iterator file = _saveFileCache.find(filename);
Common::FSNode fileNode;
@@ -266,4 +278,101 @@ void DefaultSaveFileManager::assureCached(const Common::String &savePathName) {
_cachedDirectory = savePathName;
}
+#ifdef USE_CLOUD
+
+Common::HashMap<Common::String, uint32> DefaultSaveFileManager::loadTimestamps() {
+ Common::HashMap<Common::String, uint32> timestamps;
+
+ //refresh the files list
+ Common::Array<Common::String> files;
+ g_system->getSavefileManager()->updateSavefilesList(files);
+
+ //start with listing all the files in saves/ directory and setting invalid timestamp to them
+ Common::StringArray localFiles = g_system->getSavefileManager()->listSavefiles("*");
+ for (uint32 i = 0; i < localFiles.size(); ++i)
+ timestamps[localFiles[i]] = INVALID_TIMESTAMP;
+
+ //now actually load timestamps from file
+ Common::InSaveFile *file = g_system->getSavefileManager()->openRawFile(TIMESTAMPS_FILENAME);
+ if (!file) {
+ warning("DefaultSaveFileManager: failed to open '%s' file to load timestamps", TIMESTAMPS_FILENAME);
+ return timestamps;
+ }
+
+ while (!file->eos()) {
+ //read filename into buffer (reading until the first ' ')
+ Common::String buffer;
+ while (!file->eos()) {
+ byte b = file->readByte();
+ if (b == ' ') break;
+ buffer += (char)b;
+ }
+
+ //read timestamp info buffer (reading until ' ' or some line ending char)
+ Common::String filename = buffer;
+ while (true) {
+ bool lineEnded = false;
+ buffer = "";
+ while (!file->eos()) {
+ byte b = file->readByte();
+ if (b == ' ' || b == '\n' || b == '\r') {
+ lineEnded = (b == '\n');
+ break;
+ }
+ buffer += (char)b;
+ }
+
+ if (buffer == "" && file->eos()) break;
+ if (!lineEnded) filename += " " + buffer;
+ else break;
+ }
+
+ //parse timestamp
+ uint32 timestamp = buffer.asUint64();
+ if (buffer == "" || timestamp == 0) break;
+ timestamps[filename] = timestamp;
+ }
+
+ delete file;
+ return timestamps;
+}
+
+void DefaultSaveFileManager::saveTimestamps(Common::HashMap<Common::String, uint32> &timestamps) {
+ Common::DumpFile f;
+ Common::String filename = concatWithSavesPath(TIMESTAMPS_FILENAME);
+ if (!f.open(filename, true)) {
+ warning("DefaultSaveFileManager: failed to open '%s' file to save timestamps", filename.c_str());
+ return;
+ }
+
+ for (Common::HashMap<Common::String, uint32>::iterator i = timestamps.begin(); i != timestamps.end(); ++i) {
+ Common::String data = i->_key + Common::String::format(" %u\n", i->_value);
+ if (f.write(data.c_str(), data.size()) != data.size()) {
+ warning("DefaultSaveFileManager: failed to write timestamps data into '%s'", filename.c_str());
+ return;
+ }
+ }
+
+ f.flush();
+ f.finalize();
+ f.close();
+}
+
+Common::String DefaultSaveFileManager::concatWithSavesPath(Common::String name) {
+ Common::String path = ConfMan.get("savepath");
+ if (path.size() > 0 && (path.lastChar() == '/' || path.lastChar() == '\\'))
+ return path + name;
+
+ //simple heuristic to determine which path separator to use
+ int backslashes = 0;
+ for (uint32 i = 0; i < path.size(); ++i)
+ if (path[i] == '/') --backslashes;
+ else if (path[i] == '\\') ++backslashes;
+
+ if (backslashes) return path + '\\' + name;
+ return path + '/' + name;
+}
+
+#endif // ifdef USE_CLOUD
+
#endif // !defined(DISABLE_DEFAULT_SAVEFILEMANAGER)
diff --git a/backends/saves/default/default-saves.h b/backends/saves/default/default-saves.h
index af30cf45e9..e9edfb1f36 100644
--- a/backends/saves/default/default-saves.h
+++ b/backends/saves/default/default-saves.h
@@ -27,7 +27,8 @@
#include "common/savefile.h"
#include "common/str.h"
#include "common/fs.h"
-#include "common/hashmap.h"
+#include "common/hash-str.h"
+#include <limits.h>
/**
* Provides a default savefile manager implementation for common platforms.
@@ -44,6 +45,17 @@ public:
virtual Common::OutSaveFile *openForSaving(const Common::String &filename, bool compress = true);
virtual bool removeSavefile(const Common::String &filename);
+#ifdef USE_CLOUD
+
+ static const uint32 INVALID_TIMESTAMP = UINT_MAX;
+ static const char *TIMESTAMPS_FILENAME;
+
+ static Common::HashMap<Common::String, uint32> loadTimestamps();
+ static void saveTimestamps(Common::HashMap<Common::String, uint32> &timestamps);
+ static Common::String concatWithSavesPath(Common::String name);
+
+#endif
+
protected:
/**
* Get the path to the savegame directory.