libqi-api  release-2.5.3-2016-11-18
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
eventloop.hxx
Go to the documentation of this file.
1 #pragma once
2 /*
3 ** Copyright (C) 2013 Aldebaran Robotics
4 ** See COPYING for the license
5 */
6 
7 #ifndef _QI_DETAIL_EVENTLOOP_HXX_
8 #define _QI_DETAIL_EVENTLOOP_HXX_
9 
10 #include <qi/detail/future_fwd.hpp>
11 #include <qi/actor.hpp>
12 
13 namespace qi
14 {
15 
16 template <typename R>
17 void nullConverter(void*, R&)
18 {}
19 
20 template <typename R>
21 Future<R> EventLoop::async(const boost::function<R()>& callback,
22  uint64_t usDelay)
23 {
24  return async(callback, qi::MicroSeconds(usDelay));
25 }
26 
27 namespace detail
28 {
29  template <typename F>
30  auto asyncMaybeActor(F&& cb, qi::Duration delay) ->
31  typename std::enable_if<detail::IsAsyncBind<F>::value, typename std::decay<decltype(cb())>::type>::type
32  {
33  if (delay != qi::Duration::zero())
34  return qi::getEventLoop()->asyncDelay(cb, delay).unwrap();
35  else
36  return cb();
37  }
38  template <typename F>
39  auto asyncMaybeActor(F&& cb, qi::Duration delay) ->
40  typename std::enable_if<!detail::IsAsyncBind<F>::value,
42  {
43  return qi::getEventLoop()->asyncDelay(cb, delay);
44  }
45  template <typename F>
46  auto asyncMaybeActor(F&& cb, qi::SteadyClockTimePoint timepoint) ->
47  typename std::enable_if<detail::IsAsyncBind<F>::value, typename std::decay<decltype(cb())>::type>::type
48  {
49  return qi::getEventLoop()->asyncAt(cb, timepoint).unwrap();
50  }
51  template <typename F>
52  auto asyncMaybeActor(F&& cb, qi::SteadyClockTimePoint timepoint) ->
53  typename std::enable_if<!detail::IsAsyncBind<F>::value,
55  {
56  return qi::getEventLoop()->asyncAt(cb, timepoint);
57  }
58 
59  // sfinae to try to call unwrap on the future
60  template <typename F>
61  auto tryUnwrap(const F& future, int) -> decltype(future.unwrap())
62  {
63  return future.unwrap();
64  }
65  template <typename F>
66  F tryUnwrap(const F& future, void*)
67  {
68  return future;
69  }
70 
71  // this function is used by qilang generation to call something regardless of if it's an actor or not
72  // it is very specific to qilang's generated code, I don't think it's a good idea to use it elsewhere
73  // this function may or may not return a future (the other overload does not)
74  template <typename F, typename Arg0, typename... Args>
75  auto invokeMaybeActor(F&& cb, Arg0* arg0, Args&&... args) ->
76  typename std::enable_if<std::is_base_of<Actor, typename std::decay<Arg0>::type>::value,
77  decltype(tryUnwrap(qi::async(qi::bind(cb, arg0, std::forward<Args>(args)...)), 0))>::type
78  {
79  // this is an actor, we must async to strand the call
80  return tryUnwrap(qi::async(qi::bind(cb, arg0, std::forward<Args>(args)...)), 0);
81  }
82  template <typename F, typename Arg0, typename... Args>
83  auto invokeMaybeActor(F&& cb, Arg0* arg0, Args&&... args) ->
84  typename std::enable_if<!std::is_base_of<Actor, typename std::decay<Arg0>::type>::value,
85  typename std::decay<decltype((arg0->*cb)(std::forward<Args>(args)...))>::type>::type
86  {
87  return (arg0->*cb)(std::forward<Args>(args)...);
88  }
89 }
90 
91 }
92 
93 #endif
DurationType< int64_t, boost::micro > MicroSeconds
Definition: clock.hpp:26
SteadyClock::time_point SteadyClockTimePoint
Steady clock time point.
Definition: clock.hpp:211
Future< R > async(const boost::function< R()> &callback, uint64_t usDelay)
Call given function once after given delay in microseconds.
Definition: eventloop.hxx:21
void nullConverter(void *, R &)
Definition: eventloop.hxx:17
auto invokeMaybeActor(F &&cb, Arg0 *arg0, Args &&...args) -> typename std::enable_if< std::is_base_of< Actor, typename std::decay< Arg0 >::type >::value, decltype(tryUnwrap(qi::async(qi::bind(cb, arg0, std::forward< Args >(args)...)), 0))>::type
Definition: eventloop.hxx:75
auto asyncDelay(F &&callback, qi::Duration delay) -> qi::Future< typename std::decay< decltype(callback())>::type >
call a callback asynchronously to be executed in delay
NanoSeconds Duration
Definition: clock.hpp:32
auto asyncMaybeActor(F &&cb, qi::Duration delay) -> typename std::enable_if< detail::IsAsyncBind< F >::value, typename std::decay< decltype(cb())>::type >::type
Definition: eventloop.hxx:30
Future< R > async(boost::function< R()> callback, uint64_t usDelay)
Definition: eventloop.hpp:186
EventLoop * getEventLoop()
Return the global eventloop, created on demand on first call.
auto tryUnwrap(const F &future, int) -> decltype(future.unwrap())
Definition: eventloop.hxx:61
auto asyncAt(F &&callback, qi::SteadyClockTimePoint tp) -> qi::Future< typename std::decay< decltype(callback())>::type >
call a callback asynchronously to be executed on tp
uint64_t uint64_t
Definition: types.hpp:66
std::enable_if< std::is_function< RF >::value, boost::function< RF > >::type bind(AF &&fun, Arg0 &&arg0, Args &&...args)
Definition: trackable.hxx:327