summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJavier S. Pedro <maemo@javispedro.com>2012-08-15 15:48:47 +0200
committerJavier S. Pedro <maemo@javispedro.com>2012-08-15 15:48:47 +0200
commitc752ccafd8d826b3c0c9140e89ece09e90b34cb1 (patch)
tree87b99b668163d7ee57f61ffc7a68b2d1e5594521
parent6ceeb0c4b0e920740a2b65b01f76bb71f9d75db8 (diff)
downloadsowatch-c752ccafd8d826b3c0c9140e89ece09e90b34cb1.tar.gz
sowatch-c752ccafd8d826b3c0c9140e89ece09e90b34cb1.zip
avoid reloading watchlets when changing order only
-rw-r--r--libsowatch/watchserver.cpp12
-rw-r--r--libsowatch/watchserver.h1
-rw-r--r--sowatchd/watchhandler.cpp88
-rw-r--r--sowatchd/watchhandler.h4
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*>(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();