From c752ccafd8d826b3c0c9140e89ece09e90b34cb1 Mon Sep 17 00:00:00 2001 From: "Javier S. Pedro" Date: Wed, 15 Aug 2012 15:48:47 +0200 Subject: avoid reloading watchlets when changing order only --- libsowatch/watchserver.cpp | 12 +++++++ libsowatch/watchserver.h | 1 + sowatchd/watchhandler.cpp | 88 +++++++++++++++++++++++++++++++++------------- sowatchd/watchhandler.h | 4 +++ 4 files changed, 80 insertions(+), 25 deletions(-) diff --git a/libsowatch/watchserver.cpp b/libsowatch/watchserver.cpp index 01af063..511c2c5 100644 --- a/libsowatch/watchserver.cpp +++ b/libsowatch/watchserver.cpp @@ -71,6 +71,18 @@ void WatchServer::insertWatchlet(int position, Watchlet *watchlet) _watchletIds[id] = watchlet; } +void WatchServer::moveWatchlet(const Watchlet *watchlet, int to) +{ + const QString id = watchlet->id(); + int index = _watchlets.indexOf(const_cast(watchlet)); + + Q_ASSERT(watchlet->_server == this); + Q_ASSERT(_watchletIds.contains(id)); + Q_ASSERT(index >= 0); + + _watchlets.move(index, to); +} + void WatchServer::removeWatchlet(const Watchlet *watchlet) { const QString id = watchlet->id(); diff --git a/libsowatch/watchserver.h b/libsowatch/watchserver.h index 91f9b4e..67fcb81 100644 --- a/libsowatch/watchserver.h +++ b/libsowatch/watchserver.h @@ -35,6 +35,7 @@ public: void addWatchlet(Watchlet *watchlet); void insertWatchlet(int position, Watchlet *watchlet); + void moveWatchlet(const Watchlet *watchlet, int to); void removeWatchlet(const Watchlet *watchlet); void addProvider(NotificationProvider *provider); diff --git a/sowatchd/watchhandler.cpp b/sowatchd/watchhandler.cpp index b04c90b..4cd86d3 100644 --- a/sowatchd/watchhandler.cpp +++ b/sowatchd/watchhandler.cpp @@ -73,42 +73,80 @@ QString WatchHandler::status() const } } -void WatchHandler::updateWatchlets() +Watchlet* WatchHandler::createWatchlet(const QString &id) { Registry *registry = Registry::registry(); + WatchletPluginInterface *plugin = registry->getWatchletPlugin(id); + if (!plugin) { + qWarning() << "Unknown watchlet" << id; + return 0; + } - if (!_server) return; + ConfigKey *subconfig = _config->getSubkey(id); + Watchlet* watchlet = plugin->getWatchlet(id, subconfig, _server); + delete subconfig; - QStringList newWatchlets = _config->value("watchlets").toStringList(); - QStringList curWatchlets = _watchlet_order; + return watchlet; +} - if (newWatchlets == curWatchlets) return; // Nothing to do +void WatchHandler::deleteWatchletAt(int index) +{ + const QString id = _watchlet_order[index]; + Watchlet *watchlet = _watchlets[id]; - // TODO: Something better than removing all and readding - foreach (const QString& s, curWatchlets) { - Watchlet* watchlet = _watchlets[s]; - _server->removeWatchlet(watchlet); - delete watchlet; - } + _server->removeWatchlet(watchlet); + _watchlet_order.removeAt(index); + _watchlets.remove(id); - _watchlet_order.clear(); - _watchlets.clear(); + delete watchlet; +} - foreach (const QString& s, newWatchlets) { - WatchletPluginInterface *plugin = registry->getWatchletPlugin(s); - if (!plugin) { - qWarning() << "Unknown watchlet" << s; - continue; +void WatchHandler::updateWatchlets() +{ + if (!_server) return; + + QStringList newWatchlets = _config->value("watchlets").toStringList(); + + // Try to do one operation at the time + // (e.g. move a watchlet or add/remove it). + // Find the first difference + int i; + for (i = 0; i < newWatchlets.size(); i++) { + // Precondition: newWatchlets and curWatchlets are equal in range 0..i-1 + if (i >= _watchlet_order.size()) { + // We need to add this watchlet + const QString id = newWatchlets[i]; + Watchlet *watchlet = createWatchlet(id); + _watchlet_order << id; + _watchlets[id] = watchlet; + _server->addWatchlet(watchlet); + } else if (newWatchlets[i] != _watchlet_order[i]) { + // Let's find out if this watchlet has been moved, or removed. + const QString id = _watchlet_order[i]; + int j; + for (j = i; j < newWatchlets.size(); j++) { + if (id == newWatchlets[j]) { + break; // Found + } + } + if (j == _watchlet_order.size()) { + // It was not found, so it has been removed + deleteWatchletAt(i); + } else { + // It has been found at index j, it needs to moved. + _watchlet_order.move(i, j); + _server->moveWatchlet(_watchlets[id], j); + } } - ConfigKey *subconfig = _config->getSubkey(s); - Watchlet* watchlet = plugin->getWatchlet(s, subconfig, _server); - _watchlet_order << s; - _watchlets[s] = watchlet; - _server->addWatchlet(watchlet); - delete subconfig; } + while (i < _watchlet_order.size()) { + // These watchlets are to be unloaded + deleteWatchletAt(i); + } + + Q_ASSERT(newWatchlets == _watchlet_order); - qDebug() << "Watchlets reloaded: " << _watchlets.keys(); + qDebug() << "New watchlet order: " << _watchlet_order; } void WatchHandler::updateProviders() diff --git a/sowatchd/watchhandler.h b/sowatchd/watchhandler.h index 39c1d17..83f0a67 100644 --- a/sowatchd/watchhandler.h +++ b/sowatchd/watchhandler.h @@ -22,6 +22,10 @@ public: signals: void statusChanged(); +private: + Watchlet* createWatchlet(const QString& id); + void deleteWatchletAt(int index); + private slots: void updateWatchlets(); void updateProviders(); -- cgit v1.2.3