libqi-api
2.0.6.8
|
00001 #pragma once 00002 /* 00003 ** Copyright (C) 2013 Aldebaran Robotics 00004 ** See COPYING for the license 00005 */ 00006 00007 #ifndef _QI_DETAILS_EVENTLOOP_HXX_ 00008 #define _QI_DETAILS_EVENTLOOP_HXX_ 00009 00010 #include <qi/future.hpp> 00011 00012 namespace qi 00013 { 00014 00015 namespace detail 00016 { 00017 template <typename T> 00018 class DelayedPromise: public Promise<T> 00019 { 00020 public: 00021 DelayedPromise() {} 00022 void setup(boost::function<void (qi::Promise<T>)> cancelCallback, FutureCallbackType async = FutureCallbackType_Async) 00023 { 00024 Promise<T>::setup(cancelCallback, async); 00025 } 00026 }; 00027 00028 template<typename R> void call_and_set(qi::Promise<R> p, boost::function<R()> f) 00029 { 00030 try 00031 { 00032 p.setValue(f()); 00033 } 00034 catch (const std::exception& e) 00035 { 00036 p.setError(e.what()); 00037 } 00038 catch(...) 00039 { 00040 p.setError("unknown exception"); 00041 } 00042 } 00043 template<typename R> void check_canceled(qi::Future<void> f, qi::Promise<R> p) 00044 { 00045 if (f.wait() == FutureState_Canceled) 00046 p.setCanceled(); 00047 // Nothing to do for other states. 00048 } 00049 } 00050 template<typename R> void nullConverter(void*, R&) {} 00051 template<typename R> Future<R> EventLoop::async(boost::function<R()> callback, uint64_t usDelay) 00052 { 00053 detail::DelayedPromise<R> promise; 00054 qi::Future<void> f = async((boost::function<void()>)boost::bind(detail::call_and_set<R>, promise, callback), usDelay); 00055 promise.setup(boost::bind(&detail::futureCancelAdapter<void>, 00056 boost::weak_ptr<detail::FutureBaseTyped<void> >(f.impl())), FutureCallbackType_Sync); 00057 f.connect(boost::bind(&detail::check_canceled<R>,_1, promise)); 00058 return promise.future(); 00059 } 00060 00061 } 00062 00063 00064 #endif