summaryrefslogtreecommitdiffstats
path: root/common/resultprovider.h
diff options
context:
space:
mode:
authorChristian Mollekopf <chrigi_1@fastmail.fm>2016-03-03 09:01:05 +0100
committerChristian Mollekopf <chrigi_1@fastmail.fm>2016-03-03 09:01:05 +0100
commit4d9746c828558c9f872e0aed52442863affb25d5 (patch)
tree507d7c2ba67f47d3cbbcf01a722236ff1b48426b /common/resultprovider.h
parent9cea920b7dd51867a0be0fed2f461b6be73c103e (diff)
downloadsink-4d9746c828558c9f872e0aed52442863affb25d5.tar.gz
sink-4d9746c828558c9f872e0aed52442863affb25d5.zip
Fromatted the whole codebase with clang-format.
clang-format -i */**{.cpp,.h}
Diffstat (limited to 'common/resultprovider.h')
-rw-r--r--common/resultprovider.h124
1 files changed, 56 insertions, 68 deletions
diff --git a/common/resultprovider.h b/common/resultprovider.h
index 2d6efbe..5561ff2 100644
--- a/common/resultprovider.h
+++ b/common/resultprovider.h
@@ -32,22 +32,19 @@ namespace Sink {
32/** 32/**
33* Query result set 33* Query result set
34*/ 34*/
35template<class T> 35template <class T>
36class ResultEmitter; 36class ResultEmitter;
37 37
38template<class T> 38template <class T>
39class ResultProviderInterface 39class ResultProviderInterface
40{ 40{
41public: 41public:
42 ResultProviderInterface() 42 ResultProviderInterface() : mRevision(0)
43 : mRevision(0)
44 { 43 {
45
46 } 44 }
47 45
48 virtual ~ResultProviderInterface() 46 virtual ~ResultProviderInterface()
49 { 47 {
50
51 } 48 }
52 49
53 virtual void add(const T &value) = 0; 50 virtual void add(const T &value) = 0;
@@ -75,17 +72,18 @@ private:
75/* 72/*
76* The promise side for the result emitter 73* The promise side for the result emitter
77*/ 74*/
78template<class T> 75template <class T>
79class ResultProvider : public ResultProviderInterface<T> { 76class ResultProvider : public ResultProviderInterface<T>
77{
80private: 78private:
81 void callInMainThreadOnEmitter(void (ResultEmitter<T>::*f)()) 79 void callInMainThreadOnEmitter(void (ResultEmitter<T>::*f)())
82 { 80 {
83 //We use the eventloop to call the addHandler directly from the main eventloop. 81 // We use the eventloop to call the addHandler directly from the main eventloop.
84 //That way the result emitter implementation doesn't have to care about threadsafety at all. 82 // That way the result emitter implementation doesn't have to care about threadsafety at all.
85 //The alternative would be to make all handlers of the emitter threadsafe. 83 // The alternative would be to make all handlers of the emitter threadsafe.
86 if (auto emitter = mResultEmitter.toStrongRef()) { 84 if (auto emitter = mResultEmitter.toStrongRef()) {
87 auto weakEmitter = mResultEmitter; 85 auto weakEmitter = mResultEmitter;
88 //We don't want to keep the emitter alive here, so we only capture a weak reference 86 // We don't want to keep the emitter alive here, so we only capture a weak reference
89 emitter->mThreadBoundary.callInMainThread([weakEmitter, f]() { 87 emitter->mThreadBoundary.callInMainThread([weakEmitter, f]() {
90 if (auto strongRef = weakEmitter.toStrongRef()) { 88 if (auto strongRef = weakEmitter.toStrongRef()) {
91 (strongRef.data()->*f)(); 89 (strongRef.data()->*f)();
@@ -96,27 +94,27 @@ private:
96 94
97 void callInMainThreadOnEmitter(const std::function<void()> &f) 95 void callInMainThreadOnEmitter(const std::function<void()> &f)
98 { 96 {
99 //We use the eventloop to call the addHandler directly from the main eventloop. 97 // We use the eventloop to call the addHandler directly from the main eventloop.
100 //That way the result emitter implementation doesn't have to care about threadsafety at all. 98 // That way the result emitter implementation doesn't have to care about threadsafety at all.
101 //The alternative would be to make all handlers of the emitter threadsafe. 99 // The alternative would be to make all handlers of the emitter threadsafe.
102 if (auto emitter = mResultEmitter.toStrongRef()) { 100 if (auto emitter = mResultEmitter.toStrongRef()) {
103 emitter->mThreadBoundary.callInMainThread(f); 101 emitter->mThreadBoundary.callInMainThread(f);
104 } 102 }
105 } 103 }
106 104
107public: 105public:
108 typedef QSharedPointer<ResultProvider<T> > Ptr; 106 typedef QSharedPointer<ResultProvider<T>> Ptr;
109 107
110 virtual ~ResultProvider() 108 virtual ~ResultProvider()
111 { 109 {
112 } 110 }
113 111
114 //Called from worker thread 112 // Called from worker thread
115 void add(const T &value) 113 void add(const T &value)
116 { 114 {
117 //Because I don't know how to use bind 115 // Because I don't know how to use bind
118 auto weakEmitter = mResultEmitter; 116 auto weakEmitter = mResultEmitter;
119 callInMainThreadOnEmitter([weakEmitter, value](){ 117 callInMainThreadOnEmitter([weakEmitter, value]() {
120 if (auto strongRef = weakEmitter.toStrongRef()) { 118 if (auto strongRef = weakEmitter.toStrongRef()) {
121 strongRef->addHandler(value); 119 strongRef->addHandler(value);
122 } 120 }
@@ -125,9 +123,9 @@ public:
125 123
126 void modify(const T &value) 124 void modify(const T &value)
127 { 125 {
128 //Because I don't know how to use bind 126 // Because I don't know how to use bind
129 auto weakEmitter = mResultEmitter; 127 auto weakEmitter = mResultEmitter;
130 callInMainThreadOnEmitter([weakEmitter, value](){ 128 callInMainThreadOnEmitter([weakEmitter, value]() {
131 if (auto strongRef = weakEmitter.toStrongRef()) { 129 if (auto strongRef = weakEmitter.toStrongRef()) {
132 strongRef->modifyHandler(value); 130 strongRef->modifyHandler(value);
133 } 131 }
@@ -136,9 +134,9 @@ public:
136 134
137 void remove(const T &value) 135 void remove(const T &value)
138 { 136 {
139 //Because I don't know how to use bind 137 // Because I don't know how to use bind
140 auto weakEmitter = mResultEmitter; 138 auto weakEmitter = mResultEmitter;
141 callInMainThreadOnEmitter([weakEmitter, value](){ 139 callInMainThreadOnEmitter([weakEmitter, value]() {
142 if (auto strongRef = weakEmitter.toStrongRef()) { 140 if (auto strongRef = weakEmitter.toStrongRef()) {
143 strongRef->removeHandler(value); 141 strongRef->removeHandler(value);
144 } 142 }
@@ -147,16 +145,16 @@ public:
147 145
148 void initialResultSetComplete(const T &parent) 146 void initialResultSetComplete(const T &parent)
149 { 147 {
150 //Because I don't know how to use bind 148 // Because I don't know how to use bind
151 auto weakEmitter = mResultEmitter; 149 auto weakEmitter = mResultEmitter;
152 callInMainThreadOnEmitter([weakEmitter, parent](){ 150 callInMainThreadOnEmitter([weakEmitter, parent]() {
153 if (auto strongRef = weakEmitter.toStrongRef()) { 151 if (auto strongRef = weakEmitter.toStrongRef()) {
154 strongRef->initialResultSetComplete(parent); 152 strongRef->initialResultSetComplete(parent);
155 } 153 }
156 }); 154 });
157 } 155 }
158 156
159 //Called from worker thread 157 // Called from worker thread
160 void complete() 158 void complete()
161 { 159 {
162 callInMainThreadOnEmitter(&ResultEmitter<T>::complete); 160 callInMainThreadOnEmitter(&ResultEmitter<T>::complete);
@@ -168,11 +166,14 @@ public:
168 } 166 }
169 167
170 168
171 QSharedPointer<ResultEmitter<T> > emitter() 169 QSharedPointer<ResultEmitter<T>> emitter()
172 { 170 {
173 if (!mResultEmitter) { 171 if (!mResultEmitter) {
174 //We have to go over a separate var and return that, otherwise we'd delete the emitter immediately again 172 // We have to go over a separate var and return that, otherwise we'd delete the emitter immediately again
175 auto sharedPtr = QSharedPointer<ResultEmitter<T> >(new ResultEmitter<T>, [this](ResultEmitter<T> *emitter){ mThreadBoundary->callInMainThread([this]() {done();}); delete emitter; }); 173 auto sharedPtr = QSharedPointer<ResultEmitter<T>>(new ResultEmitter<T>, [this](ResultEmitter<T> *emitter) {
174 mThreadBoundary->callInMainThread([this]() { done(); });
175 delete emitter;
176 });
176 mResultEmitter = sharedPtr; 177 mResultEmitter = sharedPtr;
177 sharedPtr->setFetcher([this](const T &parent) { 178 sharedPtr->setFetcher([this](const T &parent) {
178 Q_ASSERT(mFetcher); 179 Q_ASSERT(mFetcher);
@@ -192,7 +193,7 @@ public:
192 193
193 bool isDone() const 194 bool isDone() const
194 { 195 {
195 //The existance of the emitter currently defines wether we're done or not. 196 // The existance of the emitter currently defines wether we're done or not.
196 return mResultEmitter.toStrongRef().isNull(); 197 return mResultEmitter.toStrongRef().isNull();
197 } 198 }
198 199
@@ -208,12 +209,12 @@ private:
208 if (mOnDoneCallback) { 209 if (mOnDoneCallback) {
209 auto callback = mOnDoneCallback; 210 auto callback = mOnDoneCallback;
210 mOnDoneCallback = std::function<void()>(); 211 mOnDoneCallback = std::function<void()>();
211 //This may delete this object 212 // This may delete this object
212 callback(); 213 callback();
213 } 214 }
214 } 215 }
215 216
216 QWeakPointer<ResultEmitter<T> > mResultEmitter; 217 QWeakPointer<ResultEmitter<T>> mResultEmitter;
217 std::function<void()> mOnDoneCallback; 218 std::function<void()> mOnDoneCallback;
218 QSharedPointer<async::ThreadBoundary> mThreadBoundary; 219 QSharedPointer<async::ThreadBoundary> mThreadBoundary;
219 std::function<void(const T &parent)> mFetcher; 220 std::function<void(const T &parent)> mFetcher;
@@ -231,32 +232,32 @@ private:
231* * build sync interfaces that block when accessing the value 232* * build sync interfaces that block when accessing the value
232* 233*
233*/ 234*/
234template<class DomainType> 235template <class DomainType>
235class ResultEmitter { 236class ResultEmitter
237{
236public: 238public:
237 typedef QSharedPointer<ResultEmitter<DomainType> > Ptr; 239 typedef QSharedPointer<ResultEmitter<DomainType>> Ptr;
238 240
239 virtual ~ResultEmitter() 241 virtual ~ResultEmitter()
240 { 242 {
241
242 } 243 }
243 244
244 void onAdded(const std::function<void(const DomainType&)> &handler) 245 void onAdded(const std::function<void(const DomainType &)> &handler)
245 { 246 {
246 addHandler = handler; 247 addHandler = handler;
247 } 248 }
248 249
249 void onModified(const std::function<void(const DomainType&)> &handler) 250 void onModified(const std::function<void(const DomainType &)> &handler)
250 { 251 {
251 modifyHandler = handler; 252 modifyHandler = handler;
252 } 253 }
253 254
254 void onRemoved(const std::function<void(const DomainType&)> &handler) 255 void onRemoved(const std::function<void(const DomainType &)> &handler)
255 { 256 {
256 removeHandler = handler; 257 removeHandler = handler;
257 } 258 }
258 259
259 void onInitialResultSetComplete(const std::function<void(const DomainType&)> &handler) 260 void onInitialResultSetComplete(const std::function<void(const DomainType &)> &handler)
260 { 261 {
261 initialResultSetCompleteHandler = handler; 262 initialResultSetCompleteHandler = handler;
262 } 263 }
@@ -322,10 +323,10 @@ public:
322private: 323private:
323 friend class ResultProvider<DomainType>; 324 friend class ResultProvider<DomainType>;
324 325
325 std::function<void(const DomainType&)> addHandler; 326 std::function<void(const DomainType &)> addHandler;
326 std::function<void(const DomainType&)> modifyHandler; 327 std::function<void(const DomainType &)> modifyHandler;
327 std::function<void(const DomainType&)> removeHandler; 328 std::function<void(const DomainType &)> removeHandler;
328 std::function<void(const DomainType&)> initialResultSetCompleteHandler; 329 std::function<void(const DomainType &)> initialResultSetCompleteHandler;
329 std::function<void(void)> completeHandler; 330 std::function<void(void)> completeHandler;
330 std::function<void(void)> clearHandler; 331 std::function<void(void)> clearHandler;
331 332
@@ -333,37 +334,28 @@ private:
333 async::ThreadBoundary mThreadBoundary; 334 async::ThreadBoundary mThreadBoundary;
334}; 335};
335 336
336template<class DomainType> 337template <class DomainType>
337class AggregatingResultEmitter : public ResultEmitter<DomainType> { 338class AggregatingResultEmitter : public ResultEmitter<DomainType>
339{
338public: 340public:
339 typedef QSharedPointer<AggregatingResultEmitter<DomainType> > Ptr; 341 typedef QSharedPointer<AggregatingResultEmitter<DomainType>> Ptr;
340 342
341 void addEmitter(const typename ResultEmitter<DomainType>::Ptr &emitter) 343 void addEmitter(const typename ResultEmitter<DomainType>::Ptr &emitter)
342 { 344 {
343 emitter->onAdded([this](const DomainType &value) { 345 emitter->onAdded([this](const DomainType &value) { this->add(value); });
344 this->add(value); 346 emitter->onModified([this](const DomainType &value) { this->modify(value); });
345 }); 347 emitter->onRemoved([this](const DomainType &value) { this->remove(value); });
346 emitter->onModified([this](const DomainType &value) {
347 this->modify(value);
348 });
349 emitter->onRemoved([this](const DomainType &value) {
350 this->remove(value);
351 });
352 auto ptr = emitter.data(); 348 auto ptr = emitter.data();
353 emitter->onInitialResultSetComplete([this, ptr](const DomainType &parent) { 349 emitter->onInitialResultSetComplete([this, ptr](const DomainType &parent) {
354 auto hashValue = qHash(parent); 350 auto hashValue = qHash(parent);
355 mInitialResultSetInProgress.remove(hashValue, ptr); 351 mInitialResultSetInProgress.remove(hashValue, ptr);
356 //Normally a parent is only in a single resource, except the toplevel (invalid) parent 352 // Normally a parent is only in a single resource, except the toplevel (invalid) parent
357 if (!mInitialResultSetInProgress.contains(hashValue)) { 353 if (!mInitialResultSetInProgress.contains(hashValue)) {
358 this->initialResultSetComplete(parent); 354 this->initialResultSetComplete(parent);
359 } 355 }
360 }); 356 });
361 emitter->onComplete([this]() { 357 emitter->onComplete([this]() { this->complete(); });
362 this->complete(); 358 emitter->onClear([this]() { this->clear(); });
363 });
364 emitter->onClear([this]() {
365 this->clear();
366 });
367 mEmitter << emitter; 359 mEmitter << emitter;
368 } 360 }
369 361
@@ -382,10 +374,6 @@ public:
382 374
383private: 375private:
384 QList<typename ResultEmitter<DomainType>::Ptr> mEmitter; 376 QList<typename ResultEmitter<DomainType>::Ptr> mEmitter;
385 QMultiMap<qint64, ResultEmitter<DomainType>*> mInitialResultSetInProgress; 377 QMultiMap<qint64, ResultEmitter<DomainType> *> mInitialResultSetInProgress;
386}; 378};
387
388
389
390} 379}
391