diff options
author | Christian Mollekopf <chrigi_1@fastmail.fm> | 2015-11-27 17:30:04 +0100 |
---|---|---|
committer | Christian Mollekopf <chrigi_1@fastmail.fm> | 2015-11-27 17:30:04 +0100 |
commit | 5b41b26a349967acf2197f9f9228526193fd826e (patch) | |
tree | 166452bcc0757564deefe233bf031d2ccb0564d2 /common/resultprovider.h | |
parent | 13af56e436f49df32d3b2f6f223cf1dec2eabaac (diff) | |
download | sink-5b41b26a349967acf2197f9f9228526193fd826e.tar.gz sink-5b41b26a349967acf2197f9f9228526193fd826e.zip |
Introduced a QueryRunner object
The QueryRunner object lives for the duration of the query (so just
for the initial query for non-live queries, and for the lifetime of the
result model for live queries).
It's supposed to handle all the threading internally and decouple the
lifetime of the facade.
Diffstat (limited to 'common/resultprovider.h')
-rw-r--r-- | common/resultprovider.h | 150 |
1 files changed, 26 insertions, 124 deletions
diff --git a/common/resultprovider.h b/common/resultprovider.h index 921cd6b..86382ef 100644 --- a/common/resultprovider.h +++ b/common/resultprovider.h | |||
@@ -20,12 +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" |
26 | #include "resultset.h" | 27 | #include "resultset.h" |
27 | #include "log.h" | 28 | #include "log.h" |
28 | #include "modelresult.h" | ||
29 | 29 | ||
30 | using namespace async; | 30 | using namespace async; |
31 | 31 | ||
@@ -53,12 +53,7 @@ public: | |||
53 | virtual void initialResultSetComplete() = 0; | 53 | virtual void initialResultSetComplete() = 0; |
54 | virtual void complete() = 0; | 54 | virtual void complete() = 0; |
55 | virtual void clear() = 0; | 55 | virtual void clear() = 0; |
56 | virtual void setFetcher(const std::function<void(const T &parent)> &fetcher) | 56 | virtual void setFetcher(const std::function<void(const T &parent)> &fetcher) = 0; |
57 | { | ||
58 | } | ||
59 | |||
60 | virtual void setFacade(const std::shared_ptr<void> &facade) = 0; | ||
61 | virtual void setQueryRunner(const QSharedPointer<QObject> &runner) = 0; | ||
62 | 57 | ||
63 | void setRevision(qint64 revision) | 58 | void setRevision(qint64 revision) |
64 | { | 59 | { |
@@ -74,101 +69,6 @@ private: | |||
74 | qint64 mRevision; | 69 | qint64 mRevision; |
75 | }; | 70 | }; |
76 | 71 | ||
77 | template<class T, class Ptr> | ||
78 | class ModelResultProvider : public ResultProviderInterface<Ptr> { | ||
79 | public: | ||
80 | ModelResultProvider(QWeakPointer<ModelResult<T, Ptr> > model) | ||
81 | : ResultProviderInterface<Ptr>(), | ||
82 | mModel(model) | ||
83 | { | ||
84 | |||
85 | } | ||
86 | |||
87 | void add(const Ptr &value) | ||
88 | { | ||
89 | if (auto model = mModel.toStrongRef()) { | ||
90 | model->add(value); | ||
91 | } | ||
92 | } | ||
93 | |||
94 | void modify(const Ptr &value) | ||
95 | { | ||
96 | if (auto model = mModel.toStrongRef()) { | ||
97 | model->modify(value); | ||
98 | } | ||
99 | } | ||
100 | |||
101 | void remove(const Ptr &value) | ||
102 | { | ||
103 | if (auto model = mModel.toStrongRef()) { | ||
104 | model->remove(value); | ||
105 | } | ||
106 | } | ||
107 | |||
108 | void initialResultSetComplete() | ||
109 | { | ||
110 | // mResultEmitter->initialResultSetComplete(); | ||
111 | } | ||
112 | |||
113 | void complete() | ||
114 | { | ||
115 | // mResultEmitter->complete(); | ||
116 | } | ||
117 | |||
118 | void clear() | ||
119 | { | ||
120 | // mResultEmitter->clear(); | ||
121 | } | ||
122 | |||
123 | /** | ||
124 | * For lifetimemanagement only. | ||
125 | * We keep the runner alive as long as the result provider exists. | ||
126 | */ | ||
127 | void setFacade(const std::shared_ptr<void> &facade) | ||
128 | { | ||
129 | mFacade = facade; | ||
130 | } | ||
131 | |||
132 | void onDone(const std::function<void()> &callback) | ||
133 | { | ||
134 | mOnDoneCallback = callback; | ||
135 | } | ||
136 | |||
137 | bool isDone() const | ||
138 | { | ||
139 | //The existance of the emitter currently defines wether we're done or not. | ||
140 | // return mResultEmitter.toStrongRef().isNull(); | ||
141 | return true; | ||
142 | } | ||
143 | |||
144 | void setFetcher(const std::function<void(const Ptr &parent)> &fetcher) | ||
145 | { | ||
146 | if (auto model = mModel.toStrongRef()) { | ||
147 | model->setFetcher(fetcher); | ||
148 | } | ||
149 | } | ||
150 | |||
151 | void setQueryRunner(const QSharedPointer<QObject> &runner) | ||
152 | { | ||
153 | mQueryRunner = runner; | ||
154 | } | ||
155 | |||
156 | private: | ||
157 | void done() | ||
158 | { | ||
159 | qWarning() << "done"; | ||
160 | if (mOnDoneCallback) { | ||
161 | mOnDoneCallback(); | ||
162 | mOnDoneCallback = std::function<void()>(); | ||
163 | } | ||
164 | } | ||
165 | |||
166 | QWeakPointer<ModelResult<T, Ptr> > mModel; | ||
167 | QSharedPointer<QObject> mQueryRunner; | ||
168 | std::shared_ptr<void> mFacade; | ||
169 | std::function<void()> mOnDoneCallback; | ||
170 | }; | ||
171 | |||
172 | /* | 72 | /* |
173 | * The promise side for the result emitter | 73 | * The promise side for the result emitter |
174 | */ | 74 | */ |
@@ -204,6 +104,12 @@ private: | |||
204 | } | 104 | } |
205 | 105 | ||
206 | public: | 106 | public: |
107 | typedef QSharedPointer<ResultProvider<T> > Ptr; | ||
108 | |||
109 | ~ResultProvider() | ||
110 | { | ||
111 | } | ||
112 | |||
207 | //Called from worker thread | 113 | //Called from worker thread |
208 | void add(const T &value) | 114 | void add(const T &value) |
209 | { | 115 | { |
@@ -261,30 +167,16 @@ public: | |||
261 | //We have to go over a separate var and return that, otherwise we'd delete the emitter immediately again | 167 | //We have to go over a separate var and return that, otherwise we'd delete the emitter immediately again |
262 | auto sharedPtr = QSharedPointer<ResultEmitter<T> >(new ResultEmitter<T>, [this](ResultEmitter<T> *emitter){ mThreadBoundary->callInMainThread([this]() {done();}); delete emitter; }); | 168 | auto sharedPtr = QSharedPointer<ResultEmitter<T> >(new ResultEmitter<T>, [this](ResultEmitter<T> *emitter){ mThreadBoundary->callInMainThread([this]() {done();}); delete emitter; }); |
263 | mResultEmitter = sharedPtr; | 169 | mResultEmitter = sharedPtr; |
170 | sharedPtr->setFetcher([this](const T &parent) { | ||
171 | Q_ASSERT(mFetcher); | ||
172 | mFetcher(parent); | ||
173 | }); | ||
264 | return sharedPtr; | 174 | return sharedPtr; |
265 | } | 175 | } |
266 | 176 | ||
267 | return mResultEmitter.toStrongRef(); | 177 | return mResultEmitter.toStrongRef(); |
268 | } | 178 | } |
269 | 179 | ||
270 | /** | ||
271 | * For lifetimemanagement only. | ||
272 | * We keep the runner alive as long as the result provider exists. | ||
273 | */ | ||
274 | void setQueryRunner(const QSharedPointer<QObject> &runner) | ||
275 | { | ||
276 | mQueryRunner = runner; | ||
277 | } | ||
278 | |||
279 | /** | ||
280 | * For lifetimemanagement only. | ||
281 | * We keep the runner alive as long as the result provider exists. | ||
282 | */ | ||
283 | void setFacade(const std::shared_ptr<void> &facade) | ||
284 | { | ||
285 | mFacade = facade; | ||
286 | } | ||
287 | |||
288 | void onDone(const std::function<void()> &callback) | 180 | void onDone(const std::function<void()> &callback) |
289 | { | 181 | { |
290 | mThreadBoundary = QSharedPointer<ThreadBoundary>::create(); | 182 | mThreadBoundary = QSharedPointer<ThreadBoundary>::create(); |
@@ -299,7 +191,7 @@ public: | |||
299 | 191 | ||
300 | void setFetcher(const std::function<void(const T &parent)> &fetcher) | 192 | void setFetcher(const std::function<void(const T &parent)> &fetcher) |
301 | { | 193 | { |
302 | fetcher(T()); | 194 | mFetcher = fetcher; |
303 | } | 195 | } |
304 | 196 | ||
305 | private: | 197 | private: |
@@ -307,16 +199,17 @@ private: | |||
307 | { | 199 | { |
308 | qWarning() << "done"; | 200 | qWarning() << "done"; |
309 | if (mOnDoneCallback) { | 201 | if (mOnDoneCallback) { |
310 | mOnDoneCallback(); | 202 | auto callback = mOnDoneCallback; |
311 | mOnDoneCallback = std::function<void()>(); | 203 | mOnDoneCallback = std::function<void()>(); |
204 | //This may delete this object | ||
205 | callback(); | ||
312 | } | 206 | } |
313 | } | 207 | } |
314 | 208 | ||
315 | QWeakPointer<ResultEmitter<T> > mResultEmitter; | 209 | QWeakPointer<ResultEmitter<T> > mResultEmitter; |
316 | QSharedPointer<QObject> mQueryRunner; | ||
317 | std::shared_ptr<void> mFacade; | ||
318 | std::function<void()> mOnDoneCallback; | 210 | std::function<void()> mOnDoneCallback; |
319 | QSharedPointer<ThreadBoundary> mThreadBoundary; | 211 | QSharedPointer<ThreadBoundary> mThreadBoundary; |
212 | std::function<void(const T &parent)> mFetcher; | ||
320 | }; | 213 | }; |
321 | 214 | ||
322 | /* | 215 | /* |
@@ -334,6 +227,8 @@ private: | |||
334 | template<class DomainType> | 227 | template<class DomainType> |
335 | class ResultEmitter { | 228 | class ResultEmitter { |
336 | public: | 229 | public: |
230 | typedef QSharedPointer<ResultEmitter<DomainType> > Ptr; | ||
231 | |||
337 | void onAdded(const std::function<void(const DomainType&)> &handler) | 232 | void onAdded(const std::function<void(const DomainType&)> &handler) |
338 | { | 233 | { |
339 | addHandler = handler; | 234 | addHandler = handler; |
@@ -394,6 +289,13 @@ public: | |||
394 | clearHandler(); | 289 | clearHandler(); |
395 | } | 290 | } |
396 | 291 | ||
292 | void setFetcher(const std::function<void(const DomainType &parent)> &fetcher) | ||
293 | { | ||
294 | mFetcher = fetcher; | ||
295 | } | ||
296 | |||
297 | std::function<void(const DomainType &parent)> mFetcher; | ||
298 | |||
397 | private: | 299 | private: |
398 | friend class ResultProvider<DomainType>; | 300 | friend class ResultProvider<DomainType>; |
399 | 301 | ||