diff options
author | Christian Mollekopf <chrigi_1@fastmail.fm> | 2015-11-13 19:34:47 +0100 |
---|---|---|
committer | Christian Mollekopf <chrigi_1@fastmail.fm> | 2015-11-13 19:34:47 +0100 |
commit | 09aafbd1373b5d1152ac7a453a140a7f76c2e90e (patch) | |
tree | 10e33196c4dd0d69a223f7b047d1a4ef256e4705 /common/resultprovider.h | |
parent | 10d19014fe2c9c02f2bc3e19732cbe340e316076 (diff) | |
download | sink-09aafbd1373b5d1152ac7a453a140a7f76c2e90e.tar.gz sink-09aafbd1373b5d1152ac7a453a140a7f76c2e90e.zip |
It's starting to work
Diffstat (limited to 'common/resultprovider.h')
-rw-r--r-- | common/resultprovider.h | 303 |
1 files changed, 302 insertions, 1 deletions
diff --git a/common/resultprovider.h b/common/resultprovider.h index bc03152..43d21a4 100644 --- a/common/resultprovider.h +++ b/common/resultprovider.h | |||
@@ -34,11 +34,312 @@ namespace Akonadi2 { | |||
34 | template<class T> | 34 | template<class T> |
35 | class ResultEmitter; | 35 | class ResultEmitter; |
36 | 36 | ||
37 | template<class T> | ||
38 | class ResultProviderInterface | ||
39 | { | ||
40 | public: | ||
41 | ResultProviderInterface() | ||
42 | : mRevision(0) | ||
43 | { | ||
44 | |||
45 | } | ||
46 | |||
47 | virtual void add(const T &value) = 0; | ||
48 | virtual void modify(const T &value) = 0; | ||
49 | virtual void remove(const T &value) = 0; | ||
50 | virtual void initialResultSetComplete() = 0; | ||
51 | virtual void complete() = 0; | ||
52 | virtual void clear() = 0; | ||
53 | virtual void setFetcher(const std::function<void(const QByteArray &parent)> &fetcher) | ||
54 | { | ||
55 | } | ||
56 | |||
57 | virtual void setFacade(const std::shared_ptr<void> &facade) = 0; | ||
58 | virtual void setQueryRunner(const QSharedPointer<QObject> &runner) = 0; | ||
59 | |||
60 | void setRevision(qint64 revision) | ||
61 | { | ||
62 | mRevision = revision; | ||
63 | } | ||
64 | |||
65 | qint64 revision() const | ||
66 | { | ||
67 | return mRevision; | ||
68 | } | ||
69 | |||
70 | private: | ||
71 | qint64 mRevision; | ||
72 | }; | ||
73 | |||
74 | template<class T, class Ptr> | ||
75 | class ModelResultProvider : public ResultProviderInterface<Ptr> { | ||
76 | public: | ||
77 | ModelResultProvider(QWeakPointer<ModelResult<T, Ptr> > model) | ||
78 | : ResultProviderInterface<Ptr>(), | ||
79 | mModel(model) | ||
80 | { | ||
81 | |||
82 | } | ||
83 | |||
84 | void add(const Ptr &value) | ||
85 | { | ||
86 | if (auto model = mModel.toStrongRef()) { | ||
87 | model->add(value); | ||
88 | } | ||
89 | } | ||
90 | |||
91 | void modify(const Ptr &value) | ||
92 | { | ||
93 | if (auto model = mModel.toStrongRef()) { | ||
94 | model->modify(value); | ||
95 | } | ||
96 | } | ||
97 | |||
98 | void remove(const Ptr &value) | ||
99 | { | ||
100 | if (auto model = mModel.toStrongRef()) { | ||
101 | model->remove(value); | ||
102 | } | ||
103 | } | ||
104 | |||
105 | void initialResultSetComplete() | ||
106 | { | ||
107 | // mResultEmitter->initialResultSetComplete(); | ||
108 | } | ||
109 | |||
110 | void complete() | ||
111 | { | ||
112 | // mResultEmitter->complete(); | ||
113 | } | ||
114 | |||
115 | void clear() | ||
116 | { | ||
117 | // mResultEmitter->clear(); | ||
118 | } | ||
119 | |||
120 | // QSharedPointer<ResultEmitter<T> > emitter() | ||
121 | // { | ||
122 | // if (!mResultEmitter) { | ||
123 | // //We have to go over a separate var and return that, otherwise we'd delete the emitter immediately again | ||
124 | // auto sharedPtr = QSharedPointer<ResultEmitter<T> >(new ResultEmitter<T>, [this](ResultEmitter<T> *emitter){ done(); delete emitter; }); | ||
125 | // mResultEmitter = sharedPtr; | ||
126 | // return sharedPtr; | ||
127 | // } | ||
128 | // | ||
129 | // return mResultEmitter.toStrongRef(); | ||
130 | // } | ||
131 | |||
132 | /** | ||
133 | * For lifetimemanagement only. | ||
134 | * We keep the runner alive as long as the result provider exists. | ||
135 | */ | ||
136 | void setFacade(const std::shared_ptr<void> &facade) | ||
137 | { | ||
138 | mFacade = facade; | ||
139 | } | ||
140 | |||
141 | void onDone(const std::function<void()> &callback) | ||
142 | { | ||
143 | mOnDoneCallback = callback; | ||
144 | } | ||
145 | |||
146 | bool isDone() const | ||
147 | { | ||
148 | //The existance of the emitter currently defines wether we're done or not. | ||
149 | // return mResultEmitter.toStrongRef().isNull(); | ||
150 | return true; | ||
151 | } | ||
152 | |||
153 | void setFetcher(const std::function<void(const QByteArray &parent)> &fetcher) | ||
154 | { | ||
155 | if (auto model = mModel.toStrongRef()) { | ||
156 | model->setFetcher(fetcher); | ||
157 | } | ||
158 | } | ||
159 | |||
160 | void setQueryRunner(const QSharedPointer<QObject> &runner) | ||
161 | { | ||
162 | mQueryRunner = runner; | ||
163 | } | ||
164 | |||
165 | // qint64 fetch(const ResultSet &resultSet) | ||
166 | // { | ||
167 | // //Fetch a bunch | ||
168 | // // | ||
169 | // // Akonadi2::Storage storage(Akonadi2::storageLocation(), mResourceInstanceIdentifier); | ||
170 | // // storage.setDefaultErrorHandler([](const Akonadi2::Storage::Error &error) { | ||
171 | // // Warning() << "Error during query: " << error.store << error.message; | ||
172 | // // }); | ||
173 | // // | ||
174 | // // auto transaction = storage.createTransaction(Akonadi2::Storage::ReadOnly); | ||
175 | // | ||
176 | // // Log() << "Querying" << baseRevision << Akonadi2::Storage::maxRevision(transaction); | ||
177 | // // auto resultSet = getResultSet(query, transaction, baseRevision); | ||
178 | // while (resultSet.next([this](const Akonadi2::ApplicationDomain::ApplicationDomainType::Ptr &value, Akonadi2::Operation operation) -> bool { | ||
179 | // switch (operation) { | ||
180 | // case Akonadi2::Operation_Creation: | ||
181 | // Trace() << "Got creation"; | ||
182 | // //TODO Only copy in result provider | ||
183 | // add(Akonadi2::ApplicationDomain::ApplicationDomainType::getInMemoryRepresentation<T>(*value).template staticCast<T>()); | ||
184 | // break; | ||
185 | // case Akonadi2::Operation_Modification: | ||
186 | // Trace() << "Got modification"; | ||
187 | // modify(Akonadi2::ApplicationDomain::ApplicationDomainType::getInMemoryRepresentation<T>(*value).template staticCast<T>()); | ||
188 | // break; | ||
189 | // case Akonadi2::Operation_Removal: | ||
190 | // Trace() << "Got removal"; | ||
191 | // remove(Akonadi2::ApplicationDomain::ApplicationDomainType::getInMemoryRepresentation<T>(*value).template staticCast<T>()); | ||
192 | // break; | ||
193 | // } | ||
194 | // return true; | ||
195 | // })){}; | ||
196 | // // return Akonadi2::Storage::maxRevision(transaction); | ||
197 | // } | ||
198 | |||
199 | private: | ||
200 | void done() | ||
201 | { | ||
202 | qWarning() << "done"; | ||
203 | if (mOnDoneCallback) { | ||
204 | mOnDoneCallback(); | ||
205 | mOnDoneCallback = std::function<void()>(); | ||
206 | } | ||
207 | } | ||
208 | |||
209 | QWeakPointer<ModelResult<T, Ptr> > mModel; | ||
210 | QSharedPointer<QObject> mQueryRunner; | ||
211 | std::shared_ptr<void> mFacade; | ||
212 | std::function<void()> mOnDoneCallback; | ||
213 | }; | ||
214 | |||
215 | |||
216 | |||
217 | |||
218 | |||
219 | |||
220 | template<class T> | ||
221 | class SyncResultProvider : public ResultProviderInterface<T> { | ||
222 | public: | ||
223 | void add(const T &value) | ||
224 | { | ||
225 | mResultEmitter->addHandler(value); | ||
226 | } | ||
227 | |||
228 | void modify(const T &value) | ||
229 | { | ||
230 | mResultEmitter->modifyHandler(value); | ||
231 | } | ||
232 | |||
233 | void remove(const T &value) | ||
234 | { | ||
235 | mResultEmitter->removeHandler(value); | ||
236 | } | ||
237 | |||
238 | void initialResultSetComplete() | ||
239 | { | ||
240 | mResultEmitter->initialResultSetComplete(); | ||
241 | } | ||
242 | |||
243 | void complete() | ||
244 | { | ||
245 | mResultEmitter->complete(); | ||
246 | } | ||
247 | |||
248 | void clear() | ||
249 | { | ||
250 | mResultEmitter->clear(); | ||
251 | } | ||
252 | |||
253 | QSharedPointer<ResultEmitter<T> > emitter() | ||
254 | { | ||
255 | if (!mResultEmitter) { | ||
256 | //We have to go over a separate var and return that, otherwise we'd delete the emitter immediately again | ||
257 | auto sharedPtr = QSharedPointer<ResultEmitter<T> >(new ResultEmitter<T>, [this](ResultEmitter<T> *emitter){ done(); delete emitter; }); | ||
258 | mResultEmitter = sharedPtr; | ||
259 | return sharedPtr; | ||
260 | } | ||
261 | |||
262 | return mResultEmitter.toStrongRef(); | ||
263 | } | ||
264 | |||
265 | /** | ||
266 | * For lifetimemanagement only. | ||
267 | * We keep the runner alive as long as the result provider exists. | ||
268 | */ | ||
269 | void setFacade(const std::shared_ptr<void> &facade) | ||
270 | { | ||
271 | mFacade = facade; | ||
272 | } | ||
273 | |||
274 | void onDone(const std::function<void()> &callback) | ||
275 | { | ||
276 | mOnDoneCallback = callback; | ||
277 | } | ||
278 | |||
279 | bool isDone() const | ||
280 | { | ||
281 | //The existance of the emitter currently defines wether we're done or not. | ||
282 | return mResultEmitter.toStrongRef().isNull(); | ||
283 | } | ||
284 | |||
285 | // qint64 fetch(const ResultSet &resultSet) | ||
286 | // { | ||
287 | // //Fetch a bunch | ||
288 | // // | ||
289 | // // Akonadi2::Storage storage(Akonadi2::storageLocation(), mResourceInstanceIdentifier); | ||
290 | // // storage.setDefaultErrorHandler([](const Akonadi2::Storage::Error &error) { | ||
291 | // // Warning() << "Error during query: " << error.store << error.message; | ||
292 | // // }); | ||
293 | // // | ||
294 | // // auto transaction = storage.createTransaction(Akonadi2::Storage::ReadOnly); | ||
295 | // | ||
296 | // // Log() << "Querying" << baseRevision << Akonadi2::Storage::maxRevision(transaction); | ||
297 | // // auto resultSet = getResultSet(query, transaction, baseRevision); | ||
298 | // while (resultSet.next([this](const Akonadi2::ApplicationDomain::ApplicationDomainType::Ptr &value, Akonadi2::Operation operation) -> bool { | ||
299 | // switch (operation) { | ||
300 | // case Akonadi2::Operation_Creation: | ||
301 | // Trace() << "Got creation"; | ||
302 | // //TODO Only copy in result provider | ||
303 | // add(Akonadi2::ApplicationDomain::ApplicationDomainType::getInMemoryRepresentation<T>(*value).template staticCast<T>()); | ||
304 | // break; | ||
305 | // case Akonadi2::Operation_Modification: | ||
306 | // Trace() << "Got modification"; | ||
307 | // modify(Akonadi2::ApplicationDomain::ApplicationDomainType::getInMemoryRepresentation<T>(*value).template staticCast<T>()); | ||
308 | // break; | ||
309 | // case Akonadi2::Operation_Removal: | ||
310 | // Trace() << "Got removal"; | ||
311 | // remove(Akonadi2::ApplicationDomain::ApplicationDomainType::getInMemoryRepresentation<T>(*value).template staticCast<T>()); | ||
312 | // break; | ||
313 | // } | ||
314 | // return true; | ||
315 | // })){}; | ||
316 | // // return Akonadi2::Storage::maxRevision(transaction); | ||
317 | // } | ||
318 | |||
319 | private: | ||
320 | void done() | ||
321 | { | ||
322 | qWarning() << "done"; | ||
323 | if (mOnDoneCallback) { | ||
324 | mOnDoneCallback(); | ||
325 | mOnDoneCallback = std::function<void()>(); | ||
326 | } | ||
327 | } | ||
328 | |||
329 | QWeakPointer<ResultEmitter<T> > mResultEmitter; | ||
330 | std::shared_ptr<void> mFacade; | ||
331 | std::function<void()> mOnDoneCallback; | ||
332 | QSharedPointer<ThreadBoundary> mThreadBoundary; | ||
333 | }; | ||
334 | |||
335 | |||
336 | |||
337 | |||
37 | /* | 338 | /* |
38 | * The promise side for the result emitter | 339 | * The promise side for the result emitter |
39 | */ | 340 | */ |
40 | template<class T> | 341 | template<class T> |
41 | class ResultProvider { | 342 | class ResultProvider : public ResultProviderInterface<T> { |
42 | private: | 343 | private: |
43 | void callInMainThreadOnEmitter(void (ResultEmitter<T>::*f)()) | 344 | void callInMainThreadOnEmitter(void (ResultEmitter<T>::*f)()) |
44 | { | 345 | { |