Global crash fix : Cpp Objects were destroyed on GUI destruction.

Add debug name on VariantObject.
This commit is contained in:
Julien Wadel 2025-01-08 18:41:32 +01:00
parent 5d1e837786
commit fb29ddb4c4
3 changed files with 27 additions and 21 deletions

View file

@ -26,24 +26,29 @@
#include "core/App.hpp"
DEFINE_ABSTRACT_OBJECT(VariantObject)
VariantObject::VariantObject(QObject *parent) : VariantObject(QVariant()) {
VariantObject::VariantObject(QString name, QObject *parent) : VariantObject(name, QVariant()) {
}
VariantObject::VariantObject(QVariant defaultValue, QObject *parent) {
mCoreObject = QSharedPointer<SafeObject>::create(defaultValue);
mModelObject = QSharedPointer<SafeObject>::create();
VariantObject::VariantObject(QString name, QVariant defaultValue, QObject *parent) {
mName = name;
mCoreObject = QSharedPointer<SafeObject>(new SafeObject(defaultValue), &QObject::deleteLater);
mModelObject = QSharedPointer<SafeObject>(new SafeObject(), &QObject::deleteLater);
mModelObject->moveToThread(CoreModel::getInstance()->thread());
App::getInstance()->mEngine->setObjectOwnership(mCoreObject.get(), QQmlEngine::CppOwnership);
App::getInstance()->mEngine->setObjectOwnership(mModelObject.get(), QQmlEngine::CppOwnership);
mConnection = QSharedPointer<SafeConnection<SafeObject, SafeObject>>(
new SafeConnection<SafeObject, SafeObject>(mCoreObject, mModelObject), &QObject::deleteLater);
mConnection->makeConnectToCore(&SafeObject::setValue, [this](QVariant value) {
mConnection->invokeToModel([this, value]() {
mConnection->makeConnectToCore(&SafeObject::setValue, [this, d = mName](QVariant value) {
mConnection->invokeToModel([this, value, d]() {
if (mModelObject) mModelObject->onSetValue(value);
});
});
mConnection->makeConnectToModel(&SafeObject::setValue, [this](QVariant value) {
mConnection->invokeToCore([this, value]() {
if (mCoreObject) mCoreObject->onSetValue(value);
mConnection->makeConnectToModel(&SafeObject::setValue, [this, d = mName, coreObject = mCoreObject](QVariant value) {
// Note: do not use member because 'this' is managed by GUI and can be deleted.
mConnection->invokeToCore([this, d, coreObject, value]() {
if (coreObject) coreObject->onSetValue(value);
});
});
mConnection->makeConnectToModel(&SafeObject::valueChanged, [this](QVariant value) {

View file

@ -36,8 +36,8 @@ class VariantObject : public QObject, public AbstractObject {
Q_OBJECT
Q_PROPERTY(QVariant value READ getValue NOTIFY valueChanged)
public:
VariantObject(QObject *parent = nullptr);
VariantObject(QVariant defaultValue, QObject *parent = nullptr);
VariantObject(QString name, QObject *parent = nullptr);
VariantObject(QString name, QVariant defaultValue, QObject *parent = nullptr);
~VariantObject();
template <typename Func, typename... Args>
@ -51,7 +51,7 @@ public:
mConnection->makeConnectToModel(
sender, signal, [this]() { mConnection->invokeToCore([this]() { mCoreObject->requestValue(); }); });
}
QString mName; // usefull to know what is this VariantObject
QVariant getValue() const;
void requestValue();
void setDefaultValue(QVariant value);

View file

@ -63,7 +63,8 @@ VariantObject *Utils::getDisplayName(const QString &address) {
QStringList splitted = address.split(":");
if (splitted.size() > 0 && splitted[0] == "sip") splitted.removeFirst();
VariantObject *data = nullptr;
if (splitted.size() != 0) data = new VariantObject(splitted.first().split("@").first()); // Scope : GUI
if (splitted.size() != 0)
data = new VariantObject("getDisplayName", splitted.first().split("@").first()); // Scope : GUI
if (!data) return nullptr;
data->makeRequest([address]() {
QString displayName = ToolModel::getDisplayName(address);
@ -115,7 +116,7 @@ QString Utils::getInitials(const QString &username) {
}
VariantObject *Utils::findLocalAccountByAddress(const QString &address) {
VariantObject *data = new VariantObject();
VariantObject *data = new VariantObject("findLocalAccountByAddress");
if (!data) return nullptr;
data->makeRequest([address]() {
auto linAccount = ToolModel::findAccount(address);
@ -191,7 +192,7 @@ void Utils::showInformationPopup(const QString &title,
}
VariantObject *Utils::haveAccount() {
VariantObject *result = new VariantObject();
VariantObject *result = new VariantObject("haveAccount");
if (!result) return nullptr;
// Using connect ensure to have sender() and receiver() alive.
result->makeRequest([]() {
@ -322,7 +323,7 @@ QString Utils::formatDateElapsedTime(const QDateTime &date) {
}
VariantObject *Utils::interpretUrl(QString uri) {
VariantObject *data = new VariantObject(uri);
VariantObject *data = new VariantObject("interpretUrl", uri);
if (!data) return nullptr;
data->makeRequest([uri]() -> QVariant {
QString address = uri;
@ -344,7 +345,7 @@ bool Utils::isValidURL(const QString &url) {
}
VariantObject *Utils::findAvatarByAddress(const QString &address) {
VariantObject *data = new VariantObject("");
VariantObject *data = new VariantObject("findAvatarByAddress", "");
if (!data) return nullptr;
data->makeRequest([address]() -> QVariant {
QString avatar;
@ -360,7 +361,7 @@ VariantObject *Utils::findAvatarByAddress(const QString &address) {
}
VariantObject *Utils::findFriendByAddress(const QString &address) {
VariantObject *data = new VariantObject();
VariantObject *data = new VariantObject("findFriendByAddress");
if (!data) return nullptr;
data->makeRequest([address]() {
auto linFriend = ToolModel::findFriendByAddress(address);
@ -373,7 +374,7 @@ VariantObject *Utils::findFriendByAddress(const QString &address) {
}
VariantObject *Utils::getFriendAddressSecurityLevel(const QString &address) {
VariantObject *data = new VariantObject();
VariantObject *data = new VariantObject("getFriendAddressSecurityLevel");
if (!data) return nullptr;
data->makeRequest([address]() {
auto defaultFriendList = ToolModel::getAppFriendList();
@ -1316,14 +1317,14 @@ int Utils::getYear(const QDate &date) {
}
VariantObject *Utils::isMe(const QString &address) {
VariantObject *data = new VariantObject(QVariant(false));
VariantObject *data = new VariantObject("isMe", QVariant(false));
if (!data) return nullptr;
data->makeRequest([address]() { return QVariant::fromValue(ToolModel::isMe(address)); });
data->requestValue();
return data;
}
VariantObject *Utils::isLocal(const QString &address) {
VariantObject *data = new VariantObject(QVariant(false));
VariantObject *data = new VariantObject("isLocal", QVariant(false));
data->makeRequest([address]() { return QVariant(ToolModel::isLocal(address)); });
data->requestValue();
return data;