From 17ddc75c3a4ac2d05ee85a6456bf7d084b0ca525 Mon Sep 17 00:00:00 2001 From: Chani Armitage Date: Tue, 22 Jan 2008 17:03:34 +0000 Subject: [PATCH] fix bug where one signalrelay requests an update right after another and gets nothing svn path=/trunk/KDE/kdebase/workspace/libs/plasma/; revision=764821 --- datacontainer.cpp | 10 ++++++++++ datacontainer.h | 10 ++++++++++ datacontainer_p.h | 4 +++- dataengine.cpp | 6 ++++-- 4 files changed, 27 insertions(+), 3 deletions(-) diff --git a/datacontainer.cpp b/datacontainer.cpp index 709982a4c..830397a38 100644 --- a/datacontainer.cpp +++ b/datacontainer.cpp @@ -90,9 +90,19 @@ int DataContainer::timeSinceLastUpdate() const bool DataContainer::hasUpdates() const { + if (d->cached) { + //some signalrelay needs us to pretend we did an update + d->cached = false; + return true; + } return d->dirty; } +void DataContainer::setNeedsUpdate(bool update) +{ + d->cached = update; +} + void DataContainer::checkUsage() { if (d->relays.count() < 1 && diff --git a/datacontainer.h b/datacontainer.h index 55d161e89..8340daf56 100644 --- a/datacontainer.h +++ b/datacontainer.h @@ -91,6 +91,16 @@ class PLASMA_EXPORT DataContainer : public QObject **/ bool hasUpdates() const; + /** + * Indicates that the data should be treated as dirty the next time hasUpdates() is called. + * + * why? because if one SignalRelay times out just after another, the minimum update + * interval stops a real update from being done - but that relay still needs to be given + * data, because it won't have been in the queue and won't have gotten that last update. + * when it checks hasUpdates() we'll lie, and then everything will return to normal. + **/ + void setNeedsUpdate(bool update = true); + public Q_SLOTS: /** * Check if the DataContainer is still in use. diff --git a/datacontainer_p.h b/datacontainer_p.h index 64d8df775..818676ac0 100644 --- a/datacontainer_p.h +++ b/datacontainer_p.h @@ -32,7 +32,7 @@ class DataContainer::Private { public: Private() - : dirty(false) + : dirty(false), cached(false) {} QObject* signalRelay(const DataContainer* dc, QObject *visualization, @@ -43,6 +43,7 @@ public: QMap relays; QTime updateTs; bool dirty : 1; + bool cached : 1; }; class SignalRelay : public QObject @@ -157,6 +158,7 @@ QObject* DataContainer::Private::signalRelay(const DataContainer* dc, QObject *v QMap::const_iterator relayIt = relays.find(updateInterval); SignalRelay *relay = 0; + //FIXME what if we have two applets with the same interval and different alignment? if (relayIt == relays.end()) { relay = new SignalRelay(const_cast(dc), this, updateInterval, align); relays[updateInterval] = relay; diff --git a/dataengine.cpp b/dataengine.cpp index b68c44eaf..c1ff56ff2 100644 --- a/dataengine.cpp +++ b/dataengine.cpp @@ -252,9 +252,11 @@ void DataEngine::internalUpdateSource(DataContainer* source) if (d->minUpdateInterval > 0 && source->timeSinceLastUpdate() < d->minUpdateInterval) { // skip updating this source; it's been too soon - //TODO: should we queue an update in this case? return to this - // once we see the results in real world usage //kDebug() << "internal update source is delaying" << source->timeSinceLastUpdate() << d->minUpdateInterval; + //but fake an update so that the signalrelay that triggered this gets the data from the + //recent update. this way we don't have to worry about queuing - the relay will send a + //signal immediately and everyone else is undisturbed. + source->setNeedsUpdate(); return; }