7 #ifndef QI_TYPE_DETAIL_FUTURE_ADAPTER_HXX_
8 #define QI_TYPE_DETAIL_FUTURE_ADAPTER_HXX_
10 #include <boost/scope_exit.hpp>
19 static const char* InvalidFutureError =
"function returned an invalid future";
25 qiLogDebug(
"qi.adapter") <<
"converting value";
31 catch(
const std::exception& e)
33 qiLogError(
"qi.adapter") <<
"future to promise forwarding error: " << e.what();
50 boost::shared_ptr<GenericObject>& ao)
53 qiLogDebug(
"qi.adapter") <<
"futureAdapter trigger";
64 BOOST_SCOPE_EXIT_TPL(&ao, &val) {
67 } BOOST_SCOPE_EXIT_END
68 if (gfut.
call<
bool>(
"hasError", 0))
70 qiLogDebug(
"qi.adapter") <<
"futureAdapter: future in error";
71 std::string s = gfut.
call<std::string>(
"error", 0);
72 qiLogDebug(
"qi.adapter") <<
"futureAdapter: got error: " << s;
76 if (gfut.
call<
bool>(
"isCanceled"))
78 qiLogDebug(
"qi.adapter") <<
"futureAdapter: future canceled";
82 qiLogDebug(
"qi.adapter") <<
"futureAdapter: future has value";
103 *kind = ft1->templateArgument()->kind();
109 *kind = ft2->templateArgument()->kind();
113 return boost::shared_ptr<GenericObject>();
114 return boost::make_shared<GenericObject>(onext, val.
rawValue());
119 template <
typename T>
126 if (!ao->call<
bool>(
"isValid"))
128 promise.
setError(InvalidFutureError);
132 boost::function<void()> cb =
133 boost::bind(futureAdapterGeneric<T>, val, promise, ao);
139 ao->call<
void>(
"_connect", cb);
143 &GenericObject::call<void>),
144 boost::weak_ptr<GenericObject>(ao),
147 catch (std::exception& e)
149 qiLogError(
"qi.object") <<
"future connect error " << e.what();
150 promise.
setError(
"internal error: cannot connect returned future");
165 template <
typename T>
174 if (!ao->call<
bool>(
"isValid"))
175 throw std::runtime_error(InvalidFutureError);
182 QI_ONCE(targetType = typeOf<T>());
185 std::pair<AnyReference, bool> conv = val.
convert(targetType);
186 if (!conv.first.type())
187 throw std::runtime_error(std::string(
"Unable to convert call result to target type: from ")
194 return std::move(*conv.first.ptr<T>(
false));
197 return std::move(*conv.first.ptr<T>(
false));
200 catch(
const std::exception& e)
202 throw std::runtime_error(std::string(
"Return argument conversion error: ") + e.what());
214 if (!ao->call<
bool>(
"isValid"))
215 throw std::runtime_error(InvalidFutureError);
221 template <
typename T>
224 qiLogDebug(
"qi.object") <<
"futureAdapter " << qi::typeOf<T>()->infoString()<<
' ' << metaFut.
hasError();
240 QI_ONCE(targetType = typeOf<T>());
243 std::pair<AnyReference, bool> conv = val.
convert(targetType);
244 if (!conv.first.type())
245 promise.
setError(std::string(
"Unable to convert call result to target type: from ")
249 promise.
setValue(*conv.first.ptr<T>(
false));
252 conv.first.destroy();
254 catch(
const std::exception& e)
256 promise.
setError(std::string(
"Return argument conversion error: ") + e.what());
264 qiLogDebug(
"qi.object") <<
"futureAdapter void " << metaFut.hasError();
266 if (metaFut.hasError()) {
267 promise.setError(metaFut.error());
270 if (metaFut.isCanceled()) {
271 promise.setCanceled();
282 template <
typename T>
299 catch (
const std::exception& e)
301 promise.
setError(std::string(
"Return argument conversion error: ") + e.what());
std::pair< AnyReference, bool > convert(TypeInterface *targetType) const
std::string toPrettySignature() const
std::enable_if< std::is_function< RF >::value, boost::function< RF > >::type bindSilent(AF &&fun, Arg0 &&arg0, Args &&...args)
AutoRefDestroy(AnyReference ref)
void destroy()
Stop and flush the logging system.
void futureAdapter(const Future< FT > &f, Promise< PT > p, CONV converter)
void setError(const std::string &msg)
#define QI_ASSERT(expr__)
T extractFuture(const qi::Future< qi::AnyReference > &metaFut)
void futureAdapterGeneric(AnyReference val, qi::Promise< T > promise, boost::shared_ptr< GenericObject > &ao)
void setPromise(qi::Promise< T > &promise, AnyValue &v)
void destroy()
Deletes storage.
R call(const std::string &methodName, Args &&...args)
#define qiLogError(...)
Log in error mode.
T to() const
Convert to anything or throw trying.
qi::Signature signature(bool resolveDynamic=false) const
TypeInterface * type() const
void futureAdapterVal(const qi::Future< qi::AnyValue > &metaFut, qi::Promise< T > promise)
#define QI_TEMPLATE_TYPE_GET(typeInst, templateName)
#define QI_ONCE(code)
Execute code once, parallel calls are blocked until code finishes.
boost::shared_ptr< GenericObject > getGenericFuture(AnyReference val, TypeKind *kind=0)
AnyReference asReference() const
const char * infoString()
void setOnCancel(boost::function< void(qi::Promise< T > &)> cancelCallback)
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 futureAdapter< void >(const qi::Future< qi::AnyReference > &metaFut, qi::Promise< void > promise)
void setValue(const ValueType &value)
bool handleFuture(AnyReference val, Promise< T > promise)
std::enable_if< std::is_function< RF >::value, boost::function< RF > >::type bind(AF &&fun, Arg0 &&arg0, Args &&...args)
void extractFuture< void >(const qi::Future< qi::AnyReference > &metaFut)
qi::Signature signature(void *storage=0, bool resolveDynamic=false)
bool hasError(int msecs=FutureTimeout_Infinite) const