summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--client/clientapi.h45
-rw-r--r--client/test/clientapitest.cpp12
2 files changed, 48 insertions, 9 deletions
diff --git a/client/clientapi.h b/client/clientapi.h
index 592fa48..662f96c 100644
--- a/client/clientapi.h
+++ b/client/clientapi.h
@@ -6,6 +6,7 @@
6#include <QStandardPaths> 6#include <QStandardPaths>
7#include <QTimer> 7#include <QTimer>
8#include <QDebug> 8#include <QDebug>
9#include <QEventLoop>
9#include <functional> 10#include <functional>
10 11
11namespace async { 12namespace async {
@@ -64,6 +65,14 @@ namespace async {
64 * The future side for the client. 65 * The future side for the client.
65 * 66 *
66 * It does not directly hold the state. 67 * It does not directly hold the state.
68 *
69 * The advantage of this is that we can specialize it to:
70 * * do inline transformations to the data
71 * * directly store the state in a suitable datastructure: QList, QSet, std::list, QVector, ...
72 * * build async interfaces with signals
73 * * build sync interfaces that block when accessing the value
74 *
75 * TODO: This should probably be merged with daniels futurebase used in Async
67 */ 76 */
68 template<class DomainType> 77 template<class DomainType>
69 class ResultEmitter { 78 class ResultEmitter {
@@ -85,6 +94,42 @@ namespace async {
85 std::function<void(void)> completeHandler; 94 std::function<void(void)> completeHandler;
86 }; 95 };
87 96
97
98 /*
99 * A result set specialization that provides a syncronous list
100 */
101 template<class T>
102 class SyncListResult : public QList<T> {
103 public:
104 SyncListResult(const QSharedPointer<ResultEmitter<T> > &emitter)
105 :QList<T>(),
106 mComplete(false),
107 mEmitter(emitter)
108 {
109 emitter->onAdded([this](const T &value) {
110 this->append(value);
111 });
112 emitter->onComplete([this]() {
113 mComplete = true;
114 auto loop = mWaitLoop.toStrongRef();
115 if (loop) {
116 loop->quit();
117 }
118 });
119 }
120
121 void exec()
122 {
123 auto loop = QSharedPointer<QEventLoop>::create();
124 mWaitLoop = loop;
125 loop->exec(QEventLoop::ExcludeUserInputEvents);
126 }
127
128 private:
129 bool mComplete;
130 QWeakPointer<QEventLoop> mWaitLoop;
131 QSharedPointer<ResultEmitter<T> > mEmitter;
132 };
88} 133}
89 134
90namespace Akonadi2 { 135namespace Akonadi2 {
diff --git a/client/test/clientapitest.cpp b/client/test/clientapitest.cpp
index bff910b..2d1c238 100644
--- a/client/test/clientapitest.cpp
+++ b/client/test/clientapitest.cpp
@@ -37,15 +37,9 @@ private Q_SLOTS:
37 Akonadi2::Query query; 37 Akonadi2::Query query;
38 query.resources << "dummyresource"; 38 query.resources << "dummyresource";
39 39
40 auto result = Akonadi2::Store::load<Akonadi2::Domain::Event>(query); 40 async::SyncListResult<Akonadi2::Domain::Event::Ptr> result(Akonadi2::Store::load<Akonadi2::Domain::Event>(query));
41 41 result.exec();
42 QList<Akonadi2::Domain::Event::Ptr> resultSet; 42 QCOMPARE(result.size(), 1);
43 result->onAdded([&resultSet](const Akonadi2::Domain::Event::Ptr &event){ resultSet << event; qDebug() << "result added";});
44
45 bool complete;
46 result->onComplete([&complete]{ complete = true; qDebug() << "complete";});
47
48 QTRY_VERIFY(complete);
49 } 43 }
50 44
51}; 45};