libqi-api  release-2.5.3-2016-11-18
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
signal.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 _QITYPE_DETAIL_SIGNAL_HXX_
8 #define _QITYPE_DETAIL_SIGNAL_HXX_
9 
10 #include <qi/trackable.hpp>
12 #include <boost/bind.hpp>
14 
15 namespace qi
16 {
17  template <typename T>
18  template <typename F, typename Arg0, typename... Args>
19  SignalSubscriber& SignalF<T>::connect(F&& func, Arg0&& arg0, Args&&... args)
20  {
21  int curId;
22  SignalLink* trackLink;
23  createNewTrackLink(curId, trackLink);
24  SignalSubscriber& s =
25  connect(qi::bind(std::forward<F>(func), std::forward<Arg0>(arg0), std::forward<Args>(args)...));
26  *trackLink = s;
27  return s;
28  }
29 
30  template<typename T>
32  {
33  return SignalBase::connect(SignalSubscriber(std::move(f)));
34  }
35  template<typename T>
36  SignalSubscriber& SignalF<T>::connect(const SignalSubscriber& sub)
37  {
38  return SignalBase::connect(std::move(sub));
39  }
40  template<typename T>
41  template<typename U>
42  SignalSubscriber& SignalF<T>::connect(SignalF<U>& signal)
43  {
44  int curId;
45  SignalLink* trackLink;
46  createNewTrackLink(curId, trackLink);
47  SignalSubscriber& s = connect(qi::trackWithFallback(
48  boost::bind(&SignalF<T>::disconnectTrackLink, this, curId),
49  (boost::function<U>&)signal,
50  boost::weak_ptr<SignalBasePrivate>(signal._p)));
51  *trackLink = s;
52  return s;
53  }
54 
55  template <typename T>
56  template <typename... P>
57  SignalSubscriber& SignalF<T>::connect(Signal<P...>& signal)
58  {
59  typedef void(ftype)(P...);
60  int curId;
61  SignalLink* trackLink;
62  createNewTrackLink(curId, trackLink);
63  SignalSubscriber& s = connect(qi::trackWithFallback(
64  boost::bind(&SignalF<T>::disconnectTrackLink, this, curId),
65  (boost::function<ftype>&)signal,
66  boost::weak_ptr<SignalBasePrivate>(signal._p)));
67  *trackLink = s;
68  return s;
69  }
70 
71  template<typename F>
72  SignalSubscriber& SignalBase::connect(boost::function<F> fun)
73  {
74  return connect(AnyFunction::from(std::move(fun)));
75  }
76  // TODO: taking by forward ref is too greedy and connect(SignalSubscriber) takes this overload
77  // find a way to fix this
78  template<typename T>
79  template<typename F>
81  {
82  SignalSubscriber& sub = connect(qi::AnyFunction::from(boost::function<T>(std::move(c))));
85  return sub;
86  }
87  template<typename T>
88  SignalSubscriber& SignalF<T>::connect(const AnyObject& obj, const std::string& slot)
89  {
90  return SignalBase::connect(obj, slot);
91  }
92 
93  template<typename T>
94  SignalSubscriber& SignalF<T>::connect(const AnyObject& obj, unsigned int slot)
95  {
96  return connect(SignalSubscriber(obj, slot));
97  }
98 
99  namespace detail
100  {
101 
102  template<typename T> class BounceToSignalBase
103  {
104  // This default should not be instanciated
105  static_assert(sizeof(T) < 0, "You can't instanciate BounceToSignalBase");
106  public:
108  {
109  }
110  };
111  #define pushArg(z, n, _) \
112  args.push_back(AutoAnyReference(p ##n));
113  #define makeBounce(n, argstypedecl, argstype, argsdecl, argsues, comma) \
114  template<typename R comma argstypedecl> \
115  class BounceToSignalBase<R(argstype)> { \
116  public: \
117  BounceToSignalBase(SignalBase& signalBase) : signalBase(signalBase) {} \
118  R operator()(argsdecl) { \
119  AnyReferenceVector args; \
120  BOOST_PP_REPEAT(n, pushArg, _); \
121  signalBase.trigger(args); \
122  } \
123  private: \
124  SignalBase& signalBase; \
125  };
127  #undef makeBounce
128  #undef pushArg
129 
130  } // detail
131 
132  template<typename T>
134  : SignalBase(onSubscribers)
135  {
136  * (boost::function<T>*)this = detail::BounceToSignalBase<T>(*this);
137  _setSignature(detail::functionArgumentsSignature<T>());
138  }
139 
140 
141  template<typename T>
143  {
144  return detail::functionArgumentsSignature<T>();
145  }
146 
147  inline
149  {
150  threadingModel = ct;
151  return *this;
152  }
153 } // qi
154 #endif // _QITYPE_DETAIL_SIGNAL_HXX_
boost::function< void(bool)> OnSubscribers
Definition: signal.hpp:41
SignalSubscriber & setCallType(MetaCallType ct)
Definition: signal.hxx:148
BounceToSignalBase(SignalBase &sb)
Definition: signal.hxx:107
void _setSignature(const Signature &s)
SignalSubscriber & connect(boost::function< F > func)
Definition: signal.hxx:72
SignalSubscriber & connect(...)
Definition: signal.hxx:19
virtual qi::Signature signature() const
Definition: signal.hxx:142
Force a synchronous call.
Definition: typeobject.hpp:25
#define makeBounce(n, argstypedecl, argstype, argsdecl, argsues, comma)
Definition: signal.hxx:113
MetaCallType
Definition: typeobject.hpp:21
MetaCallType threadingModel
Definition: signal.hpp:248
Object< Empty > AnyObject
Definition: anyobject.hpp:21
static AnyFunction from(F &&func)
qi::uint64_t SignalLink
Definition: signal.hpp:35
SignalF(OnSubscribers onSubscribers=OnSubscribers())
Definition: signal.hxx:133
auto trackWithFallback(boost::function< void()> onFail, F &&f, Arg0 &&arg0) -> decltype(detail::BindTransform< Arg0 >::wrap(std::forward< Arg0 >(arg0), std::forward< F >(f), std::move(onFail)))
Definition: trackable.hxx:404
std::enable_if< std::is_function< RF >::value, boost::function< RF > >::type bind(AF &&fun, Arg0 &&arg0, Args &&...args)
Definition: trackable.hxx:327
#define QI_GEN(f)
Definition: preproc.hpp:476