* fix bug in ui

* drop QUEUE_LIMIT build option (moved to runtime cfg)
* apply concurrent updates for slots
This commit is contained in:
arcan1s 2015-09-23 03:53:42 +03:00
parent 82e2bc23a1
commit 0fa274ad75
6 changed files with 93 additions and 55 deletions

View File

@ -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)

View File

@ -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()
}
}

View File

@ -19,7 +19,11 @@
#include <KI18n/KLocalizedString>
#include <QtConcurrent/QtConcurrent>
#include <QBuffer>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QPixmap>
#include <math.h>
@ -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<QString, QString>>("QHash<QString, QString>");
initScene();
@ -154,27 +161,13 @@ void AWDataAggregator::dataUpdate(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());
#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);

View File

@ -19,18 +19,21 @@
#ifndef AWTOOLTIP_H
#define AWTOOLTIP_H
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QObject>
#include <QPixmap>
#include <QVariant>
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<float> getData(const QString key) const;
QString htmlImage(const QPixmap source) const;
@ -41,7 +44,7 @@ signals:
void updateData(const QHash<QString, QString> values);
void toolTipPainted(const QString image) const;
private slots:
public slots:
void dataUpdate(const QHash<QString, QString> 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<QString, QString> 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<QString, QList<float>> data;
bool m_enablePopup = false;
QStringList requiredKeys;
QThreadPool *threadPool = nullptr;
};

View File

@ -26,7 +26,6 @@
#include <QSettings>
#include <QStandardPaths>
#include <QThread>
#include <QThreadPool>
#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<QString> 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);
});
}

View File

@ -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