- Aldebaran documentation |
- C++ Libraries |
- index

libqi-api 2.8.7.4

- Main Page
- Related Pages
- Namespaces
- Classes
- Files
- Examples

- File List
- File Members

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>
11 #include <qi/type/detail/manageable.hpp>
12 #include <boost/bind.hpp>
13 #include <qi/type/detail/functionsignature.hxx>
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 SignalSubscriber s =
22 connect(qi::bind(std::forward<F>(func), std::forward<Arg0>(arg0), std::forward<Args>(args)...));
23 return s;
24 }
25
26 template<typename T>
27 SignalSubscriber SignalF<T>::connect(AnyFunction f)
28 {
29 auto execContext = executionContext();
30 if (execContext)
31 {
32 return SignalBase::connect(SignalSubscriber(std::move(f), execContext));
33 }
34 else
35 {
36 return SignalBase::connect(SignalSubscriber(std::move(f), MetaCallType_Auto));
37 }
38 }
39 template<typename T>
40 SignalSubscriber SignalF<T>::connect(const SignalSubscriber& sub)
41 {
42 return SignalBase::connect(std::move(sub));
43 }
44
45 template<typename T>
46 template<class ForcedSignalType, class SignalType>
47 SignalSubscriber SignalF<T>::connectSignal(SignalType& signal)
48 {
49 int curId = 0;
50 SignalLink* trackLink = nullptr;
51 createNewTrackLink(curId, trackLink);
52
53 boost::weak_ptr<SignalBasePrivate> maybeThisSignalPrivate(this->_p);
54
55 auto onSignalLost = [=]{
56 if (auto thisSignalPrivate = maybeThisSignalPrivate.lock())
57 {
58 disconnectTrackLink(curId);
59 }
60 };
61
62 auto forwardSignalCall = qi::trackWithFallback(
63 std::move(onSignalLost),
64 static_cast<ForcedSignalType&>(signal),
65 boost::weak_ptr<SignalBasePrivate>(signal._p));
66
67 SignalSubscriber s = connect(std::move(forwardSignalCall));
68
69 *trackLink = s;
70 return s;
71 }
72
73 template<typename T>
74 template<typename U>
75 SignalSubscriber SignalF<T>::connect(SignalF<U>& signal)
76 {
77 return connectSignal<boost::function<U>>(signal);
78 }
79
80 template <typename T>
81 template <typename... P>
82 SignalSubscriber SignalF<T>::connect(Signal<P...>& signal)
83 {
84 typedef void(ftype)(P...);
85 return connectSignal<boost::function<ftype>>(signal);
86 }
87
88 template<typename F>
89 SignalSubscriber SignalBase::connect(boost::function<F> fun)
90 {
91 return connect(AnyFunction::from(std::move(fun)));
92 }
93 // TODO: taking by forward ref is too greedy and connect(SignalSubscriber) takes this overload
94 // find a way to fix this
95 template<typename T>
96 template<typename F>
97 SignalSubscriber SignalF<T>::connect(F c)
98 {
99 SignalSubscriber sub = connect(qi::AnyFunction::from(boost::function<T>(std::move(c))));
100 if (detail::IsAsyncBind<F>::value)
101 sub.setCallType(MetaCallType_Direct);
102 return sub;
103 }
104 template<typename T>
105 SignalSubscriber SignalF<T>::connect(const AnyObject& obj, const std::string& slot)
106 {
107 return SignalBase::connect(obj, slot);
108 }
109
110 template<typename T>
111 SignalSubscriber SignalF<T>::connect(const AnyObject& obj, unsigned int slot)
112 {
113 return connect(SignalSubscriber(obj, slot));
114 }
115
116 namespace detail
117 {
118
119 template<typename T> class BounceToSignalBase
120 {
121 // This default should not be instanciated
122 static_assert(sizeof(T) < 0, "You can't instanciate BounceToSignalBase");
123 public:
124 BounceToSignalBase(SignalBase& sb)
125 {
126 }
127 };
128 #define pushArg(z, n, _) \
129 args.push_back(AutoAnyReference(p ##n));
130 #define makeBounce(n, argstypedecl, argstype, argsdecl, argsues, comma) \
131 template<typename R comma argstypedecl> \
132 class BounceToSignalBase<R(argstype)> { \
133 public: \
134 BounceToSignalBase(SignalBase& signalBase) : signalBase(signalBase) {} \
135 R operator()(argsdecl) { \
136 AnyReferenceVector args; \
137 BOOST_PP_REPEAT(n, pushArg, _); \
138 signalBase.trigger(args); \
139 } \
140 private: \
141 SignalBase& signalBase; \
142 };
143 QI_GEN(makeBounce)
144 #undef makeBounce
145 #undef pushArg
146
147 } // detail
148
149 template<typename T>
150 SignalF<T>::SignalF(OnSubscribers onSubscribers)
151 : SignalF(nullptr, std::move(onSubscribers))
152 {
153 }
154
155 template<typename T>
156 SignalF<T>::SignalF(ExecutionContext* execContext, OnSubscribers onSubscribers)
157 : SignalBase(execContext, onSubscribers)
158 {
159 * (boost::function<T>*)this = detail::BounceToSignalBase<T>(*this);
160 _setSignature(detail::functionArgumentsSignature<T>());
161 }
162
163
164 template<typename T>
165 qi::Signature SignalF<T>::signature() const
166 {
167 return detail::functionArgumentsSignature<T>();
168 }
169 } // qi
170 #endif // _QITYPE_DETAIL_SIGNAL_HXX_
qi::trackWithFallback
auto trackWithFallback(boost::function< void()> onFail, F &&f, T &&toTrack) -> decltype(detail::BindTransform< T >::wrap(std::forward< T >(toTrack), std::forward< F >(f), std::move(onFail)))
Definition: trackable.hxx:413
qi::detail::BounceToSignalBase::BounceToSignalBase
BounceToSignalBase(SignalBase &sb)
Definition: signal.hxx:124
functionsignature.hxx
qi::SignalBase::_setSignature
void _setSignature(const Signature &s)
qi::AnyFunction
Definition: anyfunction.hpp:149
qi::Signature
Definition: signature.hpp:66
qi::detail::BounceToSignalBase
Definition: signal.hxx:119
qi::MetaCallType_Auto
Honor the default behavior.
Definition: typeobject.hpp:26
trackable.hpp
qi::ExecutionContext
Definition: executioncontext.hpp:63
qi::SignalF::signature
virtual qi::Signature signature() const
Definition: signal.hxx:165
qi::detail::IsAsyncBind
Definition: trackable.hxx:172
qi::SignalF
Definition: signal.hpp:171
qi::SignalBase::OnSubscribers
boost::function< Future< void >(bool)> OnSubscribers
Definition: signal.hpp:45
qi::MetaCallType_Direct
Force a synchronous call.
Definition: typeobject.hpp:28
makeBounce
#define makeBounce(n, argstypedecl, argstype, argsdecl, argsues, comma)
Definition: signal.hxx:130
qi::SignalBase
Definition: signal.hpp:42
qi::SignalBase::connect
SignalSubscriber connect(boost::function< F > func)
Definition: signal.hxx:89
manageable.hpp
qi::AnyObject
Object< Empty > AnyObject
Definition: anyobject.hpp:21
qi::AnyFunction::from
static AnyFunction from(F &&func)
qi::SignalLink
qi::uint64_t SignalLink
Definition: signal.hpp:36
qi::SignalF::connect
SignalSubscriber connect(...)
Definition: signal.hxx:19
qi::SignalF::SignalF
SignalF(OnSubscribers onSubscribers=OnSubscribers())
Definition: signal.hxx:150
qi::bind
std::enable_if< std::is_function< RF >::value, boost::function< RF > >::type bind(AF &&fun, Arg0 &&arg0, Args &&...args)
Definition: trackable.hxx:308
QI_GEN
#define QI_GEN(f)
Definition: preproc.hpp:476