summaryrefslogtreecommitdiffstats
path: root/async/src
diff options
context:
space:
mode:
Diffstat (limited to 'async/src')
-rw-r--r--async/src/async.cpp10
-rw-r--r--async/src/async.h76
2 files changed, 48 insertions, 38 deletions
diff --git a/async/src/async.cpp b/async/src/async.cpp
index 5c89e53..7e81f24 100644
--- a/async/src/async.cpp
+++ b/async/src/async.cpp
@@ -28,11 +28,18 @@
28 28
29using namespace Async; 29using namespace Async;
30 30
31JobBase::JobBase(JobBase::JobType jobType, JobBase* prev)
32 : mPrev(prev)
33 , mResult(0)
34 , mJobType(jobType)
35{
36}
37
38
31FutureBase::FutureBase() 39FutureBase::FutureBase()
32 : mFinished(false) 40 : mFinished(false)
33 , mWaitLoop(nullptr) 41 , mWaitLoop(nullptr)
34{ 42{
35
36} 43}
37 44
38FutureBase::FutureBase(const Async::FutureBase &other) 45FutureBase::FutureBase(const Async::FutureBase &other)
@@ -65,3 +72,4 @@ void FutureBase::waitForFinished()
65 delete mWaitLoop; 72 delete mWaitLoop;
66 mWaitLoop = 0; 73 mWaitLoop = 0;
67} 74}
75
diff --git a/async/src/async.h b/async/src/async.h
index 3fee450..239927d 100644
--- a/async/src/async.h
+++ b/async/src/async.h
@@ -39,8 +39,8 @@ class JobBase;
39template<typename Out, typename ... In> 39template<typename Out, typename ... In>
40class Job; 40class Job;
41 41
42template<typename Out, typename ... In> 42template<typename Out, typename ... In, typename F>
43Job<Out, In ...> start(const std::function<Async::Future<Out>(In ...)> &func); 43Job<Out, In ...> start(F func);
44 44
45namespace Private 45namespace Private
46{ 46{
@@ -51,9 +51,6 @@ namespace Private
51class JobBase 51class JobBase
52{ 52{
53 template<typename Out, typename ... In> 53 template<typename Out, typename ... In>
54 friend Async::Future<Out>* Private::doExec(Job<Out, In ...> *job, const In & ... args);
55
56 template<typename Out, typename ... In>
57 friend class Job; 54 friend class Job;
58 55
59protected: 56protected:
@@ -63,23 +60,15 @@ protected:
63 }; 60 };
64 61
65public: 62public:
66 JobBase(JobType jobType, JobBase *prev = nullptr) 63 JobBase(JobType jobType, JobBase *prev = nullptr);
67 : mPrev(prev)
68 , mResult(0)
69 , mJobType(jobType)
70 {}
71
72 virtual void exec() = 0; 64 virtual void exec() = 0;
73 65
74protected: 66protected:
75 JobBase *mPrev; 67 JobBase *mPrev;
76 void *mResult; 68 void *mResult;
77
78 JobType mJobType; 69 JobType mJobType;
79}; 70};
80 71
81
82
83template<typename Out, typename ... In> 72template<typename Out, typename ... In>
84class Job : public JobBase 73class Job : public JobBase
85{ 74{
@@ -115,20 +104,7 @@ public:
115 return *reinterpret_cast<Async::Future<Out>*>(mResult); 104 return *reinterpret_cast<Async::Future<Out>*>(mResult);
116 } 105 }
117 106
118 void exec() 107 void exec();
119 {
120 Async::Future<InType> *in = nullptr;
121 if (mPrev) {
122 mPrev->exec();
123 in = reinterpret_cast<Async::Future<InType>*>(mPrev->mResult);
124 assert(in->isFinished());
125 }
126
127 Job<Out, In ...> *job = dynamic_cast<Job<Out, In ...>*>(this);
128 Async::Future<Out> *out = Private::doExec<Out, In ...>(this, in ? in->value() : In() ...);
129 out->waitForFinished();
130 job->mResult = reinterpret_cast<void*>(out);
131 }
132 108
133private: 109private:
134 Job(JobBase::JobType jobType, JobBase *parent = nullptr) 110 Job(JobBase::JobType jobType, JobBase *parent = nullptr)
@@ -137,31 +113,57 @@ private:
137 } 113 }
138 114
139 template<typename F> 115 template<typename F>
140 static Job<Out, In ... > create(F func, JobBase::JobType jobType, JobBase *parent = nullptr) 116 static Job<Out, In ... > create(F func, JobBase::JobType jobType, JobBase *parent = nullptr);
141 {
142 Job<Out, In ...> job(jobType, parent);
143 job.mFunc = func;
144 return job;
145 }
146 117
147public: 118public:
148 std::function<Async::Future<Out>(In ...)> mFunc; 119 std::function<Async::Future<Out>(In ...)> mFunc;
149}; 120};
150 121
122
123} // namespace Async
124
125
126
127// ********** Out of line definitions ****************
128
151template<typename Out, typename ... In, typename F> 129template<typename Out, typename ... In, typename F>
152Job<Out, In ...> start(F func) 130Async::Job<Out, In ...> Async::start(F func)
153{ 131{
154 return Job<Out, In ...>::create(func, JobBase::Then); 132 return Job<Out, In ...>::create(func, JobBase::Then);
155} 133}
156 134
157} // namespace Async
158
159template<typename Out, typename ... In> 135template<typename Out, typename ... In>
160Async::Future<Out>* Async::Private::doExec(Job<Out, In ...> *job, const In & ... args) 136Async::Future<Out>* Async::Private::doExec(Job<Out, In ...> *job, const In & ... args)
161{ 137{
162 return new Async::Future<Out>(job->mFunc(args ...)); 138 return new Async::Future<Out>(job->mFunc(args ...));
163}; 139};
164 140
141template<typename Out, typename ... In>
142void Async::Job<Out, In ...>::exec()
143{
144 Async::Future<InType> *in = nullptr;
145 if (mPrev) {
146 mPrev->exec();
147 in = reinterpret_cast<Async::Future<InType>*>(mPrev->mResult);
148 assert(in->isFinished());
149 }
150
151 Job<Out, In ...> *job = dynamic_cast<Job<Out, In ...>*>(this);
152 Async::Future<Out> *out = Private::doExec<Out, In ...>(this, in ? in->value() : In() ...);
153 out->waitForFinished();
154 job->mResult = reinterpret_cast<void*>(out);
155}
156
157template<typename Out, typename ... In>
158template<typename F>
159Async::Job<Out, In ...> Async::Job<Out, In ...>::create(F func, Async::JobBase::JobType jobType, Async::JobBase* parent)
160{
161 Job<Out, In ...> job(jobType, parent);
162 job.mFunc = func;
163 return job;
164}
165
166
165#endif // ASYNC_H 167#endif // ASYNC_H
166 168
167 169