diff options
author | Christian Mollekopf <chrigi_1@fastmail.fm> | 2017-01-31 19:01:10 +0100 |
---|---|---|
committer | Christian Mollekopf <chrigi_1@fastmail.fm> | 2017-01-31 19:38:57 +0100 |
commit | a910706986aa8e83e070d23525c02649d80c05c3 (patch) | |
tree | d31cf91bdfbaf47ed750a744000327f0f8d45f2a /common/modelresult.cpp | |
parent | 546d86aae7cd0b9766f3a0ea73f3777334d55814 (diff) | |
download | sink-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.cpp | 49 |
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 | ||
35 | static qint64 getIdentifier(const QModelIndex &idx) | ||
36 | { | ||
37 | if (!idx.isValid()) { | ||
38 | return 0; | ||
39 | } | ||
40 | return idx.internalId(); | ||
41 | } | ||
42 | |||
34 | template <class T, class Ptr> | 43 | template <class T, class Ptr> |
35 | ModelResult<T, Ptr>::ModelResult(const Sink::Query &query, const QList<QByteArray> &propertyColumns, const Sink::Log::Context &ctx) | 44 | ModelResult<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 | ||
40 | static qint64 getIdentifier(const QModelIndex &idx) | 49 | template <class T, class Ptr> |
50 | ModelResult<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 | ||
48 | template <class T, class Ptr> | 57 | template <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 | } |