Optimize DataSource
- Use QQmlParserStatus to provide event compression for setupDate() method - Re-introduce interval alignment - Cache sources and emit change signal only when it has actually changed Changelog: DataSource can now align polling to full minutes REVIEW: 122470
This commit is contained in:
parent
073b83b440
commit
5cfe737618
@ -26,7 +26,9 @@ namespace Plasma
|
||||
{
|
||||
DataSource::DataSource(QObject *parent)
|
||||
: QObject(parent),
|
||||
m_ready(false),
|
||||
m_interval(0),
|
||||
m_intervalAlignment(Plasma::Types::NoAlignment),
|
||||
m_dataEngine(0),
|
||||
m_dataEngineConsumer(0)
|
||||
{
|
||||
@ -35,6 +37,17 @@ DataSource::DataSource(QObject *parent)
|
||||
setObjectName("DataSource");
|
||||
}
|
||||
|
||||
void DataSource::classBegin()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void DataSource::componentComplete()
|
||||
{
|
||||
m_ready = true;
|
||||
setupData();
|
||||
}
|
||||
|
||||
void DataSource::setConnectedSources(const QStringList &sources)
|
||||
{
|
||||
bool sourcesChanged = false;
|
||||
@ -43,7 +56,7 @@ void DataSource::setConnectedSources(const QStringList &sources)
|
||||
sourcesChanged = true;
|
||||
if (m_dataEngine) {
|
||||
m_connectedSources.append(source);
|
||||
m_dataEngine->connectSource(source, this, m_interval);
|
||||
m_dataEngine->connectSource(source, this, m_interval, m_intervalAlignment);
|
||||
emit sourceConnected(source);
|
||||
}
|
||||
}
|
||||
@ -73,7 +86,48 @@ void DataSource::setEngine(const QString &e)
|
||||
}
|
||||
|
||||
m_engine = e;
|
||||
setupData();
|
||||
|
||||
if (m_engine.isEmpty()) {
|
||||
emit engineChanged();
|
||||
return;
|
||||
}
|
||||
|
||||
m_dataEngineConsumer = new Plasma::DataEngineConsumer();
|
||||
Plasma::DataEngine *engine = dataEngine(m_engine);
|
||||
if (!engine) {
|
||||
qWarning() << "DataEngine" << m_engine << "not found";
|
||||
emit engineChanged();
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_dataEngine) {
|
||||
m_dataEngine->disconnect(this);
|
||||
// Deleting the consumer triggers the reference counting
|
||||
delete m_dataEngineConsumer;
|
||||
m_dataEngineConsumer = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* It is due little explanation why this is a queued connection:
|
||||
* If sourceAdded arrives immediately, in the case we have a datamodel
|
||||
* with items at source level we connect too soon (before setData for
|
||||
* all roles is done), having a dataupdated in the datamodel with only
|
||||
* the first role, killing off the other roles.
|
||||
* Besides causing a model reset more, unfortunately setRoleNames can be done a single time, so is not possible adding new roles after the
|
||||
* first setRoleNames() is called.
|
||||
* This fixes engines that have 1 item per source like the
|
||||
* recommendations engine.
|
||||
*/
|
||||
m_dataEngine = engine;
|
||||
connect(m_dataEngine, SIGNAL(sourceAdded(QString)), this, SLOT(updateSources()), Qt::QueuedConnection);
|
||||
connect(m_dataEngine, SIGNAL(sourceRemoved(QString)), this, SLOT(updateSources()));
|
||||
|
||||
connect(m_dataEngine, SIGNAL(sourceAdded(QString)), this, SIGNAL(sourceAdded(QString)), Qt::QueuedConnection);
|
||||
connect(m_dataEngine, SIGNAL(sourceRemoved(QString)), this, SLOT(removeSource(QString)));
|
||||
connect(m_dataEngine, SIGNAL(sourceRemoved(QString)), this, SIGNAL(sourceRemoved(QString)));
|
||||
|
||||
updateSources();
|
||||
|
||||
emit engineChanged();
|
||||
}
|
||||
|
||||
@ -88,56 +142,30 @@ void DataSource::setInterval(const int interval)
|
||||
emit intervalChanged();
|
||||
}
|
||||
|
||||
//TODO: event compression for this
|
||||
void DataSource::setIntervalAlignment(Plasma::Types::IntervalAlignment intervalAlignment)
|
||||
{
|
||||
if (intervalAlignment == m_intervalAlignment) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_intervalAlignment = intervalAlignment;
|
||||
setupData();
|
||||
emit intervalAlignmentChanged();
|
||||
}
|
||||
|
||||
void DataSource::setupData()
|
||||
{
|
||||
if (!m_ready) {
|
||||
return;
|
||||
}
|
||||
|
||||
// qDebug() << " loading engine " << m_engine;
|
||||
//FIXME: should all services be deleted just because we're changing the interval, etc?
|
||||
qDeleteAll(m_services);
|
||||
m_services.clear();
|
||||
|
||||
if (m_engine.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_dataEngineConsumer = new Plasma::DataEngineConsumer();
|
||||
Plasma::DataEngine *engine = dataEngine(m_engine);
|
||||
if (!engine) {
|
||||
qWarning() << "DataEngine" << m_engine << "not found";
|
||||
return;
|
||||
}
|
||||
// qDebug() << "Engine loaed .. . " << m_engine << m_dataEngineConsumer;
|
||||
|
||||
if (engine != m_dataEngine) {
|
||||
if (m_dataEngine) {
|
||||
m_dataEngine->disconnect(this);
|
||||
// Deleting the consumer triggers the reference counting
|
||||
delete m_dataEngineConsumer;
|
||||
m_dataEngineConsumer = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* It is due little explanation why this is a queued connection:
|
||||
* If sourceAdded arrives immediately, in the case we have a datamodel
|
||||
* with items at source level we connect too soon (before setData for
|
||||
* all roles is done), having a dataupdated in the datamodel with only
|
||||
* the first role, killing off the other roles.
|
||||
* Besides causing a model reset more, unfortunately setRoleNames can be done a single time, so is not possible adding new roles after the
|
||||
* first setRoleNames() is called.
|
||||
* This fixes engines that have 1 item per source like the
|
||||
* recommendations engine.
|
||||
*/
|
||||
m_dataEngine = engine;
|
||||
connect(m_dataEngine, SIGNAL(sourceAdded(QString)), this, SIGNAL(sourcesChanged()), Qt::QueuedConnection);
|
||||
connect(m_dataEngine, SIGNAL(sourceRemoved(QString)), this, SIGNAL(sourcesChanged()));
|
||||
|
||||
connect(m_dataEngine, SIGNAL(sourceAdded(QString)), this, SIGNAL(sourceAdded(QString)), Qt::QueuedConnection);
|
||||
connect(m_dataEngine, SIGNAL(sourceRemoved(QString)), this, SLOT(removeSource(QString)));
|
||||
connect(m_dataEngine, SIGNAL(sourceRemoved(QString)), this, SIGNAL(sourceRemoved(QString)));
|
||||
}
|
||||
|
||||
foreach (const QString &source, m_connectedSources) {
|
||||
m_dataEngine->connectSource(source, this, m_interval);
|
||||
m_dataEngine->connectSource(source, this, m_interval, m_intervalAlignment);
|
||||
emit sourceConnected(source);
|
||||
}
|
||||
}
|
||||
@ -210,7 +238,7 @@ void DataSource::connectSource(const QString &source)
|
||||
|
||||
m_connectedSources.append(source);
|
||||
if (m_dataEngine) {
|
||||
m_dataEngine->connectSource(source, this, m_interval);
|
||||
m_dataEngine->connectSource(source, this, m_interval, m_intervalAlignment);
|
||||
emit sourceConnected(source);
|
||||
emit connectedSourcesChanged();
|
||||
}
|
||||
@ -226,4 +254,17 @@ void DataSource::disconnectSource(const QString &source)
|
||||
}
|
||||
}
|
||||
|
||||
void DataSource::updateSources()
|
||||
{
|
||||
QStringList sources;
|
||||
if (m_dataEngine) {
|
||||
sources = m_dataEngine->sources();
|
||||
}
|
||||
|
||||
if (sources != m_sources) {
|
||||
m_sources = sources;
|
||||
emit sourcesChanged();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include <QObject>
|
||||
#include <QtQml>
|
||||
#include <QQmlPropertyMap>
|
||||
#include <QQmlParserStatus>
|
||||
|
||||
#include <Plasma/DataEngineConsumer>
|
||||
#include <Plasma/DataEngine>
|
||||
@ -40,9 +41,11 @@ class DataEngine;
|
||||
* @class DataSource
|
||||
* @short Provides data from a range of plugins
|
||||
*/
|
||||
class DataSource : public QObject, DataEngineConsumer
|
||||
class DataSource : public QObject, public QQmlParserStatus, DataEngineConsumer
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(QQmlParserStatus)
|
||||
|
||||
public:
|
||||
enum Change {
|
||||
NoChange = 0,
|
||||
@ -54,6 +57,10 @@ public:
|
||||
typedef QMap<QString, QVariant> Data;
|
||||
|
||||
DataSource(QObject *parent = 0);
|
||||
|
||||
void classBegin();
|
||||
void componentComplete();
|
||||
|
||||
/**
|
||||
* true if the connection to the Plasma DataEngine is valid
|
||||
*/
|
||||
@ -73,6 +80,16 @@ public:
|
||||
}
|
||||
void setInterval(const int interval);
|
||||
|
||||
/**
|
||||
* The interval to align polling to
|
||||
*/
|
||||
Q_PROPERTY(Plasma::Types::IntervalAlignment intervalAlignment READ intervalAlignment WRITE setIntervalAlignment NOTIFY intervalAlignmentChanged)
|
||||
Plasma::Types::IntervalAlignment intervalAlignment() const
|
||||
{
|
||||
return m_intervalAlignment;
|
||||
}
|
||||
void setIntervalAlignment(Plasma::Types::IntervalAlignment intervalAlignment);
|
||||
|
||||
/**
|
||||
* Plugin name of the Plasma DataEngine
|
||||
*/
|
||||
@ -100,11 +117,7 @@ public:
|
||||
Q_PROPERTY(QStringList sources READ sources NOTIFY sourcesChanged)
|
||||
QStringList sources() const
|
||||
{
|
||||
if (m_dataEngine) {
|
||||
return m_dataEngine->sources();
|
||||
} else {
|
||||
return QStringList();
|
||||
}
|
||||
return m_sources;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -151,6 +164,7 @@ public Q_SLOTS:
|
||||
protected Q_SLOTS:
|
||||
void removeSource(const QString &source);
|
||||
void setupData();
|
||||
void updateSources();
|
||||
|
||||
Q_SIGNALS:
|
||||
void newData(const QString &sourceName, const QVariantMap &data);
|
||||
@ -159,19 +173,23 @@ Q_SIGNALS:
|
||||
void sourceConnected(const QString &source);
|
||||
void sourceDisconnected(const QString &source);
|
||||
void intervalChanged();
|
||||
void intervalAlignmentChanged();
|
||||
void engineChanged();
|
||||
void dataChanged();
|
||||
void connectedSourcesChanged();
|
||||
void sourcesChanged();
|
||||
|
||||
private:
|
||||
bool m_ready;
|
||||
QString m_id;
|
||||
int m_interval;
|
||||
Plasma::Types::IntervalAlignment m_intervalAlignment;
|
||||
QString m_engine;
|
||||
QQmlPropertyMap *m_data;
|
||||
QQmlPropertyMap *m_models;
|
||||
Plasma::DataEngine *m_dataEngine;
|
||||
Plasma::DataEngineConsumer *m_dataEngineConsumer;
|
||||
QStringList m_sources;
|
||||
QStringList m_connectedSources;
|
||||
QStringList m_oldSources;
|
||||
QStringList m_newSources;
|
||||
|
Loading…
Reference in New Issue
Block a user