summaryrefslogtreecommitdiffstats
path: root/common/resultprovider.h
diff options
context:
space:
mode:
Diffstat (limited to 'common/resultprovider.h')
-rw-r--r--common/resultprovider.h114
1 files changed, 84 insertions, 30 deletions
diff --git a/common/resultprovider.h b/common/resultprovider.h
index bc03152..d50f3f6 100644
--- a/common/resultprovider.h
+++ b/common/resultprovider.h
@@ -20,9 +20,12 @@
20 20
21#pragma once 21#pragma once
22 22
23#include <QThread>
23#include <functional> 24#include <functional>
24#include <memory> 25#include <memory>
25#include "threadboundary.h" 26#include "threadboundary.h"
27#include "resultset.h"
28#include "log.h"
26 29
27using namespace async; 30using namespace async;
28 31
@@ -34,11 +37,43 @@ namespace Akonadi2 {
34template<class T> 37template<class T>
35class ResultEmitter; 38class ResultEmitter;
36 39
40template<class T>
41class ResultProviderInterface
42{
43public:
44 ResultProviderInterface()
45 : mRevision(0)
46 {
47
48 }
49
50 virtual void add(const T &value) = 0;
51 virtual void modify(const T &value) = 0;
52 virtual void remove(const T &value) = 0;
53 virtual void initialResultSetComplete(const T &parent) = 0;
54 virtual void complete() = 0;
55 virtual void clear() = 0;
56 virtual void setFetcher(const std::function<void(const T &parent)> &fetcher) = 0;
57
58 void setRevision(qint64 revision)
59 {
60 mRevision = revision;
61 }
62
63 qint64 revision() const
64 {
65 return mRevision;
66 }
67
68private:
69 qint64 mRevision;
70};
71
37/* 72/*
38* The promise side for the result emitter 73* The promise side for the result emitter
39*/ 74*/
40template<class T> 75template<class T>
41class ResultProvider { 76class ResultProvider : public ResultProviderInterface<T> {
42private: 77private:
43 void callInMainThreadOnEmitter(void (ResultEmitter<T>::*f)()) 78 void callInMainThreadOnEmitter(void (ResultEmitter<T>::*f)())
44 { 79 {
@@ -69,6 +104,12 @@ private:
69 } 104 }
70 105
71public: 106public:
107 typedef QSharedPointer<ResultProvider<T> > Ptr;
108
109 virtual ~ResultProvider()
110 {
111 }
112
72 //Called from worker thread 113 //Called from worker thread
73 void add(const T &value) 114 void add(const T &value)
74 { 115 {
@@ -103,9 +144,15 @@ public:
103 }); 144 });
104 } 145 }
105 146
106 void initialResultSetComplete() 147 void initialResultSetComplete(const T &parent)
107 { 148 {
108 callInMainThreadOnEmitter(&ResultEmitter<T>::initialResultSetComplete); 149 //Because I don't know how to use bind
150 auto weakEmitter = mResultEmitter;
151 callInMainThreadOnEmitter([weakEmitter, parent](){
152 if (auto strongRef = weakEmitter.toStrongRef()) {
153 strongRef->initialResultSetComplete(parent);
154 }
155 });
109 } 156 }
110 157
111 //Called from worker thread 158 //Called from worker thread
@@ -126,30 +173,16 @@ public:
126 //We have to go over a separate var and return that, otherwise we'd delete the emitter immediately again 173 //We have to go over a separate var and return that, otherwise we'd delete the emitter immediately again
127 auto sharedPtr = QSharedPointer<ResultEmitter<T> >(new ResultEmitter<T>, [this](ResultEmitter<T> *emitter){ mThreadBoundary->callInMainThread([this]() {done();}); delete emitter; }); 174 auto sharedPtr = QSharedPointer<ResultEmitter<T> >(new ResultEmitter<T>, [this](ResultEmitter<T> *emitter){ mThreadBoundary->callInMainThread([this]() {done();}); delete emitter; });
128 mResultEmitter = sharedPtr; 175 mResultEmitter = sharedPtr;
176 sharedPtr->setFetcher([this](const T &parent) {
177 Q_ASSERT(mFetcher);
178 mFetcher(parent);
179 });
129 return sharedPtr; 180 return sharedPtr;
130 } 181 }
131 182
132 return mResultEmitter.toStrongRef(); 183 return mResultEmitter.toStrongRef();
133 } 184 }
134 185
135 /**
136 * For lifetimemanagement only.
137 * We keep the runner alive as long as the result provider exists.
138 */
139 void setQueryRunner(const QSharedPointer<QObject> &runner)
140 {
141 mQueryRunner = runner;
142 }
143
144 /**
145 * For lifetimemanagement only.
146 * We keep the runner alive as long as the result provider exists.
147 */
148 void setFacade(const std::shared_ptr<void> &facade)
149 {
150 mFacade = facade;
151 }
152
153 void onDone(const std::function<void()> &callback) 186 void onDone(const std::function<void()> &callback)
154 { 187 {
155 mThreadBoundary = QSharedPointer<ThreadBoundary>::create(); 188 mThreadBoundary = QSharedPointer<ThreadBoundary>::create();
@@ -162,21 +195,27 @@ public:
162 return mResultEmitter.toStrongRef().isNull(); 195 return mResultEmitter.toStrongRef().isNull();
163 } 196 }
164 197
198 void setFetcher(const std::function<void(const T &parent)> &fetcher)
199 {
200 mFetcher = fetcher;
201 }
202
165private: 203private:
166 void done() 204 void done()
167 { 205 {
168 qWarning() << "done"; 206 qWarning() << "done";
169 if (mOnDoneCallback) { 207 if (mOnDoneCallback) {
170 mOnDoneCallback(); 208 auto callback = mOnDoneCallback;
171 mOnDoneCallback = std::function<void()>(); 209 mOnDoneCallback = std::function<void()>();
210 //This may delete this object
211 callback();
172 } 212 }
173 } 213 }
174 214
175 QWeakPointer<ResultEmitter<T> > mResultEmitter; 215 QWeakPointer<ResultEmitter<T> > mResultEmitter;
176 QSharedPointer<QObject> mQueryRunner;
177 std::shared_ptr<void> mFacade;
178 std::function<void()> mOnDoneCallback; 216 std::function<void()> mOnDoneCallback;
179 QSharedPointer<ThreadBoundary> mThreadBoundary; 217 QSharedPointer<ThreadBoundary> mThreadBoundary;
218 std::function<void(const T &parent)> mFetcher;
180}; 219};
181 220
182/* 221/*
@@ -194,6 +233,8 @@ private:
194template<class DomainType> 233template<class DomainType>
195class ResultEmitter { 234class ResultEmitter {
196public: 235public:
236 typedef QSharedPointer<ResultEmitter<DomainType> > Ptr;
237
197 void onAdded(const std::function<void(const DomainType&)> &handler) 238 void onAdded(const std::function<void(const DomainType&)> &handler)
198 { 239 {
199 addHandler = handler; 240 addHandler = handler;
@@ -209,7 +250,7 @@ public:
209 removeHandler = handler; 250 removeHandler = handler;
210 } 251 }
211 252
212 void onInitialResultSetComplete(const std::function<void(void)> &handler) 253 void onInitialResultSetComplete(const std::function<void(const DomainType&)> &handler)
213 { 254 {
214 initialResultSetCompleteHandler = handler; 255 initialResultSetCompleteHandler = handler;
215 } 256 }
@@ -239,28 +280,41 @@ public:
239 removeHandler(value); 280 removeHandler(value);
240 } 281 }
241 282
242 void initialResultSetComplete() 283 void initialResultSetComplete(const DomainType &parent)
243 { 284 {
244 initialResultSetCompleteHandler(); 285 if (initialResultSetCompleteHandler) {
286 initialResultSetCompleteHandler(parent);
287 }
245 } 288 }
246 289
247 void complete() 290 void complete()
248 { 291 {
249 completeHandler(); 292 if (completeHandler) {
293 completeHandler();
294 }
250 } 295 }
251 296
252 void clear() 297 void clear()
253 { 298 {
254 clearHandler(); 299 if (clearHandler) {
300 clearHandler();
301 }
255 } 302 }
256 303
304 void setFetcher(const std::function<void(const DomainType &parent)> &fetcher)
305 {
306 mFetcher = fetcher;
307 }
308
309 std::function<void(const DomainType &parent)> mFetcher;
310
257private: 311private:
258 friend class ResultProvider<DomainType>; 312 friend class ResultProvider<DomainType>;
259 313
260 std::function<void(const DomainType&)> addHandler; 314 std::function<void(const DomainType&)> addHandler;
261 std::function<void(const DomainType&)> modifyHandler; 315 std::function<void(const DomainType&)> modifyHandler;
262 std::function<void(const DomainType&)> removeHandler; 316 std::function<void(const DomainType&)> removeHandler;
263 std::function<void(void)> initialResultSetCompleteHandler; 317 std::function<void(const DomainType&)> initialResultSetCompleteHandler;
264 std::function<void(void)> completeHandler; 318 std::function<void(void)> completeHandler;
265 std::function<void(void)> clearHandler; 319 std::function<void(void)> clearHandler;
266 ThreadBoundary mThreadBoundary; 320 ThreadBoundary mThreadBoundary;