Fix async crashes like getting display name from Ui.
This commit is contained in:
parent
5e3a2d07aa
commit
05b7251797
3 changed files with 34 additions and 17 deletions
|
|
@ -36,6 +36,7 @@ public:
|
||||||
QVariant getValue() const;
|
QVariant getValue() const;
|
||||||
void onSetValue(QVariant value);
|
void onSetValue(QVariant value);
|
||||||
void setDefaultValue(QVariant value); // Don't send signal
|
void setDefaultValue(QVariant value); // Don't send signal
|
||||||
|
bool mDeleted = false;
|
||||||
signals:
|
signals:
|
||||||
void requestValue();
|
void requestValue();
|
||||||
void setValue(QVariant value);
|
void setValue(QVariant value);
|
||||||
|
|
|
||||||
|
|
@ -40,24 +40,35 @@ VariantObject::VariantObject(QString name, QVariant defaultValue, QObject *paren
|
||||||
mConnection = QSharedPointer<SafeConnection<SafeObject, SafeObject>>(
|
mConnection = QSharedPointer<SafeConnection<SafeObject, SafeObject>>(
|
||||||
new SafeConnection<SafeObject, SafeObject>(mCoreObject, mModelObject), &QObject::deleteLater);
|
new SafeConnection<SafeObject, SafeObject>(mCoreObject, mModelObject), &QObject::deleteLater);
|
||||||
|
|
||||||
mConnection->makeConnectToCore(&SafeObject::setValue, [this, d = mName](QVariant value) {
|
// Note: do not use member because 'this' is managed by GUI and can be deleted. Objects scope should have the same
|
||||||
mConnection->invokeToModel([this, value, d]() {
|
// as connections so it should be fine to use the object directly.
|
||||||
if (mModelObject) mModelObject->onSetValue(value);
|
mConnection->makeConnectToCore(&SafeObject::setValue,
|
||||||
});
|
[this, d = mName, modelObject = mModelObject.get()](QVariant value) {
|
||||||
});
|
if (modelObject && !modelObject->mDeleted)
|
||||||
mConnection->makeConnectToModel(&SafeObject::setValue, [this, d = mName, coreObject = mCoreObject](QVariant value) {
|
mConnection->invokeToModel([this, value, d, modelObject]() {
|
||||||
// Note: do not use member because 'this' is managed by GUI and can be deleted.
|
if (modelObject && !modelObject->mDeleted)
|
||||||
mConnection->invokeToCore([this, d, coreObject, value]() {
|
modelObject->onSetValue(value);
|
||||||
if (coreObject) coreObject->onSetValue(value);
|
});
|
||||||
});
|
});
|
||||||
});
|
mConnection->makeConnectToModel(&SafeObject::setValue,
|
||||||
mConnection->makeConnectToModel(&SafeObject::valueChanged, [this](QVariant value) {
|
[this, d = mName, coreObject = mCoreObject.get()](QVariant value) {
|
||||||
mConnection->invokeToCore([this, value]() { mCoreObject->valueChanged(value); });
|
if (coreObject && !coreObject->mDeleted)
|
||||||
|
mConnection->invokeToCore([this, d, coreObject, value]() {
|
||||||
|
if (coreObject && !coreObject->mDeleted) coreObject->onSetValue(value);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
mConnection->makeConnectToModel(&SafeObject::valueChanged, [this, coreObject = mCoreObject.get()](QVariant value) {
|
||||||
|
if (coreObject && !coreObject->mDeleted)
|
||||||
|
mConnection->invokeToCore([this, value, coreObject]() {
|
||||||
|
if (coreObject && !coreObject->mDeleted) coreObject->valueChanged(value);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
connect(mCoreObject.get(), &SafeObject::valueChanged, this, &VariantObject::valueChanged);
|
connect(mCoreObject.get(), &SafeObject::valueChanged, this, &VariantObject::valueChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
VariantObject::~VariantObject() {
|
VariantObject::~VariantObject() {
|
||||||
|
mCoreObject->mDeleted = true;
|
||||||
|
mModelObject->mDeleted = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant VariantObject::getValue() const {
|
QVariant VariantObject::getValue() const {
|
||||||
|
|
|
||||||
|
|
@ -38,13 +38,18 @@ class VariantObject : public QObject, public AbstractObject {
|
||||||
public:
|
public:
|
||||||
VariantObject(QString name, QObject *parent = nullptr);
|
VariantObject(QString name, QObject *parent = nullptr);
|
||||||
VariantObject(QString name, QVariant defaultValue, QObject *parent = nullptr);
|
VariantObject(QString name, QVariant defaultValue, QObject *parent = nullptr);
|
||||||
~VariantObject();
|
virtual ~VariantObject();
|
||||||
|
|
||||||
|
// Note: do not use member because 'this' is managed by GUI and can be deleted. Objects scope should have the same
|
||||||
|
// as connections so it should be fine to use the object directly.
|
||||||
template <typename Func, typename... Args>
|
template <typename Func, typename... Args>
|
||||||
void makeRequest(Func &&callable, Args &&...args) {
|
void makeRequest(Func &&callable, Args &&...args) {
|
||||||
mConnection->makeConnectToCore(&SafeObject::requestValue, [this, callable, args...]() {
|
mConnection->makeConnectToCore(&SafeObject::requestValue,
|
||||||
mConnection->invokeToModel([this, callable, args...]() { mModelObject->setValue(callable(args...)); });
|
[this, modelObject = mModelObject.get(), callable, args...]() {
|
||||||
});
|
mConnection->invokeToModel([this, modelObject, callable, args...]() {
|
||||||
|
modelObject->setValue(callable(args...));
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
template <typename Sender, typename SenderClass>
|
template <typename Sender, typename SenderClass>
|
||||||
void makeUpdate(Sender sender, SenderClass signal) {
|
void makeUpdate(Sender sender, SenderClass signal) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue