From 81cf29f92427c0c564861aa34bba632f98fad42e Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Wed, 1 Nov 2023 20:57:39 +0100 Subject: Possibly fix crash when room is cleared on event delegate --- src/timeline/EventDelegateChooser.cpp | 109 +++++++++++++++++++--------------- 1 file changed, 60 insertions(+), 49 deletions(-) (limited to 'src') diff --git a/src/timeline/EventDelegateChooser.cpp b/src/timeline/EventDelegateChooser.cpp index 99a4cf3a..f299b991 100644 --- a/src/timeline/EventDelegateChooser.cpp +++ b/src/timeline/EventDelegateChooser.cpp @@ -162,48 +162,50 @@ EventDelegateChooser::DelegateIncubator::setInitialState(QObject *obj) // setInitialProperties(rolesToSet); - auto update = - [this, obj, roleToPropIdx = std::move(roleToPropIdx)](const QList &changedRoles) { - if (changedRoles.empty() || changedRoles.contains(TimelineModel::Roles::Type)) { - int type = chooser.room_ - ->dataById(currentId, - TimelineModel::Roles::Type, - forReply ? chooser.eventId_ : QString()) - .toInt(); - if (type != oldType) { - // nhlog::ui()->debug("Type changed!"); - reset(currentId); - return; - } - } - - std::vector rolesToRequest; - - if (changedRoles.empty()) { - for (const auto role : - std::ranges::subrange(roleToPropIdx.keyBegin(), roleToPropIdx.keyEnd())) - rolesToRequest.emplace_back(role); - } else { - for (auto role : changedRoles) { - if (roleToPropIdx.contains(role)) { - rolesToRequest.emplace_back(role); - } - } - } - - if (rolesToRequest.empty()) - return; - - auto mo = obj->metaObject(); - chooser.room_->multiData( - currentId, forReply ? chooser.eventId_ : QString(), rolesToRequest); - - Qt::beginPropertyUpdateGroup(); - for (const auto &role : rolesToRequest) { - mo->property(roleToPropIdx[role.role()]).write(obj, role.data()); - } - Qt::endPropertyUpdateGroup(); - }; + auto update = [this, obj, roleToPropIdx = std::move(roleToPropIdx)]( + const QList &changedRoles, TimelineModel *room) { + if (!room) + return; + + if (changedRoles.empty() || changedRoles.contains(TimelineModel::Roles::Type)) { + int type = room + ->dataById(currentId, + TimelineModel::Roles::Type, + forReply ? chooser.eventId_ : QString()) + .toInt(); + if (type != oldType) { + // nhlog::ui()->debug("Type changed!"); + reset(currentId); + return; + } + } + + std::vector rolesToRequest; + + if (changedRoles.empty()) { + for (const auto role : + std::ranges::subrange(roleToPropIdx.keyBegin(), roleToPropIdx.keyEnd())) + rolesToRequest.emplace_back(role); + } else { + for (auto role : changedRoles) { + if (roleToPropIdx.contains(role)) { + rolesToRequest.emplace_back(role); + } + } + } + + if (rolesToRequest.empty()) + return; + + auto mo = obj->metaObject(); + room->multiData(currentId, forReply ? chooser.eventId_ : QString(), rolesToRequest); + + Qt::beginPropertyUpdateGroup(); + for (const auto &role : rolesToRequest) { + mo->property(roleToPropIdx[role.role()]).write(obj, role.data()); + } + Qt::endPropertyUpdateGroup(); + }; if (!forReply) { auto row = chooser.room_->idToIndex(currentId); @@ -211,18 +213,27 @@ EventDelegateChooser::DelegateIncubator::setInitialState(QObject *obj) chooser.room_, &QAbstractItemModel::dataChanged, obj, - [row, update](const QModelIndex &topLeft, - const QModelIndex &bottomRight, - const QList &changedRoles) { + [row, update, room = chooser.room_](const QModelIndex &topLeft, + const QModelIndex &bottomRight, + const QList &changedRoles) { if (row < topLeft.row() || row > bottomRight.row()) return; - update(changedRoles); + update(changedRoles, room); }, Qt::QueuedConnection); - connect(&this->chooser, &EventDelegateChooser::destroyed, obj, [connection]() { - QObject::disconnect(connection); - }); + connect( + &this->chooser, + &EventDelegateChooser::destroyed, + obj, + [connection]() { QObject::disconnect(connection); }, + Qt::SingleShotConnection); + connect( + &this->chooser, + &EventDelegateChooser::roomChanged, + obj, + [connection]() { QObject::disconnect(connection); }, + Qt::SingleShotConnection); } } -- cgit 1.4.1