diff --git a/sources/awesome-widget/plugin/awcustomkeyshelper.h b/sources/awesome-widget/plugin/awcustomkeyshelper.h index b555605..53ceeed 100644 --- a/sources/awesome-widget/plugin/awcustomkeyshelper.h +++ b/sources/awesome-widget/plugin/awcustomkeyshelper.h @@ -34,7 +34,7 @@ public: [[nodiscard]] QStringList sources() const; [[nodiscard]] QStringList refinedSources() const; // configuration related - void editPairs() override{}; + void editPairs() override {}; QStringList leftKeys() override; QStringList rightKeys() override; }; diff --git a/sources/awesome-widget/plugin/awdataengineaggregator.cpp b/sources/awesome-widget/plugin/awdataengineaggregator.cpp index 9189cdc..5665f07 100644 --- a/sources/awesome-widget/plugin/awdataengineaggregator.cpp +++ b/sources/awesome-widget/plugin/awdataengineaggregator.cpp @@ -95,13 +95,55 @@ void AWDataEngineAggregator::loadSources() } +void AWDataEngineAggregator::registerClient(QObject *_client) +{ + qCDebug(LOG_AW) << "Register client" << _client; + + // register new client + m_clients.insert(_client); + // (re)connect sources for new client + connectSources(); +} + + +void AWDataEngineAggregator::unregisterClient(QObject *_client) +{ + qCDebug(LOG_AW) << "Unregister client" << _client; + + m_clients.remove(_client); + for (auto [source, clients] : m_droppedBy.asKeyValueRange()) { + if (clients.remove(_client)) { + if (isSubscriptionUnused(source)) + dropSource(source); + } + } +} + + void AWDataEngineAggregator::dropSource(const QString &_source) { qCDebug(LOG_AW) << "Disconnect sensor" << _source; - m_interface->unsubscribe({_source}).waitForFinished(); - m_interface->unsubscribe({_source}).waitForFinished(); - m_subscribed.remove(_source); + if (m_subscribed.remove(_source)) + m_interface->unsubscribe({_source}).waitForFinished(); +} + + +void AWDataEngineAggregator::dropSourceForClient(QObject *_client, const QString &_source) +{ + qCDebug(LOG_AW) << "Client" << _client << "dropping source" << _source; + + m_droppedBy[_source].insert(_client); + + // only unsubscribe if ALL clients have dropped this source + if (isSubscriptionUnused(_source)) + dropSource(_source); +} + + +bool AWDataEngineAggregator::isSubscriptionUnused(const QString &_source) const +{ + return m_droppedBy.value(_source).size() >= m_clients.size() && !m_clients.isEmpty(); } diff --git a/sources/awesome-widget/plugin/awdataengineaggregator.h b/sources/awesome-widget/plugin/awdataengineaggregator.h index a528302..0a0eeb9 100644 --- a/sources/awesome-widget/plugin/awdataengineaggregator.h +++ b/sources/awesome-widget/plugin/awdataengineaggregator.h @@ -23,6 +23,7 @@ #include #include +#include namespace KSysGuard::SystemStats { @@ -34,12 +35,26 @@ class AWDataEngineAggregator : public QObject Q_OBJECT public: - explicit AWDataEngineAggregator(QObject *_parent = nullptr); ~AWDataEngineAggregator() override; + + AWDataEngineAggregator(AWDataEngineAggregator &) = delete; + void operator=(const AWDataEngineAggregator &) = delete; + + [[nodiscard]] static AWDataEngineAggregator *instance(QObject *_client) + { + static auto instance = loadInstance(); + instance->registerClient(_client); + return instance.get(); + }; + void connectSources(); void disconnectSources(); + void dropSourceForClient(QObject *_client, const QString &_source); + [[nodiscard]] inline bool isSubscriptionUnused(const QString &_source) const; [[nodiscard]] static bool isValidSensor(const KSysGuard::SensorInfo &_sensor); void loadSources(); + void registerClient(QObject *_client); + void unregisterClient(QObject *_client); signals: void dataUpdated(const QHash &_sensors, const KSysGuard::SensorDataList &_data); @@ -52,7 +67,18 @@ public slots: void updateData(const KSysGuard::SensorDataList &_data); void updateSensors(const QHash &_sensors); +protected: + explicit AWDataEngineAggregator(QObject *_parent = nullptr); + + [[nodiscard]] static std::unique_ptr loadInstance() + { + auto instance = new AWDataEngineAggregator(); + return std::unique_ptr(instance); + }; + private: + QSet m_clients; + QHash> m_droppedBy; KSysGuard::SystemStats::DBusInterface *m_interface = nullptr; QHash m_sensors; QSet m_subscribed; diff --git a/sources/awesome-widget/plugin/awkeys.cpp b/sources/awesome-widget/plugin/awkeys.cpp index 4b11db2..1729666 100644 --- a/sources/awesome-widget/plugin/awkeys.cpp +++ b/sources/awesome-widget/plugin/awkeys.cpp @@ -43,7 +43,7 @@ AWKeys::AWKeys(QObject *_parent) m_aggregator = new AWKeysAggregator(this); m_dataAggregator = new AWDataAggregator(this); - m_dataEngineAggregator = new AWDataEngineAggregator(this); + m_dataEngineAggregator = AWDataEngineAggregator::instance(this); m_keyOperator = new AWKeyOperations(this); m_timer = new QTimer(this); @@ -59,7 +59,8 @@ AWKeys::AWKeys(QObject *_parent) connect(m_dataAggregator, &AWDataAggregator::toolTipPainted, [this](const QString &_tooltip) { emit(needToolTipToBeUpdated(_tooltip)); }); - connect(this, &AWKeys::dropSourceFromDataengine, m_dataEngineAggregator, &AWDataEngineAggregator::dropSource); + connect(this, &AWKeys::dropSourceFromDataengine, this, + [this](const QString &_source) { m_dataEngineAggregator->dropSourceForClient(this, _source); }); connect(m_dataEngineAggregator, &AWDataEngineAggregator::dataUpdated, this, &AWKeys::dataUpdated); // transfer signal from dataengine to update source list connect(m_dataEngineAggregator, &AWDataEngineAggregator::deviceAdded, m_keyOperator, &AWKeyOperations::addDevice); @@ -70,6 +71,8 @@ AWKeys::~AWKeys() { qCDebug(LOG_AW) << __PRETTY_FUNCTION__; + m_dataEngineAggregator->unregisterClient(this); + m_timer->stop(); // delete dbus session auto id = reinterpret_cast(this); @@ -294,8 +297,8 @@ QString AWKeys::parsePattern(QString _pattern) const // bars for (auto &bar : m_foundBars) { auto item = m_keyOperator->giByKey(bar); - auto image = item->isCustom() ? item->image( - AWPatternFunctions::expandLambdas(item->bar(), m_aggregator, m_values, item->usedKeys())) + auto image = item->isCustom() ? item->image(AWPatternFunctions::expandLambdas(item->bar(), m_aggregator, + m_values, item->usedKeys())) : item->image(m_values[item->bar()]); _pattern.replace(QString("$%1").arg(bar), image); } diff --git a/sources/awesome-widget/plugin/formatters/awpluginformatter.h b/sources/awesome-widget/plugin/formatters/awpluginformatter.h index 57b4789..be5c8c0 100644 --- a/sources/awesome-widget/plugin/formatters/awpluginformatter.h +++ b/sources/awesome-widget/plugin/formatters/awpluginformatter.h @@ -32,7 +32,7 @@ public: [[nodiscard]] virtual QString format(const QVariant &_value, const QString &_key, const AWPluginFormatSettings &_settings) const = 0; - virtual void load(){}; + virtual void load() {}; }; diff --git a/sources/awtranslation.h b/sources/awtranslation.h index 583be19..de5bf09 100644 --- a/sources/awtranslation.h +++ b/sources/awtranslation.h @@ -22,4 +22,3 @@ #ifndef ui_i18n #define ui_i18n(text, parent) i18n(text) #endif /* ui_i18n */ -