core/transformwatcher: fix crash when a or b is destroyed

Usually happens during reload.
This commit is contained in:
outfoxxed 2024-06-09 15:42:38 -07:00
parent b5b9c1f6c3
commit 67783ec24c
Signed by: outfoxxed
GPG key ID: 4C88A185FB89301E
2 changed files with 51 additions and 2 deletions

View file

@ -82,7 +82,10 @@ void TransformWatcher::linkItem(QQuickItem* item) const {
QObject::connect(item, &QQuickItem::parentChanged, this, &TransformWatcher::recalcChains); QObject::connect(item, &QQuickItem::parentChanged, this, &TransformWatcher::recalcChains);
QObject::connect(item, &QQuickItem::windowChanged, this, &TransformWatcher::recalcChains); QObject::connect(item, &QQuickItem::windowChanged, this, &TransformWatcher::recalcChains);
QObject::connect(item, &QObject::destroyed, this, &TransformWatcher::recalcChains);
if (item != this->mA && item != this->mB) {
QObject::connect(item, &QObject::destroyed, this, &TransformWatcher::itemDestroyed);
}
} }
void TransformWatcher::linkChains() { void TransformWatcher::linkChains() {
@ -103,6 +106,18 @@ void TransformWatcher::unlinkChains() {
for (auto* item: this->childChain) { for (auto* item: this->childChain) {
QObject::disconnect(item, nullptr, this, nullptr); QObject::disconnect(item, nullptr, this, nullptr);
} }
// relink a and b destruction notifications
if (this->mA != nullptr) {
QObject::connect(this->mA, &QObject::destroyed, this, &TransformWatcher::aDestroyed);
}
if (this->mB != nullptr) {
QObject::connect(this->mB, &QObject::destroyed, this, &TransformWatcher::bDestroyed);
}
this->parentChain.clear();
this->childChain.clear();
} }
void TransformWatcher::recalcChains() { void TransformWatcher::recalcChains() {
@ -111,26 +126,57 @@ void TransformWatcher::recalcChains() {
this->linkChains(); this->linkChains();
} }
void TransformWatcher::itemDestroyed() {
auto destroyed =
this->parentChain.removeOne(this->sender()) || this->childChain.removeOne(this->sender());
if (destroyed) this->recalcChains();
}
QQuickItem* TransformWatcher::a() const { return this->mA; } QQuickItem* TransformWatcher::a() const { return this->mA; }
void TransformWatcher::setA(QQuickItem* a) { void TransformWatcher::setA(QQuickItem* a) {
if (this->mA == a) return; if (this->mA == a) return;
if (this->mA != nullptr) QObject::disconnect(this->mA, nullptr, this, nullptr);
this->mA = a; this->mA = a;
if (this->mA != nullptr) {
QObject::connect(this->mA, &QObject::destroyed, this, &TransformWatcher::aDestroyed);
}
this->recalcChains(); this->recalcChains();
} }
void TransformWatcher::aDestroyed() {
this->mA = nullptr;
this->unlinkChains();
emit this->aChanged();
}
QQuickItem* TransformWatcher::b() const { return this->mB; } QQuickItem* TransformWatcher::b() const { return this->mB; }
void TransformWatcher::setB(QQuickItem* b) { void TransformWatcher::setB(QQuickItem* b) {
if (this->mB == b) return; if (this->mB == b) return;
if (this->mB != nullptr) QObject::disconnect(this->mB, nullptr, this, nullptr);
this->mB = b; this->mB = b;
if (this->mB != nullptr) {
QObject::connect(this->mB, &QObject::destroyed, this, &TransformWatcher::bDestroyed);
}
this->recalcChains(); this->recalcChains();
} }
void TransformWatcher::bDestroyed() {
this->mB = nullptr;
this->unlinkChains();
emit this->bChanged();
}
QQuickItem* TransformWatcher::commonParent() const { return this->mCommonParent; } QQuickItem* TransformWatcher::commonParent() const { return this->mCommonParent; }
void TransformWatcher::setCommonParent(QQuickItem* commonParent) { void TransformWatcher::setCommonParent(QQuickItem* commonParent) {
if (this->mCommonParent == commonParent) return; if (this->mCommonParent == commonParent) return;
this->mCommonParent = commonParent; this->mCommonParent = commonParent;
this->resolveChains(); this->recalcChains();
} }

View file

@ -60,6 +60,9 @@ signals:
private slots: private slots:
void recalcChains(); void recalcChains();
void itemDestroyed();
void aDestroyed();
void bDestroyed();
private: private:
void resolveChains(QQuickItem* a, QQuickItem* b, QQuickItem* commonParent); void resolveChains(QQuickItem* a, QQuickItem* b, QQuickItem* commonParent);