diff options
Diffstat (limited to 'backends')
| -rw-r--r-- | backends/cloud/dropbox/dropboxstorage.cpp | 26 | ||||
| -rw-r--r-- | backends/cloud/dropbox/dropboxstorage.h | 8 | ||||
| -rw-r--r-- | backends/cloud/storage.cpp | 73 | ||||
| -rw-r--r-- | backends/cloud/storage.h | 19 | ||||
| -rw-r--r-- | backends/module.mk | 3 | ||||
| -rw-r--r-- | backends/networking/curl/connectionmanager.cpp | 63 | ||||
| -rw-r--r-- | backends/networking/curl/connectionmanager.h | 40 | ||||
| -rw-r--r-- | backends/networking/curl/curljsonrequest.cpp | 5 | ||||
| -rw-r--r-- | backends/networking/curl/curljsonrequest.h | 6 | ||||
| -rw-r--r-- | backends/networking/curl/networkreadstream.cpp | 2 | ||||
| -rw-r--r-- | backends/networking/curl/networkreadstream.h | 2 | ||||
| -rw-r--r-- | backends/networking/curl/request.h (renamed from backends/cloud/request.h) | 15 | 
12 files changed, 123 insertions, 139 deletions
diff --git a/backends/cloud/dropbox/dropboxstorage.cpp b/backends/cloud/dropbox/dropboxstorage.cpp index add6bff54c..93f0eebcf6 100644 --- a/backends/cloud/dropbox/dropboxstorage.cpp +++ b/backends/cloud/dropbox/dropboxstorage.cpp @@ -22,6 +22,7 @@  #define FORBIDDEN_SYMBOL_ALLOW_ALL  #include "backends/cloud/dropbox/dropboxstorage.h" +#include "backends/networking/curl/connectionmanager.h"  #include "backends/networking/curl/curljsonrequest.h"  #include "common/config-manager.h"  #include "common/debug.h" @@ -76,8 +77,7 @@ DropboxStorage::~DropboxStorage() {  	curl_global_cleanup();  } -void DropboxStorage::listDirectory(Common::String path) { -	startTimer(1000000); //in one second +void DropboxStorage::listDirectory(Common::String path) {	  }  void DropboxStorage::syncSaves() { @@ -88,7 +88,7 @@ void DropboxStorage::syncSaves() {  void DropboxStorage::printInfo() {  	Networking::CurlJsonRequest *request = new Networking::CurlJsonRequest(printJsonCallback, "https://api.dropboxapi.com/1/account/info");  	request->addHeader("Authorization: Bearer " + _token); -	addRequest(request); +	ConnMan.addRequest(request);  }  DropboxStorage *DropboxStorage::loadFromConfig() { @@ -119,10 +119,10 @@ Common::String DropboxStorage::getAuthLink() {  	return url;  } -DropboxStorage *DropboxStorage::authThroughConsole() { +void DropboxStorage::authThroughConsole() {  	if (!ConfMan.hasKey("DROPBOX_KEY", "cloud") || !ConfMan.hasKey("DROPBOX_SECRET", "cloud")) {  		warning("No Dropbox keys available, cannot do auth"); -		return 0; +		return;  	}  	KEY = ConfMan.get("DROPBOX_KEY", "cloud"); @@ -130,29 +130,25 @@ DropboxStorage *DropboxStorage::authThroughConsole() {  	if (ConfMan.hasKey("dropbox_code", "cloud")) {  		//phase 2: get access_token using specified code -		return getAccessToken(ConfMan.get("dropbox_code", "cloud")); +		getAccessToken(ConfMan.get("dropbox_code", "cloud")); +		return;  	}  	debug("Navigate to this URL and press \"Allow\":");  	debug("%s\n", getAuthLink().c_str());  	debug("Then, add dropbox_code key in [cloud] section of configuration file. You should copy the <code> value from URL and put it as value for that key.\n");  	debug("Navigate to this URL to get more information on ScummVM's configuration files:"); -	debug("http://wiki.scummvm.org/index.php/User_Manual/Configuring_ScummVM#Using_the_configuration_file_to_configure_ScummVM\n"); -	return 0; +	debug("http://wiki.scummvm.org/index.php/User_Manual/Configuring_ScummVM#Using_the_configuration_file_to_configure_ScummVM\n");	  } -DropboxStorage *DropboxStorage::getAccessToken(Common::String code) { +void DropboxStorage::getAccessToken(Common::String code) {  	Networking::CurlJsonRequest *request = new Networking::CurlJsonRequest(saveAccessTokenCallback, "https://api.dropboxapi.com/1/oauth2/token");  	request->addPostField("code=" + code);  	request->addPostField("grant_type=authorization_code");  	request->addPostField("client_id=" + KEY);  	request->addPostField("client_secret=" + SECRET); -	request->addPostField("&redirect_uri=http%3A%2F%2Flocalhost%3A12345%2F"); -	 -	//OK, that's not how I imagined that...	 -	DropboxStorage *storage = new DropboxStorage("", ""); -	storage->addRequest(request); -	return storage; +	request->addPostField("&redirect_uri=http%3A%2F%2Flocalhost%3A12345%2F");	 +	ConnMan.addRequest(request);	  }  } //end of namespace Dropbox diff --git a/backends/cloud/dropbox/dropboxstorage.h b/backends/cloud/dropbox/dropboxstorage.h index f2281f146f..0500db5d49 100644 --- a/backends/cloud/dropbox/dropboxstorage.h +++ b/backends/cloud/dropbox/dropboxstorage.h @@ -24,7 +24,7 @@  #define BACKENDS_CLOUD_DROPBOX_STORAGE_H  #include "backends/cloud/storage.h" -#include "../manager.h" +#include "backends/cloud/manager.h"  namespace Cloud {  namespace Dropbox { @@ -37,7 +37,7 @@ class DropboxStorage: public Cloud::Storage {  	/** This private constructor is called from loadFromConfig(). */  	DropboxStorage(Common::String token, Common::String uid); -	static DropboxStorage *getAccessToken(Common::String code); +	static void getAccessToken(Common::String code);  public:	  	virtual ~DropboxStorage(); @@ -58,10 +58,8 @@ public:  	/**  	* Show message with Dropbox auth instructions. (Temporary) -	* Returns temporary DropboxStorage, which does network requests -	* to get access token.  	*/ -	static DropboxStorage *authThroughConsole(); +	static void authThroughConsole();  };  } //end of namespace Dropbox diff --git a/backends/cloud/storage.cpp b/backends/cloud/storage.cpp deleted file mode 100644 index d7217a57cd..0000000000 --- a/backends/cloud/storage.cpp +++ /dev/null @@ -1,73 +0,0 @@ -/* ScummVM - Graphic Adventure Engine -* -* ScummVM is the legal property of its developers, whose names -* are too numerous to list here. Please refer to the COPYRIGHT -* file distributed with this source distribution. -* -* This program is free software; you can redistribute it and/or -* modify it under the terms of the GNU General Public License -* as published by the Free Software Foundation; either version 2 -* of the License, or (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software -* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -* -*/ - -#include "backends/cloud/storage.h" -#include "common/debug.h" -#include "common/system.h" -#include "common/timer.h" - -namespace Cloud { - -void cloudThread(void *thread) { -	Storage *cloudThread = (Storage *)thread; -	cloudThread->handler(); -} - -Storage::Storage() : _timerStarted(false) {} - -void Storage::addRequest(Request *request) { -	_requests.push_back(request); -	if (!_timerStarted) startTimer(); -} - -void Storage::handler() { -	//TODO: lock mutex here (in case another handler() would be called before this one ends) -	debug("\nhandler's here"); -	for (Common::Array<Request *>::iterator i = _requests.begin(); i != _requests.end();) { -		if ((*i)->handle(_connectionManager)) { -			delete (*i); -			_requests.erase(i); -		} -		else ++i; -	} -	if (_requests.empty()) stopTimer(); - -	_connectionManager.handle(); -	//TODO: unlock mutex here -} - -void Storage::startTimer(int interval) { -	Common::TimerManager *manager = g_system->getTimerManager(); -	if (manager->installTimerProc(cloudThread, interval, this, "Cloud Thread")) { -		_timerStarted = true; -	} else { -		warning("Failed to create cloud thread");		 -	} -} - -void Storage::stopTimer() { -	Common::TimerManager *manager = g_system->getTimerManager(); -	manager->removeTimerProc(cloudThread); -	_timerStarted = false; -} - -} //end of namespace Cloud diff --git a/backends/cloud/storage.h b/backends/cloud/storage.h index a5d048d3af..9e23e97761 100644 --- a/backends/cloud/storage.h +++ b/backends/cloud/storage.h @@ -24,28 +24,13 @@  #define BACKENDS_CLOUD_STORAGE_H  #include "common/str.h" -#include "common/array.h" -#include "backends/cloud/request.h" -#include "backends/networking/curl/connectionmanager.h"  namespace Cloud {  class Storage { -	friend void cloudThread(void *); //calls handler() -	bool _timerStarted; - -protected: -	Common::Array<Request *> _requests; -	Networking::ConnectionManager _connectionManager; - -	virtual void addRequest(Request *request); //starts the timer if it's not started -	virtual void handler();	 -	virtual void startTimer(int interval = 1000000); //1 second is the default interval -	virtual void stopTimer(); -  public: -	Storage(); -	virtual ~Storage() {}; +	Storage() {} +	virtual ~Storage() {}  	/**  	* Lists given directory. diff --git a/backends/module.mk b/backends/module.mk index 72183f9563..0142531835 100644 --- a/backends/module.mk +++ b/backends/module.mk @@ -21,8 +21,7 @@ MODULE_OBJS := \  ifdef USE_CLOUD  MODULE_OBJS += \ -	cloud/manager.o \ -	cloud/storage.o \ +	cloud/manager.o \	  	cloud/dropbox/dropboxstorage.o  endif diff --git a/backends/networking/curl/connectionmanager.cpp b/backends/networking/curl/connectionmanager.cpp index d34eab23e8..31e99f989c 100644 --- a/backends/networking/curl/connectionmanager.cpp +++ b/backends/networking/curl/connectionmanager.cpp @@ -25,11 +25,16 @@  #include "backends/networking/curl/connectionmanager.h"  #include "backends/networking/curl/networkreadstream.h"  #include "common/debug.h" +#include "common/system.h" +#include "common/timer.h"  #include <curl/curl.h> +using Common::Singleton; + +DECLARE_SINGLETON(Networking::ConnectionManager);  namespace Networking { -ConnectionManager::ConnectionManager(): _multi(0) { +ConnectionManager::ConnectionManager(): _multi(0), _timerStarted(false) {  	curl_global_init(CURL_GLOBAL_ALL);  	_multi = curl_multi_init();  } @@ -39,13 +44,57 @@ ConnectionManager::~ConnectionManager() {  	curl_global_cleanup();  } -NetworkReadStream *ConnectionManager::makeRequest(const char *url, curl_slist *headersList, Common::String postFields) { -	NetworkReadStream *stream = new NetworkReadStream(url, headersList, postFields); -	curl_multi_add_handle(_multi, stream->getEasyHandle()); -	return stream; +void ConnectionManager::registerEasyHandle(CURL *easy) { +	curl_multi_add_handle(_multi, easy); +} + +void ConnectionManager::addRequest(Request *request) { +	_requests.push_back(request); +	if (!_timerStarted) startTimer(); +} + +//private goes here: + +void connectionsThread(void *ignored) { +	ConnMan.handle(); +} + +void ConnectionManager::startTimer(int interval) { +	Common::TimerManager *manager = g_system->getTimerManager(); +	if (manager->installTimerProc(connectionsThread, interval, 0, "Networking::ConnectionManager's Timer")) { +		_timerStarted = true; +	} else { +		warning("Failed to install Networking::ConnectionManager's timer"); +	} +} + +void ConnectionManager::stopTimer() { +	Common::TimerManager *manager = g_system->getTimerManager(); +	manager->removeTimerProc(connectionsThread); +	_timerStarted = false;  }  void ConnectionManager::handle() { +	//TODO: lock mutex here (in case another handle() would be called before this one ends) +	interateRequests(); +	processTransfers(); +	//TODO: unlock mutex here +} + +void ConnectionManager::interateRequests() { +	//call handle() of all running requests (so they can do their work) +	debug("handler's here"); +	for (Common::Array<Request *>::iterator i = _requests.begin(); i != _requests.end();) { +		if ((*i)->handle()) { +			delete (*i); +			_requests.erase(i); +		} else ++i; +	} +	if (_requests.empty()) stopTimer(); +} + +void ConnectionManager::processTransfers() { +	//check libcurl's transfers and notify requests of messages from queue (transfer completion or failure)  	int transfersRunning;  	curl_multi_perform(_multi, &transfersRunning); @@ -59,9 +108,9 @@ void ConnectionManager::handle() {  		if (stream) stream->finished();  		if (curlMsg->msg == CURLMSG_DONE) { -			debug("ConnectionManager: SUCCESS (%d - %s)", curlMsg->data.result, curl_easy_strerror(curlMsg->data.result));			 +			debug("ConnectionManager: SUCCESS (%d - %s)", curlMsg->data.result, curl_easy_strerror(curlMsg->data.result));  		} else { -			debug("ConnectionManager: FAILURE (CURLMsg (%d))", curlMsg->msg);			 +			debug("ConnectionManager: FAILURE (CURLMsg (%d))", curlMsg->msg);  		}  		curl_multi_remove_handle(_multi, easyHandle); diff --git a/backends/networking/curl/connectionmanager.h b/backends/networking/curl/connectionmanager.h index b83de6191a..ed726441c4 100644 --- a/backends/networking/curl/connectionmanager.h +++ b/backends/networking/curl/connectionmanager.h @@ -23,8 +23,12 @@  #ifndef BACKENDS_NETWORKING_CURL_CONNECTIONMANAGER_H  #define BACKENDS_NETWORKING_CURL_CONNECTIONMANAGER_H +#include "backends/networking/curl/request.h"  #include "common/str.h" +#include "common/singleton.h" +#include "common/array.h" +typedef void CURL;  typedef void CURLM;  struct curl_slist; @@ -32,17 +36,43 @@ namespace Networking {  class NetworkReadStream; -class ConnectionManager { -	CURLM *_multi; +class ConnectionManager : public Common::Singleton<ConnectionManager> { +	friend void connectionsThread(void *); //calls handle() + +	CURLM *_multi;	 +	bool _timerStarted; +	Common::Array<Request *> _requests;	 +	 +	void startTimer(int interval = 1000000); //1 second is the default interval +	void stopTimer(); +	void handle(); +	void interateRequests(); +	void processTransfers();  public:  	ConnectionManager();  	virtual ~ConnectionManager(); -	NetworkReadStream *makeRequest(const char *url, curl_slist *headersList, Common::String postFields); -	void handle(); +	/** +	* All libcurl transfers are going through this ConnectionManager. +	* So, if you want to start any libcurl transfer, you must create +	* an easy handle and register it using this method. +	*/ +	void registerEasyHandle(CURL *easy); + +	/** +	* Use this method to add new Request into manager's queue. +	* Manager will periodically call handle() method of these +	* Requests until they return true. +	* +	* @note This method starts the timer if it's not started yet. +	*/ +	void addRequest(Request *request);  }; -} //end of namespace Cloud +/** Shortcut for accessing the connection manager. */ +#define ConnMan		Networking::ConnectionManager::instance() + +} //end of namespace Networking  #endif diff --git a/backends/networking/curl/curljsonrequest.cpp b/backends/networking/curl/curljsonrequest.cpp index 0c6363467a..59bc830692 100644 --- a/backends/networking/curl/curljsonrequest.cpp +++ b/backends/networking/curl/curljsonrequest.cpp @@ -23,6 +23,7 @@  #define FORBIDDEN_SYMBOL_ALLOW_ALL  #include "backends/networking/curl/curljsonrequest.h" +#include "backends/networking/curl/connectionmanager.h"  #include "backends/networking/curl/networkreadstream.h"  #include "common/debug.h"  #include "common/json.h" @@ -56,8 +57,8 @@ char *CurlJsonRequest::getPreparedContents() {  	return (char *)result;  } -bool CurlJsonRequest::handle(ConnectionManager &manager) { -	if (!_stream) _stream = manager.makeRequest(_url, _headersList, _postFields); +bool CurlJsonRequest::handle() { +	if (!_stream) _stream = new NetworkReadStream(_url, _headersList, _postFields);  	if (_stream) {  		const int kBufSize = 16*1024; diff --git a/backends/networking/curl/curljsonrequest.h b/backends/networking/curl/curljsonrequest.h index 17df9693f2..cbf3f6dd56 100644 --- a/backends/networking/curl/curljsonrequest.h +++ b/backends/networking/curl/curljsonrequest.h @@ -23,7 +23,7 @@  #ifndef BACKENDS_NETWORKING_CURL_CURLJSONREQUEST_H  #define BACKENDS_NETWORKING_CURL_CURLJSONREQUEST_H -#include "backends/cloud/request.h" +#include "backends/networking/curl/request.h"  #include "common/memstream.h"  struct curl_slist; @@ -32,7 +32,7 @@ namespace Networking {  class NetworkReadStream; -class CurlJsonRequest : public Cloud::Request {	 +class CurlJsonRequest : public Request {	  	const char *_url;  	NetworkReadStream *_stream;  	curl_slist *_headersList; @@ -46,7 +46,7 @@ public:  	CurlJsonRequest(Callback cb, const char *url);  	virtual ~CurlJsonRequest(); -	virtual bool handle(ConnectionManager &manager); +	virtual bool handle();  	void addHeader(Common::String header); diff --git a/backends/networking/curl/networkreadstream.cpp b/backends/networking/curl/networkreadstream.cpp index f2af4fd50c..8fd39d6884 100644 --- a/backends/networking/curl/networkreadstream.cpp +++ b/backends/networking/curl/networkreadstream.cpp @@ -23,6 +23,7 @@  #define FORBIDDEN_SYMBOL_ALLOW_ALL  #include "backends/networking/curl/networkreadstream.h" +#include "backends/networking/curl/connectionmanager.h"  #include "common/debug.h"  #include <curl/curl.h> @@ -47,6 +48,7 @@ NetworkReadStream::NetworkReadStream(const char *url, curl_slist *headersList, C  	curl_easy_setopt(_easy, CURLOPT_HTTPHEADER, headersList);  	curl_easy_setopt(_easy, CURLOPT_POSTFIELDSIZE, postFields.size());  	curl_easy_setopt(_easy, CURLOPT_COPYPOSTFIELDS, postFields.c_str()); +	ConnMan.registerEasyHandle(_easy);  }  NetworkReadStream::~NetworkReadStream() { diff --git a/backends/networking/curl/networkreadstream.h b/backends/networking/curl/networkreadstream.h index bc4b761ba7..6431a01fee 100644 --- a/backends/networking/curl/networkreadstream.h +++ b/backends/networking/curl/networkreadstream.h @@ -40,8 +40,6 @@ public:  	NetworkReadStream(const char *url, curl_slist *headersList, Common::String postFields);  	virtual ~NetworkReadStream(); -	CURL *getEasyHandle() const { return _easy; } -  	/**  	* Returns true if a read failed because the stream end has been reached.  	* This flag is cleared by clearErr(). diff --git a/backends/cloud/request.h b/backends/networking/curl/request.h index d85a68d570..4f901f7c94 100644 --- a/backends/cloud/request.h +++ b/backends/networking/curl/request.h @@ -20,21 +20,20 @@  *  */ -#ifndef BACKENDS_CLOUD_REQUEST_H -#define BACKENDS_CLOUD_REQUEST_H +#ifndef BACKENDS_NETWORKING_CURL_REQUEST_H +#define BACKENDS_NETWORKING_CURL_REQUEST_H -#include "backends/networking/curl/connectionmanager.h" - -namespace Cloud { +namespace Networking {  class Request {  protected: +	typedef void(*Callback)(void *result); +  	/**  	* Callback, which should be called before Request returns true in handle(). -	* That's the way Requests pass the result to the code which asked to create this request.	 +	* That's the way Requests pass the result to the code which asked to create this request.  	*/ -	typedef void(*Callback)(void *result);  	Callback _callback;  public: @@ -47,7 +46,7 @@ public:  	* @return true if request's work is complete and it may be removed from Storage's list  	*/ -	virtual bool handle(Networking::ConnectionManager &manager) = 0; +	virtual bool handle() = 0;  };  } //end of namespace Cloud  | 
