diff options
Diffstat (limited to 'common/resultprovider.h')
-rw-r--r-- | common/resultprovider.h | 114 |
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 | ||
27 | using namespace async; | 30 | using namespace async; |
28 | 31 | ||
@@ -34,11 +37,43 @@ namespace Akonadi2 { | |||
34 | template<class T> | 37 | template<class T> |
35 | class ResultEmitter; | 38 | class ResultEmitter; |
36 | 39 | ||
40 | template<class T> | ||
41 | class ResultProviderInterface | ||
42 | { | ||
43 | public: | ||
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 | |||
68 | private: | ||
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 | */ |
40 | template<class T> | 75 | template<class T> |
41 | class ResultProvider { | 76 | class ResultProvider : public ResultProviderInterface<T> { |
42 | private: | 77 | private: |
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 | ||
71 | public: | 106 | public: |
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 | |||
165 | private: | 203 | private: |
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: | |||
194 | template<class DomainType> | 233 | template<class DomainType> |
195 | class ResultEmitter { | 234 | class ResultEmitter { |
196 | public: | 235 | public: |
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 | |||
257 | private: | 311 | private: |
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; |