summaryrefslogtreecommitdiffstats
path: root/common/modelresult.cpp
diff options
context:
space:
mode:
authorChristian Mollekopf <chrigi_1@fastmail.fm>2017-01-31 19:01:10 +0100
committerChristian Mollekopf <chrigi_1@fastmail.fm>2017-01-31 19:38:57 +0100
commita910706986aa8e83e070d23525c02649d80c05c3 (patch)
treed31cf91bdfbaf47ed750a744000327f0f8d45f2a /common/modelresult.cpp
parent546d86aae7cd0b9766f3a0ea73f3777334d55814 (diff)
downloadsink-a910706986aa8e83e070d23525c02649d80c05c3.tar.gz
sink-a910706986aa8e83e070d23525c02649d80c05c3.zip
Don't call into the model after the model has been destroyed.
Diffstat (limited to 'common/modelresult.cpp')
-rw-r--r--common/modelresult.cpp49
1 files changed, 33 insertions, 16 deletions
diff --git a/common/modelresult.cpp b/common/modelresult.cpp
index 695072c..0825518 100644
--- a/common/modelresult.cpp
+++ b/common/modelresult.cpp
@@ -21,6 +21,7 @@
21 21
22#include <QDebug> 22#include <QDebug>
23#include <QThread> 23#include <QThread>
24#include <QPointer>
24 25
25#include "log.h" 26#include "log.h"
26 27
@@ -31,18 +32,26 @@ static uint qHash(const Sink::ApplicationDomain::ApplicationDomainType &type)
31 return qHash(type.resourceInstanceIdentifier() + type.identifier()); 32 return qHash(type.resourceInstanceIdentifier() + type.identifier());
32} 33}
33 34
35static qint64 getIdentifier(const QModelIndex &idx)
36{
37 if (!idx.isValid()) {
38 return 0;
39 }
40 return idx.internalId();
41}
42
34template <class T, class Ptr> 43template <class T, class Ptr>
35ModelResult<T, Ptr>::ModelResult(const Sink::Query &query, const QList<QByteArray> &propertyColumns, const Sink::Log::Context &ctx) 44ModelResult<T, Ptr>::ModelResult(const Sink::Query &query, const QList<QByteArray> &propertyColumns, const Sink::Log::Context &ctx)
36 : QAbstractItemModel(), mLogCtx(ctx.subContext("modelresult")), mPropertyColumns(propertyColumns), mQuery(query) 45 : QAbstractItemModel(), mLogCtx(ctx.subContext("modelresult")), mPropertyColumns(propertyColumns), mQuery(query)
37{ 46{
38} 47}
39 48
40static qint64 getIdentifier(const QModelIndex &idx) 49template <class T, class Ptr>
50ModelResult<T, Ptr>::~ModelResult()
41{ 51{
42 if (!idx.isValid()) { 52 if (mEmitter) {
43 return 0; 53 mEmitter->waitForMethodExecutionEnd();
44 } 54 }
45 return idx.internalId();
46} 55}
47 56
48template <class T, class Ptr> 57template <class T, class Ptr>
@@ -259,33 +268,41 @@ void ModelResult<T, Ptr>::setEmitter(const typename Sink::ResultEmitter<Ptr>::Pt
259{ 268{
260 setFetcher([this](const Ptr &parent) { mEmitter->fetch(parent); }); 269 setFetcher([this](const Ptr &parent) { mEmitter->fetch(parent); });
261 270
262 emitter->onAdded([this](const Ptr &value) { 271 QPointer<QObject> guard(this);
272 emitter->onAdded([this, guard](const Ptr &value) {
263 SinkTraceCtx(mLogCtx) << "Received addition: " << value->identifier(); 273 SinkTraceCtx(mLogCtx) << "Received addition: " << value->identifier();
264 threadBoundary.callInMainThread([this, value]() { 274 Q_ASSERT(guard);
275 threadBoundary.callInMainThread([this, value, guard]() {
276 Q_ASSERT(guard);
265 add(value); 277 add(value);
266 }); 278 });
267 }); 279 });
268 emitter->onModified([this](const Ptr &value) { 280 emitter->onModified([this, guard](const Ptr &value) {
269 SinkTraceCtx(mLogCtx) << "Received modification: " << value->identifier(); 281 SinkTraceCtx(mLogCtx) << "Received modification: " << value->identifier();
282 Q_ASSERT(guard);
270 threadBoundary.callInMainThread([this, value]() { 283 threadBoundary.callInMainThread([this, value]() {
271 modify(value); 284 modify(value);
272 }); 285 });
273 }); 286 });
274 emitter->onRemoved([this](const Ptr &value) { 287 emitter->onRemoved([this, guard](const Ptr &value) {
275 SinkTraceCtx(mLogCtx) << "Received removal: " << value->identifier(); 288 SinkTraceCtx(mLogCtx) << "Received removal: " << value->identifier();
289 Q_ASSERT(guard);
276 threadBoundary.callInMainThread([this, value]() { 290 threadBoundary.callInMainThread([this, value]() {
277 remove(value); 291 remove(value);
278 }); 292 });
279 }); 293 });
280 emitter->onInitialResultSetComplete([this](const Ptr &parent, bool fetchedAll) { 294 emitter->onInitialResultSetComplete([this, guard](const Ptr &parent, bool fetchedAll) {
281 SinkTraceCtx(mLogCtx) << "Initial result set complete. Fetched all: " << fetchedAll; 295 SinkTraceCtx(mLogCtx) << "Initial result set complete. Fetched all: " << fetchedAll;
282 const qint64 parentId = parent ? qHash(*parent) : 0; 296 Q_ASSERT(guard);
283 const auto parentIndex = createIndexFromId(parentId); 297 threadBoundary.callInMainThread([=]() {
284 mEntityChildrenFetchComplete.insert(parentId); 298 const qint64 parentId = parent ? qHash(*parent) : 0;
285 if (fetchedAll) { 299 const auto parentIndex = createIndexFromId(parentId);
286 mEntityAllChildrenFetched.insert(parentId); 300 mEntityChildrenFetchComplete.insert(parentId);
287 } 301 if (fetchedAll) {
288 emit dataChanged(parentIndex, parentIndex, QVector<int>() << ChildrenFetchedRole); 302 mEntityAllChildrenFetched.insert(parentId);
303 }
304 emit dataChanged(parentIndex, parentIndex, QVector<int>() << ChildrenFetchedRole);
305 });
289 }); 306 });
290 mEmitter = emitter; 307 mEmitter = emitter;
291} 308}