diff options
author | Bastien Bouclet | 2016-09-18 13:05:16 +0200 |
---|---|---|
committer | Bastien Bouclet | 2016-09-18 17:54:12 +0200 |
commit | 1a1a5b5f692ac74e25b03ba2bdc09e0af3606a4a (patch) | |
tree | 462f5a2740370259327a51959a0923da4f28ed0d | |
parent | 361d84ca74b82151509378e1a5bb868b52049502 (diff) | |
download | scummvm-rg350-1a1a5b5f692ac74e25b03ba2bdc09e0af3606a4a.tar.gz scummvm-rg350-1a1a5b5f692ac74e25b03ba2bdc09e0af3606a4a.tar.bz2 scummvm-rg350-1a1a5b5f692ac74e25b03ba2bdc09e0af3606a4a.zip |
CLOUD: Change the cloud icon to be updated by the main thread
The cloud manager registers itself as an event source as a mean to be polled
periodically by the GUI or engine code. The periodical polling is used to
update the OSD icon indicating background sync activity.
Also move the cloud icon from ConnectionManager to CloudManager,
allowing to decouple icon handling from network connections updates.
-rw-r--r-- | backends/cloud/cloudicon.cpp (renamed from backends/networking/curl/cloudicon.cpp) | 143 | ||||
-rw-r--r-- | backends/cloud/cloudicon.h (renamed from backends/networking/curl/cloudicon.h) | 78 | ||||
-rw-r--r-- | backends/cloud/cloudicon_data.h (renamed from backends/networking/curl/cloudicon_data.h) | 0 | ||||
-rw-r--r-- | backends/cloud/cloudicon_disabled_data.h (renamed from backends/networking/curl/cloudicon_disabled_data.h) | 0 | ||||
-rw-r--r-- | backends/cloud/cloudmanager.cpp | 24 | ||||
-rw-r--r-- | backends/cloud/cloudmanager.h | 22 | ||||
-rw-r--r-- | backends/module.mk | 2 | ||||
-rw-r--r-- | backends/networking/curl/connectionmanager.cpp | 7 | ||||
-rw-r--r-- | backends/networking/curl/connectionmanager.h | 5 | ||||
-rw-r--r-- | gui/saveload-dialog.cpp | 2 |
10 files changed, 179 insertions, 104 deletions
diff --git a/backends/networking/curl/cloudicon.cpp b/backends/cloud/cloudicon.cpp index 9aa08af9fb..972efae57b 100644 --- a/backends/networking/curl/cloudicon.cpp +++ b/backends/cloud/cloudicon.cpp @@ -20,23 +20,21 @@ * */ -#include "backends/networking/curl/cloudicon.h" -#include "backends/cloud/cloudmanager.h" +#include "backends/cloud/cloudicon.h" #include "common/memstream.h" -#include "gui/ThemeEngine.h" -#include "gui/gui-manager.h" +#include "common/system.h" #include "image/png.h" -namespace Networking { +namespace Cloud { -const float CloudIcon::ALPHA_STEP = 0.025; +const float CloudIcon::ALPHA_SPEED = 0.0005; const float CloudIcon::ALPHA_MAX = 1; const float CloudIcon::ALPHA_MIN = 0.6; -CloudIcon::CloudIcon(): - _wasVisible(false), _iconsInited(false), _showingDisabled(false), - _currentAlpha(0), _alphaRising(true), _disabledFrames(0) { +CloudIcon::CloudIcon() { initIcons(); + hide(); + _lastUpdateTime = g_system->getMillis(); } CloudIcon::~CloudIcon() { @@ -45,72 +43,95 @@ CloudIcon::~CloudIcon() { _alphaIcon.free(); } -bool CloudIcon::draw() { - bool stop = false; - initIcons(); +void CloudIcon::show(CloudIcon::Type icon, int duration) { + if (_type == icon) { + return; // Nothing to do + } - if (CloudMan.isWorking() || _disabledFrames > 0) { - if (g_system) { - if (!_wasVisible) { - _wasVisible = true; - } - --_disabledFrames; - if (_alphaRising) { - if (_currentAlpha < ALPHA_MIN) - _currentAlpha += 5 * ALPHA_STEP; - else - _currentAlpha += ALPHA_STEP; - if (_currentAlpha > ALPHA_MAX) { - _currentAlpha = ALPHA_MAX; - _alphaRising = false; - } - } else { - _currentAlpha -= ALPHA_STEP; - if (_currentAlpha < ALPHA_MIN) { - _currentAlpha = ALPHA_MIN; - _alphaRising = true; - } - } + if (icon != kNone) { + _state = kShown; + _type = icon; + + if (duration) { + _hideTime = g_system->getMillis() + duration; } else { - _wasVisible = false; + _hideTime = 0; } } else { - _wasVisible = false; - _currentAlpha -= 5 * ALPHA_STEP; - if (_currentAlpha <= 0) { - _currentAlpha = 0; - stop = true; - } + _state = kGoingToHide; } +} + +void CloudIcon::hide() { + _state = kHidden; + _type = kNone; + _hideTime = 0; + _currentAlpha = 0; + _alphaRising = true; +} - if (g_system) { - if (!stop) { - makeAlphaIcon((_showingDisabled ? _disabledIcon : _icon), _currentAlpha); - g_system->displayActivityIconOnOSD(&_alphaIcon); +CloudIcon::Type CloudIcon::getShownType() const { + return _type; +} + +bool CloudIcon::needsUpdate() const { + uint32 delaySinceLastUpdate = g_system->getMillis() - _lastUpdateTime; + return delaySinceLastUpdate >= UPDATE_DELAY_MIN_MILLIS; +} + +void CloudIcon::update() { + uint32 currentTime = g_system->getMillis(); + uint32 delaySinceLastUpdate = currentTime - _lastUpdateTime; + _lastUpdateTime = currentTime; + + switch (_state) { + case kHidden: + return; // Nothing to do + case kShown: + if (_alphaRising) { + if (_currentAlpha < ALPHA_MIN) + _currentAlpha += 5 * ALPHA_SPEED * delaySinceLastUpdate; + else + _currentAlpha += ALPHA_SPEED * delaySinceLastUpdate; + if (_currentAlpha > ALPHA_MAX) { + _currentAlpha = ALPHA_MAX; + _alphaRising = false; + } } else { - g_system->displayActivityIconOnOSD(nullptr); + _currentAlpha -= ALPHA_SPEED * delaySinceLastUpdate; + if (_currentAlpha < ALPHA_MIN) { + _currentAlpha = ALPHA_MIN; + _alphaRising = true; + } } - } - if (stop) - _showingDisabled = false; - return stop; -} + if (_hideTime != 0 && _hideTime <= currentTime) { + _hideTime = 0; + _state = kGoingToHide; + } + break; + case kGoingToHide: + _currentAlpha -= 5 * ALPHA_SPEED * delaySinceLastUpdate; + if (_currentAlpha <= 0) { + hide(); + } + break; + } -void CloudIcon::showDisabled() { - _showingDisabled = true; - _disabledFrames = 20 * 3; //3 seconds 20 fps + if (_state != kHidden) { + makeAlphaIcon((_type == kDisabled ? _disabledIcon : _icon), _currentAlpha); + g_system->displayActivityIconOnOSD(&_alphaIcon); + } else { + g_system->displayActivityIconOnOSD(nullptr); + } } -#include "backends/networking/curl/cloudicon_data.h" -#include "backends/networking/curl/cloudicon_disabled_data.h" +#include "backends/cloud/cloudicon_data.h" +#include "backends/cloud/cloudicon_disabled_data.h" void CloudIcon::initIcons() { - if (_iconsInited) - return; loadIcon(_icon, cloudicon_data, ARRAYSIZE(cloudicon_data)); loadIcon(_disabledIcon, cloudicon_disabled_data, ARRAYSIZE(cloudicon_disabled_data)); - _iconsInited = true; } void CloudIcon::loadIcon(Graphics::Surface &icon, byte *data, uint32 size) { @@ -123,7 +144,7 @@ void CloudIcon::loadIcon(Graphics::Surface &icon, byte *data, uint32 size) { return icon.copyFrom(*s); } -void CloudIcon::makeAlphaIcon(Graphics::Surface &icon, float alpha) { +void CloudIcon::makeAlphaIcon(const Graphics::Surface &icon, float alpha) { _alphaIcon.copyFrom(icon); byte *pixels = (byte *)_alphaIcon.getPixels(); @@ -154,4 +175,4 @@ void CloudIcon::makeAlphaIcon(Graphics::Surface &icon, float alpha) { } } -} // End of namespace Networking +} // End of namespace Cloud diff --git a/backends/networking/curl/cloudicon.h b/backends/cloud/cloudicon.h index d6ea60bd51..2b2f9cfd57 100644 --- a/backends/networking/curl/cloudicon.h +++ b/backends/cloud/cloudicon.h @@ -25,46 +25,66 @@ #include "graphics/surface.h" -namespace Networking { +namespace Cloud { class CloudIcon { - static const float ALPHA_STEP, ALPHA_MAX, ALPHA_MIN; - - bool _wasVisible, _iconsInited, _showingDisabled; - Graphics::Surface _icon, _disabledIcon, _alphaIcon; - float _currentAlpha; - bool _alphaRising; - int _disabledFrames; - - void initIcons(); - void loadIcon(Graphics::Surface &icon, byte *data, uint32 size); - void makeAlphaIcon(Graphics::Surface &icon, float alpha); - public: CloudIcon(); ~CloudIcon(); /** - * This method is called from ConnectionManager every time - * its own timer calls the handle() method. The primary - * responsibility of this draw() method is to draw cloud icon - * on ScummVM's OSD when current cloud Storage is working. - * - * As we don't want ConnectionManager to work when no - * Requests are running, we'd like to stop the timer. But then - * this icon wouldn't have time to disappear smoothly. So, - * in order to do that, ConnectionManager stop its timer - * only when this draw() method returns true, indicating that - * the CloudIcon has disappeared and the timer could be stopped. + * The type of cloud icon to show + */ + enum Type { + kNone, /** Hide the currently shown icon if any */ + kSyncing, /** Cloud syncing icon */ + kDisabled /** Cloud syncing not available icon */ + }; + + /** + * Select the icon to show on the OSD * - * @return true if ConnMan's timer could be stopped. + * @param icon Icon type to show. Use kNone to hide the current icon if any. + * @param duration Duration in milliseconds the icon stays visible on screen. 0 means the icon stays indefinitely. */ - bool draw(); + void show(Type icon, int duration = 0); + + /** The currently visible icon. kNone means no icon is shown. */ + Type getShownType() const; + + /** Returns true if the icon state needs to be checked for changes */ + bool needsUpdate() const; + + /** Update the icon visible on the OSD */ + void update(); + +private: + static const float ALPHA_SPEED, ALPHA_MAX, ALPHA_MIN; + static const int UPDATE_DELAY_MIN_MILLIS = 10; + + enum State { + kHidden, + kShown, + kGoingToHide + }; + + State _state; + Type _type; + + Graphics::Surface _icon, _disabledIcon, _alphaIcon; + float _currentAlpha; + bool _alphaRising; + + uint32 _hideTime; + uint32 _lastUpdateTime; + + void initIcons(); + void loadIcon(Graphics::Surface &icon, byte *data, uint32 size); + void makeAlphaIcon(const Graphics::Surface &icon, float alpha); - /** Draw a "cloud disabled" icon instead of "cloud syncing" one. */ - void showDisabled(); + void hide(); }; -} // End of namespace Networking +} // End of namespace Cloud #endif diff --git a/backends/networking/curl/cloudicon_data.h b/backends/cloud/cloudicon_data.h index 21d88182a3..21d88182a3 100644 --- a/backends/networking/curl/cloudicon_data.h +++ b/backends/cloud/cloudicon_data.h diff --git a/backends/networking/curl/cloudicon_disabled_data.h b/backends/cloud/cloudicon_disabled_data.h index 4340a8a37c..4340a8a37c 100644 --- a/backends/networking/curl/cloudicon_disabled_data.h +++ b/backends/cloud/cloudicon_disabled_data.h diff --git a/backends/cloud/cloudmanager.cpp b/backends/cloud/cloudmanager.cpp index 3456b99ab7..5f7d6942ca 100644 --- a/backends/cloud/cloudmanager.cpp +++ b/backends/cloud/cloudmanager.cpp @@ -45,6 +45,8 @@ const char *const CloudManager::kStoragePrefix = "storage_"; CloudManager::CloudManager() : _currentStorageIndex(0), _activeStorage(nullptr) {} CloudManager::~CloudManager() { + g_system->getEventManager()->getEventDispatcher()->unregisterSource(this); + delete _activeStorage; freeStorages(); } @@ -108,6 +110,8 @@ void CloudManager::init() { _currentStorageIndex = ConfMan.getInt("current_storage", ConfMan.kCloudDomain); loadStorage(); + + g_system->getEventManager()->getEventDispatcher()->registerSource(this, false); } void CloudManager::save() { @@ -383,6 +387,10 @@ void CloudManager::setSyncTarget(GUI::CommandReceiver *target) const { storage->setSyncTarget(target); } +void CloudManager::showCloudDisabledIcon() { + _icon.show(CloudIcon::kDisabled, 3000); +} + ///// DownloadFolderRequest-related ///// bool CloudManager::startDownload(Common::String remotePath, Common::String localPath) const { @@ -453,4 +461,20 @@ Common::String CloudManager::getDownloadLocalDirectory() const { return ""; } +bool CloudManager::pollEvent(Common::Event &event) { + if (_icon.needsUpdate()) { + if (_icon.getShownType() != CloudIcon::kDisabled) { + if (isWorking()) { + _icon.show(CloudIcon::kSyncing); + } else { + _icon.show(CloudIcon::kNone); + } + } + + _icon.update(); + } + + return false; +} + } // End of namespace Cloud diff --git a/backends/cloud/cloudmanager.h b/backends/cloud/cloudmanager.h index 8a99d5bebb..f58ea8373a 100644 --- a/backends/cloud/cloudmanager.h +++ b/backends/cloud/cloudmanager.h @@ -24,9 +24,12 @@ #define CLOUD_CLOUDMANAGER_H #include "backends/cloud/storage.h" +#include "backends/cloud/cloudicon.h" + #include "common/array.h" #include "common/singleton.h" #include "common/str-array.h" +#include "common/events.h" namespace GUI { @@ -47,7 +50,7 @@ enum StorageID { kStorageTotal }; -class CloudManager : public Common::Singleton<CloudManager> { +class CloudManager : public Common::Singleton<CloudManager>, public Common::EventSource { static const char *const kStoragePrefix; struct StorageConfig { @@ -61,6 +64,8 @@ class CloudManager : public Common::Singleton<CloudManager> { Storage *_activeStorage; Common::Array<Storage *> _storagesToRemove; + CloudIcon _icon; + void loadStorage(); Common::String getStorageConfigName(uint32 index) const; @@ -71,6 +76,18 @@ class CloudManager : public Common::Singleton<CloudManager> { /** Calls the error callback with a special "no storage connected" message. */ void passNoStorageConnected(Networking::ErrorCallback errorCallback) const; + /** + * Common::EventSource interface + * + * The cloud manager registers itself as an event source even if does not + * actually produce events as a mean to be polled periodically by the GUI + * or engine code. + * + * The periodical polling is used to update the OSD icon indicating + * background sync activity. + */ + virtual bool pollEvent(Common::Event &event) override; + public: CloudManager(); virtual ~CloudManager(); @@ -233,6 +250,9 @@ public: /** Sets SavesSyncRequest's target to given CommandReceiver. */ void setSyncTarget(GUI::CommandReceiver *target) const; + /** Shows a "cloud disabled" icon for three seconds. */ + void showCloudDisabledIcon(); + ///// DownloadFolderRequest-related ///// /** Starts a folder download. */ diff --git a/backends/module.mk b/backends/module.mk index 9ee61ea388..10dde0be8f 100644 --- a/backends/module.mk +++ b/backends/module.mk @@ -21,6 +21,7 @@ MODULE_OBJS := \ ifdef USE_LIBCURL MODULE_OBJS += \ + cloud/cloudicon.o \ cloud/cloudmanager.o \ cloud/iso8601.o \ cloud/storage.o \ @@ -54,7 +55,6 @@ MODULE_OBJS += \ cloud/onedrive/onedriveuploadrequest.o \ networking/curl/connectionmanager.o \ networking/curl/networkreadstream.o \ - networking/curl/cloudicon.o \ networking/curl/curlrequest.o \ networking/curl/curljsonrequest.o \ networking/curl/request.o diff --git a/backends/networking/curl/connectionmanager.cpp b/backends/networking/curl/connectionmanager.cpp index 2b2c84fed3..e1761bddc6 100644 --- a/backends/networking/curl/connectionmanager.cpp +++ b/backends/networking/curl/connectionmanager.cpp @@ -78,11 +78,6 @@ Request *ConnectionManager::addRequest(Request *request, RequestCallback callbac return request; } -void ConnectionManager::showCloudDisabledIcon() { - _icon.showDisabled(); - startTimer(); -} - Common::String ConnectionManager::urlEncode(Common::String s) const { if (!_multi) return ""; @@ -137,7 +132,7 @@ void ConnectionManager::handle() { if (_frame % CURL_PERIOD == 0) processTransfers(); - if (_icon.draw() && _requests.empty() && !hasAddedRequests()) + if (_requests.empty() && !hasAddedRequests()) stopTimer(); _handleMutex.unlock(); } diff --git a/backends/networking/curl/connectionmanager.h b/backends/networking/curl/connectionmanager.h index fd90b637db..f6a9fcb36f 100644 --- a/backends/networking/curl/connectionmanager.h +++ b/backends/networking/curl/connectionmanager.h @@ -23,7 +23,6 @@ #ifndef BACKENDS_NETWORKING_CURL_CONNECTIONMANAGER_H #define BACKENDS_NETWORKING_CURL_CONNECTIONMANAGER_H -#include "backends/networking/curl/cloudicon.h" #include "backends/networking/curl/request.h" #include "common/str.h" #include "common/singleton.h" @@ -79,7 +78,6 @@ class ConnectionManager : public Common::Singleton<ConnectionManager> { bool _timerStarted; Common::Array<RequestWithCallback> _requests, _addedRequests; Common::Mutex _handleMutex, _addedRequestsMutex; - CloudIcon _icon; uint32 _frame; void startTimer(int interval = TIMER_INTERVAL); @@ -115,9 +113,6 @@ public: */ Request *addRequest(Request *request, RequestCallback callback = nullptr); - /** Shows a "cloud disabled" icon for a three seconds. */ - void showCloudDisabledIcon(); - /** Return URL-encoded version of given string. */ Common::String urlEncode(Common::String s) const; diff --git a/gui/saveload-dialog.cpp b/gui/saveload-dialog.cpp index cadd3e996f..4ae873229f 100644 --- a/gui/saveload-dialog.cpp +++ b/gui/saveload-dialog.cpp @@ -229,7 +229,7 @@ void SaveLoadChooserDialog::handleCommand(CommandSender *sender, uint32 cmd, uin void SaveLoadChooserDialog::runSaveSync(bool hasSavepathOverride) { if (!CloudMan.isSyncing()) { if (hasSavepathOverride) { - ConnMan.showCloudDisabledIcon(); + CloudMan.showCloudDisabledIcon(); } else { Cloud::SavesSyncRequest *request = CloudMan.syncSaves(); if (request) |