diff options
author | Christian Mollekopf <chrigi_1@fastmail.fm> | 2017-12-28 12:05:34 +0100 |
---|---|---|
committer | Christian Mollekopf <chrigi_1@fastmail.fm> | 2018-01-02 13:31:14 +0100 |
commit | 625190d311adfcf3f0436cfece82249a92489348 (patch) | |
tree | 1010950e14b57560ae90abe20a5657750ad27137 /common/resultprovider.h | |
parent | 11b790ba6f06141db802273628ce2d191982677e (diff) | |
download | sink-625190d311adfcf3f0436cfece82249a92489348.tar.gz sink-625190d311adfcf3f0436cfece82249a92489348.zip |
No parent query
Diffstat (limited to 'common/resultprovider.h')
-rw-r--r-- | common/resultprovider.h | 91 |
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 | ||
396 | private: | 405 | private: |
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 | }; |