diff options
Diffstat (limited to 'backends')
-rw-r--r-- | backends/cloud/dropbox/dropboxstorage.cpp | 8 | ||||
-rw-r--r-- | backends/cloud/dropbox/dropboxstorage.h | 3 | ||||
-rw-r--r-- | backends/cloud/onedrive/onedrivestorage.cpp | 12 | ||||
-rw-r--r-- | backends/cloud/onedrive/onedrivestorage.h | 3 | ||||
-rw-r--r-- | backends/cloud/storage.cpp | 24 | ||||
-rw-r--r-- | backends/cloud/storage.h | 26 | ||||
-rw-r--r-- | backends/networking/curl/connectionmanager.cpp | 11 | ||||
-rw-r--r-- | backends/networking/curl/connectionmanager.h | 13 |
8 files changed, 70 insertions, 30 deletions
diff --git a/backends/cloud/dropbox/dropboxstorage.cpp b/backends/cloud/dropbox/dropboxstorage.cpp index f51819ccae..861a58db4b 100644 --- a/backends/cloud/dropbox/dropboxstorage.cpp +++ b/backends/cloud/dropbox/dropboxstorage.cpp @@ -110,11 +110,11 @@ void DropboxStorage::printStorageFile(UploadResponse response) { } Networking::Request *DropboxStorage::listDirectory(Common::String path, ListDirectoryCallback outerCallback, Networking::ErrorCallback errorCallback, bool recursive) { - return ConnMan.addRequest(new DropboxListDirectoryRequest(_token, path, outerCallback, errorCallback, recursive)); + return addRequest(new DropboxListDirectoryRequest(_token, path, outerCallback, errorCallback, recursive)); } Networking::Request *DropboxStorage::upload(Common::String path, Common::SeekableReadStream *contents, UploadCallback callback, Networking::ErrorCallback errorCallback) { - return ConnMan.addRequest(new DropboxUploadRequest(_token, path, contents, callback, errorCallback)); + return addRequest(new DropboxUploadRequest(_token, path, contents, callback, errorCallback)); } Networking::Request *DropboxStorage::streamFile(Common::String path, Networking::NetworkReadStreamCallback callback, Networking::ErrorCallback errorCallback) { @@ -134,14 +134,14 @@ Networking::Request *DropboxStorage::streamFile(Common::String path, Networking: Networking::Request *DropboxStorage::createDirectory(Common::String path, BoolCallback callback, Networking::ErrorCallback errorCallback) { if (!errorCallback) errorCallback = getErrorPrintingCallback(); - return ConnMan.addRequest(new DropboxCreateDirectoryRequest(_token, path, callback, errorCallback)); + return addRequest(new DropboxCreateDirectoryRequest(_token, path, callback, errorCallback)); } Networking::Request *DropboxStorage::info(StorageInfoCallback outerCallback, Networking::ErrorCallback errorCallback) { Networking::JsonCallback innerCallback = new Common::CallbackBridge<DropboxStorage, StorageInfoResponse, Networking::JsonResponse>(this, &DropboxStorage::infoInnerCallback, outerCallback); Networking::CurlJsonRequest *request = new Networking::CurlJsonRequest(innerCallback, errorCallback, "https://api.dropboxapi.com/1/account/info"); request->addHeader("Authorization: Bearer " + _token); - return ConnMan.addRequest(request); + return addRequest(request); //that callback bridge wraps the outerCallback (passed in arguments from user) into innerCallback //so, when CurlJsonRequest is finished, it calls the innerCallback //innerCallback (which is DropboxStorage::infoInnerCallback in this case) processes the void *ptr diff --git a/backends/cloud/dropbox/dropboxstorage.h b/backends/cloud/dropbox/dropboxstorage.h index 2c60097701..c186d1e5d6 100644 --- a/backends/cloud/dropbox/dropboxstorage.h +++ b/backends/cloud/dropbox/dropboxstorage.h @@ -91,9 +91,6 @@ public: /** Returns storage's saves directory path with the trailing slash. */ virtual Common::String savesDirectoryPath(); - /** Returns whether there are any requests running. */ - virtual bool isWorking() { return false; } //TODO - /** * Load token and user id from configs and return DropboxStorage for those. * @return pointer to the newly created DropboxStorage or 0 if some problem occured. diff --git a/backends/cloud/onedrive/onedrivestorage.cpp b/backends/cloud/onedrive/onedrivestorage.cpp index 190a7ab603..98f0ac5a4d 100644 --- a/backends/cloud/onedrive/onedrivestorage.cpp +++ b/backends/cloud/onedrive/onedrivestorage.cpp @@ -84,7 +84,7 @@ void OneDriveStorage::getAccessToken(BoolCallback callback, Common::String code) request->addPostField("client_id=" + Common::String(KEY)); request->addPostField("client_secret=" + Common::String(SECRET)); request->addPostField("&redirect_uri=http%3A%2F%2Flocalhost%3A12345%2F"); - ConnMan.addRequest(request); + addRequest(request); } void OneDriveStorage::tokenRefreshed(BoolCallback callback, Networking::JsonResponse response) { @@ -198,11 +198,11 @@ void OneDriveStorage::fileInfoCallback(Networking::NetworkReadStreamCallback out } Networking::Request *OneDriveStorage::listDirectory(Common::String path, ListDirectoryCallback callback, Networking::ErrorCallback errorCallback, bool recursive) { - return ConnMan.addRequest(new OneDriveListDirectoryRequest(this, path, callback, errorCallback, recursive)); + return addRequest(new OneDriveListDirectoryRequest(this, path, callback, errorCallback, recursive)); } Networking::Request *OneDriveStorage::upload(Common::String path, Common::SeekableReadStream *contents, UploadCallback callback, Networking::ErrorCallback errorCallback) { - return ConnMan.addRequest(new OneDriveUploadRequest(this, path, contents, callback, errorCallback)); + return addRequest(new OneDriveUploadRequest(this, path, contents, callback, errorCallback)); } Networking::Request *OneDriveStorage::streamFile(Common::String path, Networking::NetworkReadStreamCallback outerCallback, Networking::ErrorCallback errorCallback) { @@ -210,7 +210,7 @@ Networking::Request *OneDriveStorage::streamFile(Common::String path, Networking Networking::JsonCallback innerCallback = new Common::CallbackBridge<OneDriveStorage, Networking::NetworkReadStreamResponse, Networking::JsonResponse>(this, &OneDriveStorage::fileInfoCallback, outerCallback); Networking::CurlJsonRequest *request = new OneDriveTokenRefresher(this, innerCallback, errorCallback, url.c_str()); request->addHeader("Authorization: Bearer " + _token); - return ConnMan.addRequest(request); + return addRequest(request); } void OneDriveStorage::fileDownloaded(BoolResponse response) { @@ -238,14 +238,14 @@ void OneDriveStorage::printFile(UploadResponse response) { Networking::Request *OneDriveStorage::createDirectory(Common::String path, BoolCallback callback, Networking::ErrorCallback errorCallback) { if (!errorCallback) errorCallback = getErrorPrintingCallback(); - return ConnMan.addRequest(new OneDriveCreateDirectoryRequest(this, path, callback, errorCallback)); + return addRequest(new OneDriveCreateDirectoryRequest(this, path, callback, errorCallback)); } Networking::Request *OneDriveStorage::info(StorageInfoCallback callback, Networking::ErrorCallback errorCallback) { Networking::JsonCallback innerCallback = new Common::CallbackBridge<OneDriveStorage, StorageInfoResponse, Networking::JsonResponse>(this, &OneDriveStorage::infoInnerCallback, callback); Networking::CurlJsonRequest *request = new OneDriveTokenRefresher(this, innerCallback, errorCallback, "https://api.onedrive.com/v1.0/drive/special/approot"); request->addHeader("Authorization: bearer " + _token); - return ConnMan.addRequest(request); + return addRequest(request); } Common::String OneDriveStorage::savesDirectoryPath() { return "saves/"; } diff --git a/backends/cloud/onedrive/onedrivestorage.h b/backends/cloud/onedrive/onedrivestorage.h index 5edd96e59c..a09d68b6fd 100644 --- a/backends/cloud/onedrive/onedrivestorage.h +++ b/backends/cloud/onedrive/onedrivestorage.h @@ -98,9 +98,6 @@ public: /** Returns storage's saves directory path with the trailing slash. */ virtual Common::String savesDirectoryPath(); - /** Returns whether there are any requests running. */ - virtual bool isWorking() { return false; } //TODO - /** * Load token and user id from configs and return OneDriveStorage for those. * @return pointer to the newly created OneDriveStorage or 0 if some problem occured. diff --git a/backends/cloud/storage.cpp b/backends/cloud/storage.cpp index 90e095a146..0f9a2a168a 100644 --- a/backends/cloud/storage.cpp +++ b/backends/cloud/storage.cpp @@ -30,6 +30,10 @@ namespace Cloud { +Storage::Storage(): _runningRequestsCount(0) {} + +Storage::~Storage() {} + Networking::ErrorCallback Storage::getErrorPrintingCallback() { return new Common::Callback<Storage, Networking::ErrorResponse>(this, &Storage::printErrorResponse); } @@ -39,6 +43,17 @@ void Storage::printErrorResponse(Networking::ErrorResponse error) { debug("%s", error.response.c_str()); } +Networking::Request *Storage::addRequest(Networking::Request *request) { + ++_runningRequestsCount; + if (_runningRequestsCount == 1) debug("Storage is working now"); + return ConnMan.addRequest(request, new Common::Callback<Storage, Networking::Request *>(this, &Storage::requestFinishedCallback)); +} + +void Storage::requestFinishedCallback(Networking::Request *invalidRequestPointer) { + --_runningRequestsCount; + if (_runningRequestsCount == 0) debug("Storage is not working now"); +} + Networking::Request *Storage::upload(Common::String remotePath, Common::String localPath, UploadCallback callback, Networking::ErrorCallback errorCallback) { if (!errorCallback) errorCallback = getErrorPrintingCallback(); @@ -68,19 +83,22 @@ Networking::Request *Storage::download(Common::String remotePath, Common::String return nullptr; } - return ConnMan.addRequest(new DownloadRequest(this, callback, errorCallback, remotePath, f)); + return addRequest(new DownloadRequest(this, callback, errorCallback, remotePath, f)); } Networking::Request *Storage::downloadFolder(Common::String remotePath, Common::String localPath, FileArrayCallback callback, Networking::ErrorCallback errorCallback, bool recursive) { if (!errorCallback) errorCallback = getErrorPrintingCallback(); - return ConnMan.addRequest(new FolderDownloadRequest(this, callback, errorCallback, remotePath, localPath, recursive)); + return addRequest(new FolderDownloadRequest(this, callback, errorCallback, remotePath, localPath, recursive)); } Networking::Request *Storage::syncSaves(BoolCallback callback, Networking::ErrorCallback errorCallback) { if (!errorCallback) errorCallback = getErrorPrintingCallback(); - return ConnMan.addRequest(new SavesSyncRequest(this, callback, errorCallback)); + return addRequest(new SavesSyncRequest(this, callback, errorCallback)); } +bool Storage::isWorking() { + return _runningRequestsCount > 0; +} } // End of namespace Cloud diff --git a/backends/cloud/storage.h b/backends/cloud/storage.h index 1efee85bb3..b1c62ba05b 100644 --- a/backends/cloud/storage.h +++ b/backends/cloud/storage.h @@ -48,7 +48,9 @@ public: typedef Common::BaseCallback<UploadResponse> *UploadCallback; typedef Common::BaseCallback<ListDirectoryResponse> *ListDirectoryCallback; -protected: +protected: + /** Keeps track of running requests. */ + uint32 _runningRequestsCount; /** Returns default error callback (printErrorResponse). */ virtual Networking::ErrorCallback getErrorPrintingCallback(); @@ -56,9 +58,25 @@ protected: /** Prints ErrorResponse contents with debug(). */ virtual void printErrorResponse(Networking::ErrorResponse error); + /** + * Adds request to the ConnMan, but also increases _runningRequestsCount. + * This method should be used by Storage implementations instead of + * direct ConnMan.addRequest() call. + * + * @return the same Request pointer, just as a shortcut + */ + virtual Networking::Request *addRequest(Networking::Request *request); + + /** + * Decreases _runningRequestCount. It's called from ConnMan automatically. + * Passed pointer is dangling, but one can use the address to determine + * some special Requests (which addresses were remembered somewhere). + */ + virtual void requestFinishedCallback(Networking::Request *invalidRequestPointer); + public: - Storage() {} - virtual ~Storage() {} + Storage(); + virtual ~Storage(); /** * Storage methods, which are used by CloudManager to save @@ -113,7 +131,7 @@ public: virtual Common::String savesDirectoryPath() = 0; /** Returns whether there are any requests running. */ - virtual bool isWorking() = 0; + virtual bool isWorking(); }; } // End of namespace Cloud diff --git a/backends/networking/curl/connectionmanager.cpp b/backends/networking/curl/connectionmanager.cpp index 949dc949f1..ef3c858bec 100644 --- a/backends/networking/curl/connectionmanager.cpp +++ b/backends/networking/curl/connectionmanager.cpp @@ -51,8 +51,8 @@ void ConnectionManager::registerEasyHandle(CURL *easy) { curl_multi_add_handle(_multi, easy); } -Request *ConnectionManager::addRequest(Request *request) { - _requests.push_back(request); +Request *ConnectionManager::addRequest(Request *request, RequestCallback callback) { + _requests.push_back(RequestWithCallback(request, callback)); if (!_timerStarted) startTimer(); return request; } @@ -89,10 +89,11 @@ void ConnectionManager::handle() { void ConnectionManager::interateRequests() { //call handle() of all running requests (so they can do their work) debug("handling %d request(s)", _requests.size()); - for (Common::Array<Request *>::iterator i = _requests.begin(); i != _requests.end();) { - Request *request = *i; + for (Common::Array<RequestWithCallback>::iterator i = _requests.begin(); i != _requests.end();) { + Request *request = i->request; if (!request || request->state() == FINISHED) { - delete (*i); + delete (i->request); + if (i->callback) (*i->callback)(i->request); //that's not a mistake (we're passing an address and that method knows there is no object anymore) _requests.erase(i); continue; } diff --git a/backends/networking/curl/connectionmanager.h b/backends/networking/curl/connectionmanager.h index c632fa54ef..b39a779558 100644 --- a/backends/networking/curl/connectionmanager.h +++ b/backends/networking/curl/connectionmanager.h @@ -39,9 +39,18 @@ class NetworkReadStream; class ConnectionManager : public Common::Singleton<ConnectionManager> { friend void connectionsThread(void *); //calls handle() + typedef Common::BaseCallback<Request *> *RequestCallback; + + struct RequestWithCallback { //I'm completely out of ideas + Request *request; + RequestCallback callback; + + RequestWithCallback(Request *rq = nullptr, RequestCallback cb = nullptr): request(rq), callback(cb) {} + }; + CURLM *_multi; bool _timerStarted; - Common::Array<Request *> _requests; + Common::Array<RequestWithCallback> _requests; void startTimer(int interval = 1000000); //1 second is the default interval void stopTimer(); @@ -71,7 +80,7 @@ public: * * @return the same Request pointer, just as a shortcut */ - Request *addRequest(Request *request); + Request *addRequest(Request *request, RequestCallback callback = nullptr); }; /** Shortcut for accessing the connection manager. */ |