* work around a bug in Qt where the receiver count isn't updated until *after* another connect is made (disconnects don't count); this will work even after fixed upstream (and yes, it was reported)

* be a bit smarter with connect/disconnects
* return a pointer to the Relay directly in the private interface rather than a generic qobject

svn path=/trunk/KDE/kdebase/workspace/libs/plasma/; revision=791628
This commit is contained in:
Aaron J. Seigo 2008-03-30 01:58:10 +00:00
parent f9d6be9626
commit 0ea2371835
2 changed files with 24 additions and 18 deletions

View File

@ -115,7 +115,7 @@ void DataContainer::checkUsage()
void DataContainer::connectVisualization(QObject* visualization, uint updateInterval, Plasma::IntervalAlignment alignment) void DataContainer::connectVisualization(QObject* visualization, uint updateInterval, Plasma::IntervalAlignment alignment)
{ {
// kDebug() << "connecting visualization" << (void*)visualization << "at interval of" << updateInterval; //kDebug() << "connecting visualization" << visualization << "at interval of" << updateInterval;
QMap<QObject *, SignalRelay *>::iterator objIt = d->relayObjects.find(visualization); QMap<QObject *, SignalRelay *>::iterator objIt = d->relayObjects.find(visualization);
bool connected = objIt != d->relayObjects.end(); bool connected = objIt != d->relayObjects.end();
if (connected) { if (connected) {
@ -124,14 +124,17 @@ void DataContainer::connectVisualization(QObject* visualization, uint updateInte
SignalRelay *relay = objIt.value(); SignalRelay *relay = objIt.value();
if (relay) { if (relay) {
// connected to a relay // connected to a relay
disconnect(relay, SIGNAL(dataUpdated(QString,Plasma::DataEngine::Data)), //kDebug() << " already connected, but to a relay";
visualization, SLOT(dataUpdated(QString,Plasma::DataEngine::Data)));
if (relay->isUnused()) { if (relay->receiverCount() == 1) {
//kDebug() << " removing relay, as it is now unused";
d->relays.remove(relay->m_interval); d->relays.remove(relay->m_interval);
delete relay; delete relay;
} else {
disconnect(relay, SIGNAL(dataUpdated(QString,Plasma::DataEngine::Data)),
visualization, SLOT(dataUpdated(QString,Plasma::DataEngine::Data)));
//relay->isUnused();
} }
// kDebug() << " already connected, but to a relay";
} else if (updateInterval < 1) { } else if (updateInterval < 1) {
// the visualization was connected already, but not to a relay // the visualization was connected already, but not to a relay
// and it still doesn't want to connect to a relay, so we have // and it still doesn't want to connect to a relay, so we have
@ -142,23 +145,21 @@ void DataContainer::connectVisualization(QObject* visualization, uint updateInte
disconnect(this, SIGNAL(dataUpdated(QString,Plasma::DataEngine::Data)), disconnect(this, SIGNAL(dataUpdated(QString,Plasma::DataEngine::Data)),
visualization, SLOT(dataUpdated(QString,Plasma::DataEngine::Data))); visualization, SLOT(dataUpdated(QString,Plasma::DataEngine::Data)));
} }
} } else {
if (!connected) {
connect(visualization, SIGNAL(destroyed(QObject*)), connect(visualization, SIGNAL(destroyed(QObject*)),
this, SLOT(disconnectVisualization(QObject*)));//, Qt::QueuedConnection); this, SLOT(disconnectVisualization(QObject*)));//, Qt::QueuedConnection);
} }
d->relayObjects[visualization] = 0;
if (updateInterval < 1) { if (updateInterval < 1) {
// kDebug() << " connecting directly"; // kDebug() << " connecting directly";
d->relayObjects[visualization] = 0;
connect(this, SIGNAL(dataUpdated(QString,Plasma::DataEngine::Data)), connect(this, SIGNAL(dataUpdated(QString,Plasma::DataEngine::Data)),
visualization, SLOT(dataUpdated(QString,Plasma::DataEngine::Data))); visualization, SLOT(dataUpdated(QString,Plasma::DataEngine::Data)));
} else { } else {
// kDebug() << " connecting to a relay"; // kDebug() << " connecting to a relay";
connect(d->signalRelay(this, visualization, updateInterval, alignment), SignalRelay *relay = d->signalRelay(this, visualization, updateInterval, alignment);
SIGNAL(dataUpdated(QString,Plasma::DataEngine::Data)), connect(relay, SIGNAL(dataUpdated(QString,Plasma::DataEngine::Data)),
visualization, SLOT(dataUpdated(QString,Plasma::DataEngine::Data))); visualization, SLOT(dataUpdated(QString,Plasma::DataEngine::Data)));
} }
} }
@ -173,14 +174,14 @@ void DataContainer::disconnectVisualization(QObject* visualization)
visualization, SLOT(dataUpdated(QString,Plasma::DataEngine::Data))); visualization, SLOT(dataUpdated(QString,Plasma::DataEngine::Data)));
} else { } else {
SignalRelay *relay = objIt.value(); SignalRelay *relay = objIt.value();
disconnect(relay, SIGNAL(dataUpdated(QString,Plasma::DataEngine::Data)),
visualization, SLOT(dataUpdated(QString,Plasma::DataEngine::Data)));
if (relay->isUnused()) { if (relay->receiverCount() == 1) {
d->relays.remove(relay->m_interval); d->relays.remove(relay->m_interval);
delete relay; delete relay;
} else {
disconnect(relay, SIGNAL(dataUpdated(QString,Plasma::DataEngine::Data)),
visualization, SLOT(dataUpdated(QString,Plasma::DataEngine::Data)));
} }
} }
d->relayObjects.erase(objIt); d->relayObjects.erase(objIt);

View File

@ -35,8 +35,8 @@ public:
: dirty(false), cached(false) : dirty(false), cached(false)
{} {}
QObject* signalRelay(const DataContainer* dc, QObject *visualization, SignalRelay* signalRelay(const DataContainer* dc, QObject *visualization,
uint updateInterval, Plasma::IntervalAlignment align); uint updateInterval, Plasma::IntervalAlignment align);
DataEngine::Data data; DataEngine::Data data;
QMap<QObject *, SignalRelay *> relayObjects; QMap<QObject *, SignalRelay *> relayObjects;
@ -67,6 +67,11 @@ public:
} }
} }
int receiverCount() const
{
return receivers(SIGNAL(dataUpdated(QString,Plasma::DataEngine::Data)));
}
bool isUnused() bool isUnused()
{ {
return receivers(SIGNAL(dataUpdated(QString,Plasma::DataEngine::Data))) < 1; return receivers(SIGNAL(dataUpdated(QString,Plasma::DataEngine::Data))) < 1;
@ -153,7 +158,7 @@ protected:
} }
}; };
QObject* DataContainer::Private::signalRelay(const DataContainer* dc, QObject *visualization, uint updateInterval, Plasma::IntervalAlignment align) SignalRelay* DataContainer::Private::signalRelay(const DataContainer* dc, QObject *visualization, uint updateInterval, Plasma::IntervalAlignment align)
{ {
QMap<uint, SignalRelay *>::const_iterator relayIt = relays.find(updateInterval); QMap<uint, SignalRelay *>::const_iterator relayIt = relays.find(updateInterval);
SignalRelay *relay = 0; SignalRelay *relay = 0;