summaryrefslogtreecommitdiffstats
path: root/common/resultprovider.h
diff options
context:
space:
mode:
authorChristian Mollekopf <chrigi_1@fastmail.fm>2017-12-28 12:05:34 +0100
committerChristian Mollekopf <chrigi_1@fastmail.fm>2018-01-02 13:31:14 +0100
commit625190d311adfcf3f0436cfece82249a92489348 (patch)
tree1010950e14b57560ae90abe20a5657750ad27137 /common/resultprovider.h
parent11b790ba6f06141db802273628ce2d191982677e (diff)
downloadsink-625190d311adfcf3f0436cfece82249a92489348.tar.gz
sink-625190d311adfcf3f0436cfece82249a92489348.zip
No parent query
Diffstat (limited to 'common/resultprovider.h')
-rw-r--r--common/resultprovider.h91
1 files changed, 50 insertions, 41 deletions
diff --git a/common/resultprovider.h b/common/resultprovider.h
index d6feaf9..890e109 100644
--- a/common/resultprovider.h
+++ b/common/resultprovider.h
@@ -48,10 +48,10 @@ public:
48 virtual void add(const T &value) = 0; 48 virtual void add(const T &value) = 0;
49 virtual void modify(const T &value) = 0; 49 virtual void modify(const T &value) = 0;
50 virtual void remove(const T &value) = 0; 50 virtual void remove(const T &value) = 0;
51 virtual void initialResultSetComplete(const T &parent, bool) = 0; 51 virtual void initialResultSetComplete(bool) = 0;
52 virtual void complete() = 0; 52 virtual void complete() = 0;
53 virtual void clear() = 0; 53 virtual void clear() = 0;
54 virtual void setFetcher(const std::function<void(const T &parent)> &fetcher) = 0; 54 virtual void setFetcher(const std::function<void()> &fetcher) = 0;
55 55
56 void setRevision(qint64 revision) 56 void setRevision(qint64 revision)
57 { 57 {
@@ -102,10 +102,10 @@ public:
102 } 102 }
103 } 103 }
104 104
105 void initialResultSetComplete(const T &parent, bool replayedAll) 105 void initialResultSetComplete(bool replayedAll)
106 { 106 {
107 if (auto strongRef = mResultEmitter.toStrongRef()) { 107 if (auto strongRef = mResultEmitter.toStrongRef()) {
108 strongRef->initialResultSetComplete(parent, replayedAll); 108 strongRef->initialResultSetComplete(replayedAll);
109 } 109 }
110 } 110 }
111 111
@@ -134,9 +134,9 @@ public:
134 delete emitter; 134 delete emitter;
135 }); 135 });
136 mResultEmitter = sharedPtr; 136 mResultEmitter = sharedPtr;
137 sharedPtr->setFetcher([this](const T &parent) { 137 sharedPtr->setFetcher([this]() {
138 Q_ASSERT(mFetcher); 138 Q_ASSERT(mFetcher);
139 mFetcher(parent); 139 mFetcher();
140 }); 140 });
141 return sharedPtr; 141 return sharedPtr;
142 } 142 }
@@ -155,7 +155,7 @@ public:
155 return mResultEmitter.toStrongRef().isNull(); 155 return mResultEmitter.toStrongRef().isNull();
156 } 156 }
157 157
158 void setFetcher(const std::function<void(const T &parent)> &fetcher) 158 void setFetcher(const std::function<void()> &fetcher)
159 { 159 {
160 mFetcher = fetcher; 160 mFetcher = fetcher;
161 } 161 }
@@ -173,7 +173,7 @@ private:
173 173
174 QWeakPointer<ResultEmitter<T>> mResultEmitter; 174 QWeakPointer<ResultEmitter<T>> mResultEmitter;
175 std::function<void()> mOnDoneCallback; 175 std::function<void()> mOnDoneCallback;
176 std::function<void(const T &parent)> mFetcher; 176 std::function<void()> mFetcher;
177}; 177};
178 178
179/* 179/*
@@ -222,7 +222,7 @@ public:
222 removeHandler = handler; 222 removeHandler = handler;
223 } 223 }
224 224
225 void onInitialResultSetComplete(const std::function<void(const DomainType &, bool)> &handler) 225 void onInitialResultSetComplete(const std::function<void(bool)> &handler)
226 { 226 {
227 initialResultSetCompleteHandler = handler; 227 initialResultSetCompleteHandler = handler;
228 } 228 }
@@ -246,7 +246,9 @@ public:
246 { 246 {
247 QMutexLocker locker{&mMutex}; 247 QMutexLocker locker{&mMutex};
248 if (guardOk()) { 248 if (guardOk()) {
249 addHandler(value); 249 if (addHandler) {
250 addHandler(value);
251 }
250 } 252 }
251 } 253 }
252 254
@@ -254,7 +256,9 @@ public:
254 { 256 {
255 QMutexLocker locker{&mMutex}; 257 QMutexLocker locker{&mMutex};
256 if (guardOk()) { 258 if (guardOk()) {
257 modifyHandler(value); 259 if (modifyHandler) {
260 modifyHandler(value);
261 }
258 } 262 }
259 } 263 }
260 264
@@ -262,16 +266,20 @@ public:
262 { 266 {
263 QMutexLocker locker{&mMutex}; 267 QMutexLocker locker{&mMutex};
264 if (guardOk()) { 268 if (guardOk()) {
265 removeHandler(value); 269 if (removeHandler) {
270 removeHandler(value);
271 }
266 } 272 }
267 } 273 }
268 274
269 void initialResultSetComplete(const DomainType &parent, bool replayedAll) 275 void initialResultSetComplete(bool replayedAll)
270 { 276 {
271 //This callback is only ever called from the main thread, so we don't do any locking 277 //This callback is only ever called from the main thread, so we don't do any locking
272 if (initialResultSetCompleteHandler && guardOk()) { 278 if (initialResultSetCompleteHandler && guardOk()) {
273 //This can directly lead to our destruction and thus waitForMethodExecutionEnd 279 if (initialResultSetCompleteHandler) {
274 initialResultSetCompleteHandler(parent, replayedAll); 280 //This can directly lead to our destruction and thus waitForMethodExecutionEnd
281 initialResultSetCompleteHandler(replayedAll);
282 }
275 } 283 }
276 } 284 }
277 285
@@ -279,7 +287,9 @@ public:
279 { 287 {
280 QMutexLocker locker{&mMutex}; 288 QMutexLocker locker{&mMutex};
281 if (completeHandler && guardOk()) { 289 if (completeHandler && guardOk()) {
282 completeHandler(); 290 if (completeHandler) {
291 completeHandler();
292 }
283 } 293 }
284 } 294 }
285 295
@@ -287,19 +297,21 @@ public:
287 { 297 {
288 QMutexLocker locker{&mMutex}; 298 QMutexLocker locker{&mMutex};
289 if (clearHandler && guardOk()) { 299 if (clearHandler && guardOk()) {
290 clearHandler(); 300 if (clearHandler) {
301 clearHandler();
302 }
291 } 303 }
292 } 304 }
293 305
294 void setFetcher(const std::function<void(const DomainType &parent)> &fetcher) 306 void setFetcher(const std::function<void()> &fetcher)
295 { 307 {
296 mFetcher = fetcher; 308 mFetcher = fetcher;
297 } 309 }
298 310
299 virtual void fetch(const DomainType &parent) 311 virtual void fetch()
300 { 312 {
301 if (mFetcher) { 313 if (mFetcher) {
302 mFetcher(parent); 314 mFetcher();
303 } 315 }
304 } 316 }
305 317
@@ -309,11 +321,11 @@ private:
309 std::function<void(const DomainType &)> addHandler; 321 std::function<void(const DomainType &)> addHandler;
310 std::function<void(const DomainType &)> modifyHandler; 322 std::function<void(const DomainType &)> modifyHandler;
311 std::function<void(const DomainType &)> removeHandler; 323 std::function<void(const DomainType &)> removeHandler;
312 std::function<void(const DomainType &, bool)> initialResultSetCompleteHandler; 324 std::function<void(bool)> initialResultSetCompleteHandler;
313 std::function<void(void)> completeHandler; 325 std::function<void(void)> completeHandler;
314 std::function<void(void)> clearHandler; 326 std::function<void(void)> clearHandler;
315 327
316 std::function<void(const DomainType &parent)> mFetcher; 328 std::function<void()> mFetcher;
317 /* 329 /*
318 * This mutex is here to protect the emitter from getting destroyed while the producer-thread (ResultProvider) is calling into it, 330 * This mutex is here to protect the emitter from getting destroyed while the producer-thread (ResultProvider) is calling into it,
319 * and vice-verca, to protect the producer thread from calling into a destroyed emitter. 331 * and vice-verca, to protect the producer thread from calling into a destroyed emitter.
@@ -350,53 +362,50 @@ public:
350 emitter->onModified([this](const DomainType &value) { this->modify(value); }); 362 emitter->onModified([this](const DomainType &value) { this->modify(value); });
351 emitter->onRemoved([this](const DomainType &value) { this->remove(value); }); 363 emitter->onRemoved([this](const DomainType &value) { this->remove(value); });
352 auto ptr = emitter.data(); 364 auto ptr = emitter.data();
353 emitter->onInitialResultSetComplete([this, ptr](const DomainType &parent, bool replayedAll) { 365 emitter->onInitialResultSetComplete([this, ptr](bool replayedAll) {
354 auto hashValue = qHash(parent);
355 if (replayedAll) { 366 if (replayedAll) {
356 mAllResultsReplayed.remove(hashValue, ptr); 367 mAllResultsReplayed.remove(ptr);
357 } 368 }
358 mInitialResultSetInProgress.remove(hashValue, ptr); 369 mInitialResultSetInProgress.remove(ptr);
359 callInitialResultCompleteIfDone(parent); 370 callInitialResultCompleteIfDone();
360 }); 371 });
361 emitter->onComplete([this]() { this->complete(); }); 372 emitter->onComplete([this]() { this->complete(); });
362 emitter->onClear([this]() { this->clear(); }); 373 emitter->onClear([this]() { this->clear(); });
363 mEmitter << emitter; 374 mEmitter << emitter;
364 } 375 }
365 376
366 void callInitialResultCompleteIfDone(const DomainType &parent) 377 void callInitialResultCompleteIfDone()
367 { 378 {
368 auto hashValue = qHash(parent);
369 // Normally a parent is only in a single resource, except the toplevel (invalid) parent 379 // Normally a parent is only in a single resource, except the toplevel (invalid) parent
370 if (!mInitialResultSetInProgress.contains(hashValue) && mAllResultsFetched && !mResultEmitted) { 380 if (mInitialResultSetInProgress.isEmpty() && mAllResultsFetched && !mResultEmitted) {
371 bool allResourcesReplayedAll = mAllResultsReplayed.isEmpty();
372 mResultEmitted = true; 381 mResultEmitted = true;
373 this->initialResultSetComplete(parent, allResourcesReplayedAll); 382 this->initialResultSetComplete(mAllResultsReplayed.isEmpty());
374 } 383 }
375 } 384 }
376 385
377 void fetch(const DomainType &parent) Q_DECL_OVERRIDE 386 void fetch() Q_DECL_OVERRIDE
378 { 387 {
379 if (mEmitter.isEmpty()) { 388 if (mEmitter.isEmpty()) {
380 this->initialResultSetComplete(parent, true); 389 this->initialResultSetComplete(true);
381 } else { 390 } else {
382 mResultEmitted = false; 391 mResultEmitted = false;
383 mAllResultsFetched = false; 392 mAllResultsFetched = false;
393 mInitialResultSetInProgress.clear();
384 mAllResultsReplayed.clear(); 394 mAllResultsReplayed.clear();
385 const auto hashValue = qHash(parent);
386 for (const auto &emitter : mEmitter) { 395 for (const auto &emitter : mEmitter) {
387 mInitialResultSetInProgress.insert(hashValue, emitter.data()); 396 mInitialResultSetInProgress.insert(emitter.data());
388 mAllResultsReplayed.insert(hashValue, emitter.data()); 397 mAllResultsReplayed.insert(emitter.data());
389 emitter->fetch(parent); 398 emitter->fetch();
390 } 399 }
391 mAllResultsFetched = true; 400 mAllResultsFetched = true;
392 callInitialResultCompleteIfDone(parent); 401 callInitialResultCompleteIfDone();
393 } 402 }
394 } 403 }
395 404
396private: 405private:
397 QList<typename ResultEmitter<DomainType>::Ptr> mEmitter; 406 QList<typename ResultEmitter<DomainType>::Ptr> mEmitter;
398 QMultiMap<qint64, ResultEmitter<DomainType> *> mInitialResultSetInProgress; 407 QSet<ResultEmitter<DomainType>*> mInitialResultSetInProgress;
399 QMultiMap<qint64, ResultEmitter<DomainType> *> mAllResultsReplayed; 408 QSet<ResultEmitter<DomainType>*> mAllResultsReplayed;
400 bool mAllResultsFetched; 409 bool mAllResultsFetched;
401 bool mResultEmitted; 410 bool mResultEmitted;
402}; 411};