From 0fa274ad75a4a7e465c5acabe6fb28ee7127a41c Mon Sep 17 00:00:00 2001 From: arcan1s Date: Wed, 23 Sep 2015 03:53:42 +0300 Subject: [PATCH] * fix bug in ui * drop QUEUE_LIMIT build option (moved to runtime cfg) * apply concurrent updates for slots --- sources/CMakeLists.txt | 1 - .../package/contents/ui/widget.qml | 2 +- .../plugin/awdataaggregator.cpp | 68 ++++++++++++------- .../awesome-widget/plugin/awdataaggregator.h | 16 +++-- sources/awesome-widget/plugin/awkeys.cpp | 59 +++++++++------- sources/awesome-widget/plugin/awkeys.h | 2 +- 6 files changed, 93 insertions(+), 55 deletions(-) diff --git a/sources/CMakeLists.txt b/sources/CMakeLists.txt index 334c86f..f3ecb3f 100644 --- a/sources/CMakeLists.txt +++ b/sources/CMakeLists.txt @@ -29,7 +29,6 @@ option(BUILD_FUTURE "Build with the features which will be marked as stable late option(BUILD_PLASMOIDS "Build plasmoids" ON) option(BUILD_DEB_PACKAGE "Build deb package" OFF) option(BUILD_RPM_PACKAGE "Build rpm package" OFF) -set(QUEUE_LIMIT 0 CACHE INTEGER "Limit data queue to this value") # flags if(CMAKE_COMPILER_IS_GNUCXX) diff --git a/sources/awesome-widget/package/contents/ui/widget.qml b/sources/awesome-widget/package/contents/ui/widget.qml index 5cd2a61..aeb680b 100644 --- a/sources/awesome-widget/package/contents/ui/widget.qml +++ b/sources/awesome-widget/package/contents/ui/widget.qml @@ -320,7 +320,7 @@ Item { width: parent.width * 2 / 5 text: i18n("Preview") onClicked: { - awKeys.initKeys(textPattern.text) + awKeys.initKeys(textPattern.text, plasmoid.configuration.queueLimit) awKeys.needToBeUpdated() } } diff --git a/sources/awesome-widget/plugin/awdataaggregator.cpp b/sources/awesome-widget/plugin/awdataaggregator.cpp index c149754..d19c695 100644 --- a/sources/awesome-widget/plugin/awdataaggregator.cpp +++ b/sources/awesome-widget/plugin/awdataaggregator.cpp @@ -19,7 +19,11 @@ #include +#include #include +#include +#include +#include #include @@ -27,10 +31,13 @@ #include "awdebug.h" -AWDataAggregator::AWDataAggregator(QObject *parent) - : QObject(parent) +AWDataAggregator::AWDataAggregator(QObject *parent, QThreadPool *pThreadPool) + : QObject(parent), + threadPool(pThreadPool) { qCDebug(LOG_AW); + // required by signals + qRegisterMetaType>("QHash"); initScene(); @@ -154,27 +161,13 @@ void AWDataAggregator::dataUpdate(const QHash values) { qCDebug(LOG_AW); - // battery update requires info is AC online or not - setData(values[QString("ac")] == configuration[QString("acOnline")], - QString("batTooltip"), values[QString("bat")].toFloat()); - // usual case - setData(QString("cpuTooltip"), values[QString("cpu")].toFloat(), 90.0); - setData(QString("cpuclTooltip"), values[QString("cpucl")].toFloat()); - setData(QString("memTooltip"), values[QString("mem")].toFloat(), 90.0); - setData(QString("swapTooltip"), values[QString("swap")].toFloat(), 0.0); - setData(QString("downTooltip"), values[QString("downkb")].toFloat()); - setData(QString("upTooltip"), values[QString("upkb")].toFloat()); - // additional check for network device - [this](const QString value) { - checkValue(QString("netdev"), currentNetworkDevice, value); - currentNetworkDevice = value; - }(values[QString("netdev")]); - // additional check for GPU load - [this](const float value) { - checkValue(QString("gpu"), value, 90.0); - currentGPULoad = value; - }(values[QString("gpu")].toFloat()); - +#ifdef BUILD_FUTURE + QtConcurrent::run(threadPool, [this, values]() { + setData(values); + }); +#else /* BUILD_FUTURE */ + setData(values); +#endif /* BUILD_FUTURE */ emit(toolTipPainted(htmlImage(tooltipImage()))); } @@ -205,7 +198,7 @@ void AWDataAggregator::checkValue(const QString source, const QString current, qCDebug(LOG_AW) << "Current value" << current; qCDebug(LOG_AW) << "Received value" << received; - if ((m_enablePopup) && (current != received)) + if ((m_enablePopup) && (current != received) && (!received.isEmpty())) return AWActions::sendNotification(QString("event"), notificationText(source, received)); } @@ -262,6 +255,33 @@ QString AWDataAggregator::notificationText(const QString source, const QString v } +void AWDataAggregator::setData(const QHash< QString, QString > values) +{ + qCDebug(LOG_AW); + + // battery update requires info is AC online or not + setData(values[QString("ac")] == configuration[QString("acOnline")], + QString("batTooltip"), values[QString("bat")].toFloat()); + // usual case + setData(QString("cpuTooltip"), values[QString("cpu")].toFloat(), 90.0); + setData(QString("cpuclTooltip"), values[QString("cpucl")].toFloat()); + setData(QString("memTooltip"), values[QString("mem")].toFloat(), 90.0); + setData(QString("swapTooltip"), values[QString("swap")].toFloat(), 0.0); + setData(QString("downTooltip"), values[QString("downkb")].toFloat()); + setData(QString("upTooltip"), values[QString("upkb")].toFloat()); + // additional check for network device + [this](const QString value) { + checkValue(QString("netdev"), currentNetworkDevice, value); + currentNetworkDevice = value; + }(values[QString("netdev")]); + // additional check for GPU load + [this](const float value) { + checkValue(QString("gpu"), value, 90.0); + currentGPULoad = value; + }(values[QString("gpu")].toFloat()); +} + + void AWDataAggregator::setData(const QString source, float value, const float extremum) { qCDebug(LOG_AW); diff --git a/sources/awesome-widget/plugin/awdataaggregator.h b/sources/awesome-widget/plugin/awdataaggregator.h index c62651a..c7f9539 100644 --- a/sources/awesome-widget/plugin/awdataaggregator.h +++ b/sources/awesome-widget/plugin/awdataaggregator.h @@ -19,18 +19,21 @@ #ifndef AWTOOLTIP_H #define AWTOOLTIP_H -#include -#include #include -#include +#include +class QGraphicsScene; +class QGraphicsView; +class QPixmap; +class QThreadPool; + class AWDataAggregator : public QObject { Q_OBJECT public: - explicit AWDataAggregator(QObject *parent = nullptr); + explicit AWDataAggregator(QObject *parent = nullptr, QThreadPool *pThreadPool = nullptr); virtual ~AWDataAggregator(); QList getData(const QString key) const; QString htmlImage(const QPixmap source) const; @@ -41,7 +44,7 @@ signals: void updateData(const QHash values); void toolTipPainted(const QString image) const; -private slots: +public slots: void dataUpdate(const QHash values); private: @@ -53,6 +56,8 @@ private: void initScene(); QString notificationText(const QString source, const float value) const; QString notificationText(const QString source, const QString value) const; + // main method + void setData(const QHash values); void setData(const QString source, float value, const float extremum = -1.0); // different signature for battery device void setData(const bool dontInvert, const QString source, float value); @@ -65,6 +70,7 @@ private: QHash> data; bool m_enablePopup = false; QStringList requiredKeys; + QThreadPool *threadPool = nullptr; }; diff --git a/sources/awesome-widget/plugin/awkeys.cpp b/sources/awesome-widget/plugin/awkeys.cpp index 86524f6..89ee87a 100644 --- a/sources/awesome-widget/plugin/awkeys.cpp +++ b/sources/awesome-widget/plugin/awkeys.cpp @@ -26,7 +26,6 @@ #include #include #include -#include #include "awdebug.h" #include "awkeysaggregator.h" @@ -47,21 +46,19 @@ AWKeys::AWKeys(QObject *parent) // logging qSetMessagePattern(LOG_FORMAT); - aggregator = new AWKeysAggregator(this); - dataAggregator = new AWDataAggregator(this); - connect(this, SIGNAL(needToBeUpdated()), this, SLOT(dataUpdate())); - // transfer signal from AWDataAggregator object to QML ui - connect(dataAggregator, SIGNAL(toolTipPainted(const QString)), - this, SIGNAL(needToolTipToBeUpdated(const QString))); #ifdef BUILD_FUTURE - // queue limit. It may be configured by using QUEUE_LIMIT cmake limit flag. - // In other hand since I'm using global thread pool, it makes sense to limit - // queue by QThread::idealThreadCount() value - queueLimit = QUEUE_LIMIT == 0 ? QThread::idealThreadCount() : QUEUE_LIMIT; // thread pool + queueLimit = QThread::idealThreadCount(); threadPool = new QThreadPool(this); threadPool->setMaxThreadCount(queueLimit); #endif /* BUILD_FUTURE */ + + aggregator = new AWKeysAggregator(this); + dataAggregator = new AWDataAggregator(this, threadPool); + // transfer signal from AWDataAggregator object to QML ui + connect(dataAggregator, SIGNAL(toolTipPainted(const QString)), + this, SIGNAL(needToolTipToBeUpdated(const QString))); + connect(this, SIGNAL(needToBeUpdated()), this, SLOT(dataUpdate())); } @@ -69,13 +66,15 @@ AWKeys::~AWKeys() { qCDebug(LOG_AW); + // extensions if (graphicalItems != nullptr) delete graphicalItems; if (extQuotes != nullptr) delete extQuotes; if (extScripts != nullptr) delete extScripts; if (extUpgrade != nullptr) delete extUpgrade; if (extWeather != nullptr) delete extWeather; - delete threadPool; + // core + if (threadPool != nullptr) delete threadPool; delete aggregator; delete dataAggregator; } @@ -90,17 +89,23 @@ void AWKeys::initDataAggregator(const QVariantMap tooltipParams) } -void AWKeys::initKeys(const QString currentPattern) +void AWKeys::initKeys(const QString currentPattern, const int limit) { qCDebug(LOG_AW); qCDebug(LOG_AW) << "Pattern" << currentPattern; // init m_pattern = currentPattern; +#ifdef BUILD_FUTURE + // queue limit. It may be configured by using QUEUE_LIMIT cmake limit flag. + // In other hand since I'm using global thread pool, it makes sense to limit + // queue by QThread::idealThreadCount() value + queueLimit = limit == 0 ? QThread::idealThreadCount() : limit; + threadPool->setMaxThreadCount(queueLimit); +#endif /* BUILD_FUTURE */ // update network and hdd list addKeyToCache(QString("hdd")); addKeyToCache(QString("net")); - loadKeysFromCache(); } @@ -319,8 +324,12 @@ void AWKeys::dataUpdateReceived(const QString sourceName, const QVariantMap data qCDebug(LOG_AW) << "Source" << sourceName; qCDebug(LOG_AW) << "Data" << data; - // run concurrent data update + // we will update text even if queue limit is reached + if (sourceName == QString("update")) return emit(needToBeUpdated()); + #ifdef BUILD_FUTURE + // run concurrent data update + if ((lock = ((lock) && (queue > 0)))) return; QtConcurrent::run(threadPool, [this, sourceName, data]() { return setDataBySource(sourceName, data); }); @@ -393,8 +402,16 @@ void AWKeys::dataUpdate() { qCDebug(LOG_AW); +#ifdef BUILD_FUTURE + QFuture text = QtConcurrent::run(threadPool, [this]() { + calculateValues(); + return parsePattern(m_pattern); + }); +#else /* BUILD_FUTURE */ calculateValues(); - emit(needTextToBeUpdated(parsePattern(m_pattern))); + QString text = parsePattern(m_pattern); +#endif /* BUILD_FUTURE */ + emit(needTextToBeUpdated(text)); emit(dataAggregator->updateData(values)); } @@ -442,7 +459,7 @@ void AWKeys::reinitKeys() QStringList allKeys = dictKeys(); // not documented feature - place all available tags - m_pattern = m_pattern.replace(QString("$ALL"), [allKeys](){ + m_pattern = m_pattern.replace(QString("$ALL"), [allKeys]() { QStringList strings; foreach(QString tag, allKeys) strings.append(QString("%1: $%1").arg(tag)); @@ -661,8 +678,6 @@ void AWKeys::setDataBySource(const QString sourceName, const QVariantMap data) qCDebug(LOG_AW) << "Data" << data; #ifdef BUILD_FUTURE - // check if data stream is locked - if ((lock = ((lock) && (queue > 0)))) return; // drop if limits are reached if (++queue > queueLimit) { qCWarning(LOG_AW) << "Messages queue" << queue-- << "more than limits" << queueLimit; @@ -677,15 +692,13 @@ void AWKeys::setDataBySource(const QString sourceName, const QVariantMap data) tags = aggregator->registerSource(sourceName, data[QString("units")].toString()); // update data or drop source if there are no matches - if (sourceName == QString("update")) { - emit(needToBeUpdated()); - } else if (tags.isEmpty()) { + if (tags.isEmpty()) { qCDebug(LOG_AW) << "Source" << sourceName << "not found"; emit(dropSourceFromDataengine(sourceName)); } else { // HACK workaround for time values which are stored in the different path QVariant value = sourceName == QString("Local") ? data[QString("DateTime")] : data[QString("value")]; - std::for_each(tags.cbegin(), tags.cend(), [this, value](const QString tag){ + std::for_each(tags.cbegin(), tags.cend(), [this, value](const QString tag) { values[tag] = aggregator->formater(value, tag); }); } diff --git a/sources/awesome-widget/plugin/awkeys.h b/sources/awesome-widget/plugin/awkeys.h index 7127631..ff5d465 100644 --- a/sources/awesome-widget/plugin/awkeys.h +++ b/sources/awesome-widget/plugin/awkeys.h @@ -42,7 +42,7 @@ public: virtual ~AWKeys(); Q_INVOKABLE void initDataAggregator(const QVariantMap tooltipParams); - Q_INVOKABLE void initKeys(const QString currentPattern); + Q_INVOKABLE void initKeys(const QString currentPattern, const int limit); Q_INVOKABLE void setAggregatorProperty(const QString key, const QVariant value); Q_INVOKABLE void setWrapNewLines(const bool wrap = false); // keys