7 #ifndef _QI_DETAIL_FUTURE_HXX_
8 #define _QI_DETAIL_FUTURE_HXX_
12 #include <boost/bind.hpp>
22 template <
typename T,
typename R>
26 const boost::function<R(
const T&)>& func)
36 const boost::function<
void(
const T&)>& func)
43 template <
typename T,
typename R>
45 const boost::function<R(
const Future<T>&)>& func,
52 catch (std::exception& e)
58 promise.
setError(
"unknown exception");
62 template <
typename T,
typename R>
72 catch (std::exception& e)
78 promise.
setError(
"unknown exception");
82 template <
bool Async,
typename T,
typename R>
85 template <
typename T,
typename R>
88 template <
typename AF>
91 return boost::bind(&detail::continueThenAsync<T, R>,
99 template <
typename T,
typename R>
102 template <
typename AF>
110 template <
typename T,
typename R>
127 catch (std::exception& e)
133 promise.
setError(
"unknown exception");
138 template <
typename T,
typename R>
156 catch (std::exception& e)
162 promise.
setError(
"unknown exception");
167 template <
bool Async,
typename T,
typename R>
170 template <
typename T,
typename R>
173 template <
typename AF>
176 return boost::bind(&detail::continueAndThenAsync<T, R>,
184 template <
typename T,
typename R>
187 template <
typename AF>
197 template <
typename T>
198 template <
typename R,
typename AF>
201 return thenRImpl<R>(type, std::forward<AF>(func));
204 template <
typename T>
205 template <
typename R,
typename AF>
208 boost::weak_ptr<detail::FutureBaseTyped<T> > weakp(_p);
210 if (
auto futureb = weakp.lock())
218 detail::ContinueThenMaybeAsync<detail::IsAsyncBind<AF>::value, T, R>
219 ::makeFunc(std::forward<AF>(func), promise),
226 &detail::continueThen<T, R>,
229 boost::function<R(
const Future<T>&)>(std::forward<AF>(func)),
233 return promise.future();
236 template <
typename T>
237 template <
typename R,
typename AF>
240 return andThenRImpl<R>(type, std::forward(func));
243 template <
typename T>
244 template <
typename R,
typename AF>
247 boost::weak_ptr<detail::FutureBaseTyped<T> > weakp(_p);
249 if (
auto futureb = weakp.lock())
257 detail::ContinueAndThenMaybeAsync<detail::IsAsyncBind<AF>::value, T, R>
258 ::makeFunc(std::forward<AF>(func), promise),
267 boost::function<R(
const typename Future<T>::ValueType&)>(std::forward<AF>(func)),
271 return promise.future();
274 template <
typename T>
276 const boost::function<
void(
const Future<T>&)>& cb)
278 connectWithStrand(*strand, cb);
281 template <
typename T>
283 const boost::function<
void(
const Future<T>&)>& cb)
291 template <
typename T>
301 template <
typename T>
309 template <
typename T>
316 template <
typename T>
319 if (_onDestroyed && hasValue(0))
320 _onDestroyed(_value);
323 template <
typename T>
328 boost::recursive_mutex::scoped_lock lock(mutex());
332 onCancel = _onCancel;
341 template <
typename T>
344 bool doCancel =
false;
346 boost::recursive_mutex::scoped_lock lock(mutex());
347 _onCancel = onCancel;
348 doCancel = isCancelRequested();
355 template <
typename T>
358 for (
unsigned i = 0; i < _onResult.size(); ++i)
360 const bool async = [&]{
372 _onResult[i].callback(future);
377 catch (
const std::exception& e)
379 qiLogError(
"qi.future") <<
"Exception caught in future callback " << e.what();
383 qiLogError(
"qi.future") <<
"Unknown exception caught in future callback";
390 template <
typename T>
396 boost::recursive_mutex::scoped_lock lock(mutex());
402 callCbNotify(future);
405 template <
typename T>
411 boost::recursive_mutex::scoped_lock lock(mutex());
416 callCbNotify(future);
419 template <
typename T>
422 boost::recursive_mutex::scoped_lock lock(mutex());
426 reportError(message);
427 callCbNotify(future);
430 template <
typename T>
433 boost::recursive_mutex::scoped_lock lock(mutex());
436 reportError(
"Promise broken (all promises are destroyed)");
437 callCbNotify(future);
440 template <
typename T>
443 boost::recursive_mutex::scoped_lock lock(mutex());
448 callCbNotify(future);
451 template <
typename T>
457 template <
typename T>
467 boost::recursive_mutex::scoped_lock lock(mutex());
468 ready = isFinished();
470 _onResult.push_back(Callback(s, type));
476 const bool async = [&]{
491 catch (const ::qi::PointerLockException&)
498 template <
typename T>
513 template <
typename T>
519 _onCancel = CancelCallback(PromiseNoop<T>);
523 template <
typename T>
527 if (!prom.future().isFinished() && !fut.
hasError())
541 if (!prom.future().isFinished())
547 prom.setValue(makeFutureError<T>(
"No future returned successfully."));
556 template <
typename T>
571 return promise.future();
587 const boost::weak_ptr<FutureBaseTyped<
Future<T> > >& wfuture)
589 if (boost::shared_ptr<FutureBaseTyped<
Future<T> > > fbt =
600 template <
typename T>
609 template<
typename FT,
typename PT,
typename CONV>
621 catch (
const std::exception& e)
623 p.
setError(std::string(
"futureAdapter conversion error: ") + e.what());
630 template<
typename FT>
646 template <
typename T>
654 template <
typename T>
672 template<
typename FT,
typename PT>
682 template<
typename FT,
typename PT,
typename CONV>
688 const_cast<Future<FT>&
>(f).connect(
boost::bind(detail::futureAdapter<FT, PT, CONV>, _1, p, converter),
695 template <
typename T>
744 #endif // _QI_DETAIL_FUTURE_HXX_
static void * _callfunc(const T &future, const boost::function< void(const T &)> &func)
void setError(qi::Future< T > &future, const std::string &message)
when the promise is already set.
void setup(boost::function< void(qi::Promise< T > &)> cancelCallback, FutureCallbackType async=FutureCallbackType_Auto)
void connect(const AF &fun, FutureCallbackType type=FutureCallbackType_Auto)
FutureWrapper< T > & operator()()
The future has been canceled.
void futureAdapter(const Future< FT > &f, Promise< PT > p, CONV converter)
void continueThen(const Future< T > &future, const boost::function< R(const Future< T > &)> &func, qi::Promise< R > &promise)
auto schedulerFor(F &&func, boost::function< void()> onFail={}) -> detail::WrapInStrand< typename std::decay< F >::type >
void operator()(const T &in, void *out)
void continueAndThen(const Future< T > &future, const boost::function< R(const typename Future< T >::ValueType &)> &func, qi::Promise< R > &promise)
void operator,(const T &val)
void operator()(void *in, void *out)
void setCanceled(qi::Future< T > &future)
The future has been canceled.
void setValue(qi::Future< T > &future, const ValueType &value)
static boost::function< void(const Future< T > &)> makeFunc(AF &&func, const qi::Promise< R > &promise)
static boost::function< void(const Future< T > &)> makeFunc(AF &&func, const qi::Promise< R > &promise)
void setError(const std::string &msg)
void set(qi::Future< T > &future)
void callCbNotify(qi::Future< T > &future)
#define QI_ASSERT(expr__)
boost::function< void()> makeCanceler()
Get a functor that will cancel the future.
Specialize this struct to provide conversion between future values.
FutureWrapper< void > & operator()()
qi::Future< T > makeFutureError(const std::string &error)
Helper function to return a future with the error set.
static boost::function< void(const Future< T > &)> makeFunc(AF &&func, const qi::Promise< R > &promise)
bool isCancelRequested() const
void post(const boost::function< void()> &callback, uint64_t usDelay)
Similar to async() but without cancelation or notification.
Future< T > future() const
Get a future linked to this promise. Can be called multiple times.
Future< R > andThenR(FutureCallbackType type, AF &&func)
Same as thenR(), but the callback is called only if this future finishes with a value.
boost::shared_ptr< detail::FutureBaseTyped< T > > _p
#define qiLogError(...)
Log in error mode.
the future is not associated to a promise
const ValueType & value(int msecs) const
void continueThenAsync(const Future< T > &future, const boost::function< qi::Future< R >(const Future< T > &)> &func, qi::Promise< R > &promise)
Future< R > async(boost::function< R()> callback, uint64_t usDelay)
typename FutureType< T >::type ValueType
qi::Future< void > future
Future is not tied to a promise.
void continueAndThenAsync(const Future< T > &future, const boost::function< qi::Future< R >(const typename Future< T >::ValueType &)> &func, qi::Promise< R > &promise)
void setOnDestroyed(boost::function< void(ValueType)> f)
void operator,(const Future< void > &val)
static boost::function< void(const Future< T > &)> makeFunc(AF &&func, const qi::Promise< R > &promise)
typename detail::FutureType< T >::type ValueType
EventLoop * getEventLoop()
Return the global eventloop, created on demand on first call.
void connect(qi::Future< T > future, const boost::function< void(qi::Future< T >)> &s, FutureCallbackType type)
The operation is finished with an error.
Future< R > thenR(FutureCallbackType type, AF &&func)
Execute a callback when the future is finished.
void waitForFirstHelper(qi::Promise< qi::Future< T > > &prom, qi::Future< T > &fut, qi::Atomic< int > *count)
boost::function< void(Promise< T > &)> CancelCallback
void cancel(qi::Future< T > &future)
void futureCancelAdapter(boost::weak_ptr< FutureBaseTyped< FT > > wf)
void operator,(const Future< T > &val)
const std::string & error(int msecs=FutureTimeout_Infinite) const
const ValueType & value(int msecs=FutureTimeout_Infinite) const
Return the value associated to a Future.
void setBroken(qi::Future< T > &future)
void setValue(const ValueType &value)
void setOnCancel(qi::Promise< T > &promise, CancelCallback onCancel)
void adaptFuture(const Future< FT > &f, Promise< PT > &p, AdaptFutureOption option)
Feed a promise from a future of possibly different type.
static R _callfunc(const T &arg, const boost::function< R(const T &)> &func)
void connectWithStrand(qi::Strand *strand, const boost::function< void(const Future< T > &)> &cb)
std::enable_if< std::is_function< RF >::value, boost::function< RF > >::type bind(AF &&fun, Arg0 &&arg0, Args &&...args)
void operator()(void *in, const T &out)
void adaptFutureUnwrap(Future< AnyReference > &f, Promise< R > &p)
Feed a promise from a generic future which may be unwrapped if it contains itself a future...
bool hasError(int msecs=FutureTimeout_Infinite) const