summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorNicolas Werner <nicolas.werner@hotmail.de>2023-11-01 20:57:39 +0100
committerNicolas Werner <nicolas.werner@hotmail.de>2023-11-01 20:57:39 +0100
commit81cf29f92427c0c564861aa34bba632f98fad42e (patch)
treed71ad65d75a0688709c0c6e384ad7a0cae3d39c5 /src
parentFix trailing whitespace (diff)
downloadnheko-81cf29f92427c0c564861aa34bba632f98fad42e.tar.xz
Possibly fix crash when room is cleared on event delegate
Diffstat (limited to 'src')
-rw-r--r--src/timeline/EventDelegateChooser.cpp109
1 files changed, 60 insertions, 49 deletions
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<int> &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<QModelRoleData> 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<int> &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<QModelRoleData> 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<int> &changedRoles) {
+          [row, update, room = chooser.room_](const QModelIndex &topLeft,
+                                              const QModelIndex &bottomRight,
+                                              const QList<int> &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);
     }
 }