- Aldebaran documentation |
- C++ Libraries |
- index

libqi-api 2.8.7.4

- Main Page
- Related Pages
- Namespaces
- Classes
- Files
- Examples

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
executioncontext.hpp
Go to the documentation of this file.
1 #pragma once
2 /*
3 ** Copyright (C) 2012 Aldebaran Robotics
4 ** See COPYING for the license
5 */
6
7 #ifndef _QI_EXECUTION_CONTEXT_HPP_
8 #define _QI_EXECUTION_CONTEXT_HPP_
9
10 #include <type_traits>
11 #include <boost/function.hpp>
12 #include <qi/api.hpp>
13 #include <qi/clock.hpp>
14 #include <ka/typetraits.hpp>
15
16 namespace qi
17 {
18
19 template <typename T>
20 class Future;
21
22 namespace detail
23 {
24
25 // This class is kind of a hack to deprecate the old versions of async/post etc without deprecating the correct use of
26 // the new ones. This class is just a strong alias to boost::function
27 template <typename T>
28 struct Function : boost::function<T>
29 {
30 template<class Arg>
31 Function(Arg&& arg,
32 typename std::enable_if<!std::is_same<typename std::decay<Arg>::type, Function>::value>::type* = nullptr)
33 : boost::function<T>(std::forward<Arg>(arg))
34 {}
35
36 Function(const Function&) = default;
37 };
38
39 }
40
41 enum class CancelOption
42 { AllowSkipExecution
43 , AlwaysSkipExecution
44 , NeverSkipExecution
45 };
46
48 struct ExecutionOptions
49 {
53 CancelOption onCancelRequested;
54 };
55
56 BOOST_CONSTEXPR
57 inline ExecutionOptions defaultExecutionOptions() BOOST_NOEXCEPT
58 {
59 return { CancelOption::AllowSkipExecution };
60 }
61
62
63 class QI_API ExecutionContext
64 {
65 public:
66 virtual ~ExecutionContext() {}
67
68 // DEPRECATED STUFF
71 QI_API_DEPRECATED_MSG(Use 'asyncAt' instead)
72 virtual qi::Future<void> async(const boost::function<void()>& callback, qi::SteadyClockTimePoint tp) = 0;
75 QI_API_DEPRECATED_MSG(Use 'asyncDelay' instead)
76 virtual qi::Future<void> async(const boost::function<void()>& callback, qi::Duration delay) = 0;
77
80 template <typename R>
81 QI_API_DEPRECATED_MSG(Use 'asyncDelay' instead)
82 typename boost::disable_if<std::is_same<R, void>, qi::Future<R> >::type
83 async(const boost::function<R()>& callback, qi::Duration delay);
86 template <typename R>
87 QI_API_DEPRECATED_MSG(Use 'asyncAt' instead)
88 typename boost::disable_if<std::is_same<R, void>, qi::Future<R> >::type
89 async(const boost::function<R()>& callback, qi::SteadyClockTimePoint tp);
90
92 template <typename R>
93 QI_API_DEPRECATED_MSG(Use 'async' without explicit return type template arguement instead)
94 qi::Future<R> async(const detail::Function<R()>& callback)
95 {
96 return asyncDelay(callback, qi::Duration(0));
97 }
98 // END OF DEPRECATED STUFF
99
101 template <typename F>
102 void post(F&& callback, ExecutionOptions options = defaultExecutionOptions());
103
105 template <typename F, typename R = ka::Decay<decltype(std::declval<F>()())>>
106 qi::Future<R> asyncAt(F&& callback, qi::SteadyClockTimePoint tp, ExecutionOptions options = defaultExecutionOptions());
108 template <typename F, typename R = ka::Decay<decltype(std::declval<F>()())>>
109 qi::Future<R> asyncDelay(F&& callback, qi::Duration delay, ExecutionOptions options = defaultExecutionOptions());
110
111 template <typename F>
112 auto async(F&& callback, ExecutionOptions options = defaultExecutionOptions())
113 -> decltype(asyncDelay(std::forward<F>(callback), qi::Duration(0), options))
114 {
115 return asyncDelay(std::forward<F>(callback), qi::Duration(0), options);
116 }
117
119 virtual bool isInThisContext() const = 0;
120
121 protected:
122 virtual void postImpl(boost::function<void()> callback, ExecutionOptions options) = 0;
123 virtual qi::Future<void> asyncAtImpl(boost::function<void()> cb, qi::SteadyClockTimePoint tp, ExecutionOptions options) = 0;
124 virtual qi::Future<void> asyncDelayImpl(boost::function<void()> cb, qi::Duration delay, ExecutionOptions options) = 0;
125 };
126
127 }
128
129 #include <qi/detail/future_fwd.hpp>
130
131 namespace qi
132 {
133
134 namespace detail
135 {
136
137 template <typename T>
138 class DelayedPromise: public Promise<T>
139 {
140 public:
141 void setup(boost::function<void (qi::Promise<T>)> cancelCallback, FutureCallbackType async = FutureCallbackType_Async)
142 {
143 Promise<T>::setup(cancelCallback, async);
144 }
145 };
146
147 template <typename R>
148 void setValue(qi::Promise<R>& p, const boost::function<R()>& f)
149 {
150 p.setValue(f());
151 }
152
153 template <>
154 inline void setValue<void>(qi::Promise<void>& p, const boost::function<void()>& f)
155 {
156 f();
157 p.setValue(0);
158 }
159
160 template <typename R>
161 void callAndSet(qi::Promise<R> p, boost::function<R()> f)
162 {
163 try
164 {
165 setValue<R>(p, f);
166 }
167 catch (const std::exception& e)
168 {
169 p.setError(e.what());
170 }
171 catch(...)
172 {
173 p.setError("unknown exception");
174 }
175 }
176 template <typename R>
177 void forwardError(qi::Future<void> f, qi::Promise<R> p)
178 {
179 switch (f.wait())
180 {
181 case FutureState_Canceled: p.setCanceled(); break;
182 case FutureState_FinishedWithError: p.setError(f.error()); break;
183 case FutureState_None: // Nothing to do for these states.
184 case FutureState_Running:
185 case FutureState_FinishedWithValue: break;
186 }
187 }
188
189 }
190
191 template <typename R>
192 typename boost::disable_if<std::is_same<R, void>,
193 qi::Future<R> >::type
194 ExecutionContext::async(const boost::function<R()>& callback,
195 qi::Duration delay)
196 {
197 detail::DelayedPromise<R> promise;
198 qi::Future<void> f = async(boost::function<void()>(boost::bind(
199 detail::callAndSet<R>, promise, callback)),
200 delay);
201 promise.setup(
202 boost::bind(&detail::futureCancelAdapter<void>,
203 boost::weak_ptr<detail::FutureBaseTyped<void> >(f.impl())));
204 f.connect(boost::bind(&detail::forwardError<R>, _1, promise), FutureCallbackType_Sync);
205 return promise.future();
206 }
207
208 template <typename R>
209 typename boost::disable_if<std::is_same<R, void>,
210 qi::Future<R> >::type
211 ExecutionContext::async(const boost::function<R()>& callback,
212 qi::SteadyClockTimePoint tp)
213 {
214 detail::DelayedPromise<R> promise;
215 qi::Future<void> f = async(boost::function<void()>(boost::bind(
216 detail::callAndSet<R>, promise, callback)),
217 tp);
218 promise.setup(
219 boost::bind(&detail::futureCancelAdapter<void>,
220 boost::weak_ptr<detail::FutureBaseTyped<void> >(f.impl())));
221 f.connect(boost::bind(&detail::forwardError<R>, _1, promise), FutureCallbackType_Sync);
222 return promise.future();
223 }
224
225 template <typename F>
226 void ExecutionContext::post(F&& callback, ExecutionOptions options)
227 {
228 postImpl(std::forward<F>(callback), options);
229 }
230
231 template <typename ReturnType, typename Callback>
232 struct ToPost
233 {
234 detail::DelayedPromise<ReturnType> promise;
235 Callback callback;
236
237 ToPost(Callback cb) :
238 callback(std::move(cb))
239 {}
240
241 void operator()()
242 {
243 detail::callAndSet<ReturnType>(std::move(promise), std::move(callback));
244 }
245 };
246
247 template <typename F, typename R>
248 Future<R> ExecutionContext::asyncAt(F&& callback, qi::SteadyClockTimePoint tp, ExecutionOptions options)
249 {
250 ToPost<R, typename std::decay<F>::type> topost(std::forward<F>(callback));
251 auto promise = topost.promise;
252 qi::Future<void> f = asyncAtImpl(std::move(topost), tp, options);
253 promise.setup(boost::bind(&detail::futureCancelAdapter<void>,
254 boost::weak_ptr<detail::FutureBaseTyped<void> >(f.impl())));
255 f.connect(boost::bind(&detail::forwardError<R>, _1, promise), FutureCallbackType_Sync);
256 return promise.future();
257 }
258
259 template <typename F, typename R>
260 Future<R> ExecutionContext::asyncDelay(F&& callback, qi::Duration delay, ExecutionOptions options)
261 {
262 ToPost<R, typename std::decay<F>::type> topost(std::forward<F>(callback));
263 auto promise = topost.promise;
264 qi::Future<void> f = asyncDelayImpl(std::move(topost), delay, options);
265 promise.setup(boost::bind(&detail::futureCancelAdapter<void>,
266 boost::weak_ptr<detail::FutureBaseTyped<void> >(f.impl())));
267 f.connect(boost::bind(&detail::forwardError<R>, _1, promise), FutureCallbackType_Sync);
268 return promise.future();
269 }
270 }
271
272 #endif
qi::detail::setValue
void setValue(qi::Promise< R > &p, const boost::function< R()> &f)
Definition: executioncontext.hpp:148
qi::detail::DelayedPromise::setup
void setup(boost::function< void(qi::Promise< T >)> cancelCallback, FutureCallbackType async=FutureCallbackType_Async)
Definition: executioncontext.hpp:141
qi::ToPost::promise
detail::DelayedPromise< ReturnType > promise
Definition: executioncontext.hpp:234
qi::asyncDelay
auto asyncDelay(F &&callback, qi::Duration delay) -> decltype(detail::asyncMaybeActor(std::forward< F >(callback), delay))
Definition: async.hpp:46
qi::detail::setValue< void >
void setValue< void >(qi::Promise< void > &p, const boost::function< void()> &f)
Definition: executioncontext.hpp:154
qi::Promise::setup
void setup(boost::function< void(qi::Promise< T > &)> cancelCallback, FutureCallbackType async=FutureCallbackType_Auto)
Definition: future_fwd.hpp:915
qi::Future::connect
void connect(const AF &fun, FutureCallbackType type=FutureCallbackType_Auto)
Definition: future_fwd.hpp:545
qi::defaultExecutionOptions
BOOST_CONSTEXPR ExecutionOptions defaultExecutionOptions() BOOST_NOEXCEPT
Definition: executioncontext.hpp:57
qi::FutureState_Canceled
The future has been canceled.
Definition: future_fwd.hpp:85
QI_API
#define QI_API
Definition: api.hpp:33
qi::CancelOption::AlwaysSkipExecution
... the execution context must not execute the task.
qi::Future
Definition: executioncontext.hpp:20
qi::SteadyClockTimePoint
SteadyClock::time_point SteadyClockTimePoint
Steady clock time point.
Definition: clock.hpp:211
qi::ExecutionOptions::onCancelRequested
CancelOption onCancelRequested
Definition: executioncontext.hpp:53
qi::ExecutionContext::asyncAtImpl
virtual qi::Future< void > asyncAtImpl(boost::function< void()> cb, qi::SteadyClockTimePoint tp, ExecutionOptions options)=0
qi::ExecutionContext::async
virtual qi::Future< void > async(const boost::function< void()> &callback, qi::SteadyClockTimePoint tp)=0
qi::Promise::setError
void setError(const std::string &msg)
Definition: future_fwd.hpp:862
qi::ExecutionContext::postImpl
virtual void postImpl(boost::function< void()> callback, ExecutionOptions options)=0
qi::ExecutionContext
Definition: executioncontext.hpp:63
qi::detail::Function::Function
Function(Arg &&arg, typename std::enable_if<!std::is_same< typename std::decay< Arg >::type, Function >::value >::type *=nullptr)
Definition: executioncontext.hpp:31
api.hpp
dll import/export and compiler message
qi::CancelOption::NeverSkipExecution
... the executino context must still execute the task.
qi::ExecutionContext::asyncDelay
qi::Future< R > asyncDelay(F &&callback, qi::Duration delay, ExecutionOptions options=defaultExecutionOptions())
call a callback asynchronously to be executed in delay
qi::Duration
NanoSeconds Duration
Definition: clock.hpp:32
qi::detail::forwardError
void forwardError(qi::Future< void > f, qi::Promise< R > p)
Definition: executioncontext.hpp:177
qi::detail::callAndSet
void callAndSet(qi::Promise< R > p, boost::function< R()> f)
Definition: executioncontext.hpp:161
qi::ExecutionContext::asyncDelayImpl
virtual qi::Future< void > asyncDelayImpl(boost::function< void()> cb, qi::Duration delay, ExecutionOptions options)=0
qi::Promise::future
Future< T > future() const
Get a future linked to this promise. Can be called multiple times.
Definition: future_fwd.hpp:881
qi::ToPost::ToPost
ToPost(Callback cb)
Definition: executioncontext.hpp:237
qi::CancelOption
CancelOption
< If cancel have been requested for the associated scheduled task...
Definition: executioncontext.hpp:41
qi::detail::Function
Definition: executioncontext.hpp:28
qi::CancelOption::AllowSkipExecution
... allow the execution context to not execute the task.
qi::FutureState_None
Future is not tied to a promise.
Definition: future_fwd.hpp:83
qi::ExecutionContext::async
auto async(F &&callback, ExecutionOptions options=defaultExecutionOptions()) -> decltype(asyncDelay(std::forward< F >(callback), qi::Duration(0), options))
Definition: executioncontext.hpp:112
qi::FutureState_Running
Operation pending.
Definition: future_fwd.hpp:84
QI_API_DEPRECATED_MSG
#define QI_API_DEPRECATED_MSG(msg__)
Compiler flags to mark a function as deprecated. It will generate a compiler warning.
Definition: macro.hpp:55
qi::ToPost::operator()
void operator()()
Definition: executioncontext.hpp:241
qi::async
auto async(F &&callback) -> decltype(asyncDelay(std::forward< F >(callback), qi::Duration(0)))
Definition: async.hpp:53
qi::FutureCallbackType_Sync
Definition: future_fwd.hpp:105
qi::FutureCallbackType_Async
Definition: future_fwd.hpp:106
future_fwd.hpp
qi::asyncAt
auto asyncAt(F &&callback, qi::SteadyClockTimePoint timepoint) -> decltype(qi::getEventLoop() ->asyncAt(std::forward< F >(callback), timepoint))
Definition: async.hpp:39
qi::FutureState_FinishedWithError
The operation is finished with an error.
Definition: future_fwd.hpp:86
qi::ExecutionContext::asyncAt
qi::Future< R > asyncAt(F &&callback, qi::SteadyClockTimePoint tp, ExecutionOptions options=defaultExecutionOptions())
call a callback asynchronously to be executed on tp
qi::detail::DelayedPromise
Definition: executioncontext.hpp:138
clock.hpp
qi::Promise::setCanceled
void setCanceled()
Definition: future_fwd.hpp:869
qi::ExecutionContext::post
void post(F &&callback, ExecutionOptions options=defaultExecutionOptions())
post a callback to be executed as soon as possible
Definition: executioncontext.hpp:226
qi::Future::wait
FutureState wait(int msecs=FutureTimeout_Infinite) const
Definition: future_fwd.hpp:296
qi::Future::error
const std::string & error(int msecs=FutureTimeout_Infinite) const
Definition: future_fwd.hpp:367
qi::ToPost
Definition: executioncontext.hpp:232
qi::FutureCallbackType
FutureCallbackType
Definition: future_fwd.hpp:104
qi::Promise::setValue
void setValue(const ValueType &value)
Definition: future_fwd.hpp:855
qi::Promise
Definition: future_fwd.hpp:71
qi::ExecutionContext::~ExecutionContext
virtual ~ExecutionContext()
Definition: executioncontext.hpp:66
qi::Future::impl
boost::shared_ptr< detail::FutureBaseTyped< T > > impl()
An accessor to the shared state. TODO: remove it, it should not exist.
Definition: future_fwd.hpp:588
qi::detail::FutureBaseTyped
Definition: future_fwd.hpp:74
qi::ToPost::callback
Callback callback
Definition: executioncontext.hpp:235
qi::FutureState_FinishedWithValue
The operation is finished with a value.
Definition: future_fwd.hpp:87
qi::bind
std::enable_if< std::is_function< RF >::value, boost::function< RF > >::type bind(AF &&fun, Arg0 &&arg0, Args &&...args)
Definition: trackable.hxx:308
qi::ExecutionOptions
Represent execution behaviour options attached to a task that must be interpreted by an ExecutionCont...
Definition: executioncontext.hpp:48