plugin/service: ref by object

Use QSet and auto unref on sender destruction
This commit is contained in:
2 * r + 2 * t 2025-09-22 22:08:46 +10:00
parent 1991b4176c
commit f9fa839013
7 changed files with 20 additions and 45 deletions

View file

@ -21,7 +21,7 @@ void AudioProcessor::init() {
}
void AudioProcessor::start() {
QMetaObject::invokeMethod(&AudioCollector::instance(), &AudioCollector::ref);
QMetaObject::invokeMethod(&AudioCollector::instance(), &AudioCollector::ref, Qt::QueuedConnection, this);
if (m_timer) {
m_timer->start();
}
@ -31,7 +31,7 @@ void AudioProcessor::stop() {
if (m_timer) {
m_timer->stop();
}
QMetaObject::invokeMethod(&AudioCollector::instance(), &AudioCollector::unref);
QMetaObject::invokeMethod(&AudioCollector::instance(), &AudioCollector::unref, Qt::QueuedConnection, this);
}
AudioProvider::AudioProvider(QObject* parent)

View file

@ -124,7 +124,8 @@ void CavaProvider::setBars(int bars) {
emit barsChanged();
emit valuesChanged();
QMetaObject::invokeMethod(m_processor, "setBars", Qt::QueuedConnection, Q_ARG(int, bars));
QMetaObject::invokeMethod(
static_cast<CavaProcessor*>(m_processor), &CavaProcessor::setBars, Qt::QueuedConnection, bars);
}
QVector<double> CavaProvider::values() const {

View file

@ -13,6 +13,8 @@ public:
explicit CavaProcessor(QObject* parent = nullptr);
~CavaProcessor();
void setBars(int bars);
signals:
void valuesChanged(QVector<double> values);
@ -27,8 +29,6 @@ private:
int m_bars;
QVector<double> m_values;
Q_INVOKABLE void setBars(int bars);
void reload();
void initCava();
void cleanup();

View file

@ -6,31 +6,19 @@
namespace caelestia {
Service::Service(QObject* parent)
: QObject(parent)
, m_refCount(0) {}
: QObject(parent) {}
int Service::refCount() const {
return m_refCount;
}
void Service::ref() {
if (m_refCount == 0) {
void Service::ref(QObject* sender) {
if (m_refs.isEmpty()) {
start();
}
m_refCount++;
emit refCountChanged();
QObject::connect(sender, &QObject::destroyed, this, &Service::unref);
m_refs << sender;
}
void Service::unref() {
if (m_refCount == 0) {
return;
}
m_refCount--;
emit refCountChanged();
if (m_refCount == 0) {
void Service::unref(QObject* sender) {
if (m_refs.remove(sender) && m_refs.isEmpty()) {
stop();
}
}

View file

@ -1,28 +1,21 @@
#pragma once
#include <qmutex.h>
#include <qobject.h>
#include <qset.h>
namespace caelestia {
class Service : public QObject {
Q_OBJECT
Q_PROPERTY(int refCount READ refCount NOTIFY refCountChanged)
public:
explicit Service(QObject* parent = nullptr);
[[nodiscard]] int refCount() const;
void ref();
void unref();
signals:
void refCountChanged();
void ref(QObject* sender);
void unref(QObject* sender);
private:
int m_refCount;
QSet<QObject*> m_refs;
virtual void start() = 0;
virtual void stop() = 0;

View file

@ -8,13 +8,7 @@ ServiceRef::ServiceRef(Service* service, QObject* parent)
: QObject(parent)
, m_service(service) {
if (m_service) {
m_service->ref();
}
}
ServiceRef::~ServiceRef() {
if (m_service) {
m_service->unref();
m_service->ref(this);
}
}
@ -28,14 +22,14 @@ void ServiceRef::setService(Service* service) {
}
if (m_service) {
m_service->unref();
m_service->unref(this);
}
m_service = service;
emit serviceChanged();
if (m_service) {
m_service->ref();
m_service->ref(this);
}
}

View file

@ -14,7 +14,6 @@ class ServiceRef : public QObject {
public:
explicit ServiceRef(Service* service = nullptr, QObject* parent = nullptr);
~ServiceRef();
[[nodiscard]] Service* service() const;
void setService(Service* service);