- 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.hpp
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_SIGNAL_HPP_
8 #define _QI_SIGNAL_HPP_
9
10 #include <boost/function.hpp>
11 #include <boost/scoped_ptr.hpp>
12 #include <qi/atomic.hpp>
13 #include <qi/macro.hpp>
14
15 #include <qi/anyfunction.hpp>
16 #include <qi/type/typeobject.hpp>
17
18 #include <boost/thread/thread.hpp>
19 #include <boost/thread/mutex.hpp>
20
21 #ifdef _MSC_VER
22 # pragma warning( push )
23 # pragma warning( disable: 4251 )
24 #endif
25
26 // Macro to be more expressive when emitting a signal. Does nothing, it's normal.
27 #define QI_EMIT
28
29 namespace qi {
30
31 class ManageablePrivate;
32 class SignalSubscriber;
33
34 class SignalBasePrivate;
35
36 using SignalLink = qi::uint64_t;
37
38
42 class QI_API SignalBase
43 {
44 public:
45 using OnSubscribers = boost::function<Future<void>(bool)>;
46
47 explicit SignalBase(const Signature &signature, OnSubscribers onSubscribers = OnSubscribers());
48 SignalBase(const Signature &signature, ExecutionContext* execContext,
49 OnSubscribers onSubscribers = OnSubscribers());
50 SignalBase(OnSubscribers onSubscribers = OnSubscribers());
51 SignalBase(ExecutionContext* execContext, OnSubscribers onSubscribers = OnSubscribers());
52
54 SignalBase(const SignalBase&) = delete;
55 SignalBase& operator=(const SignalBase&) = delete;
56
57 virtual ~SignalBase();
58
59 virtual qi::Signature signature() const;
60
61 template<typename F>
62 SignalSubscriber connect(boost::function<F> func);
63 SignalSubscriber connect(AnyObject object, const unsigned int slot);
64 SignalSubscriber connect(AnyObject object, const std::string& slot);
65
67 SignalSubscriber connect(const SignalSubscriber& s);
68
73 Future<SignalSubscriber> connectAsync(const SignalSubscriber&);
74
80 bool disconnectAll();
86 Future<bool> disconnectAllAsync();
87
88 QI_API_DEPRECATED_MSG("use disconnectAllAsync instead")
89 bool asyncDisconnectAll()
90 {
91 disconnectAllAsync();
92 return true;
93 }
94
104 bool disconnect(const SignalLink& link);
105
113 Future<bool> disconnectAsync(const SignalLink& link);
114
115 QI_API_DEPRECATED_MSG("use disconnectAsync instead")
116 bool asyncDisconnect(const SignalLink& link)
117 {
118 disconnectAsync(link);
119 return true;
120 }
121
130 virtual void trigger(const GenericFunctionParameters& params, MetaCallType callType = MetaCallType_Auto);
132 void setCallType(MetaCallType callType);
134 void operator()(
135 qi::AutoAnyReference p1 = qi::AutoAnyReference(),
136 qi::AutoAnyReference p2 = qi::AutoAnyReference(),
137 qi::AutoAnyReference p3 = qi::AutoAnyReference(),
138 qi::AutoAnyReference p4 = qi::AutoAnyReference(),
139 qi::AutoAnyReference p5 = qi::AutoAnyReference(),
140 qi::AutoAnyReference p6 = qi::AutoAnyReference(),
141 qi::AutoAnyReference p7 = qi::AutoAnyReference(),
142 qi::AutoAnyReference p8 = qi::AutoAnyReference());
143
144 std::vector<SignalSubscriber> subscribers();
145 bool hasSubscribers();
146
149 void setOnSubscribers(OnSubscribers onSubscribers);
150
151 static const SignalLink invalidSignalLink;
152 void _setSignature(const Signature &s);
153 protected:
154 using Trigger = boost::function<void(const GenericFunctionParameters& params, MetaCallType callType)>;
155 void callSubscribers(const GenericFunctionParameters& params, MetaCallType callType = MetaCallType_Auto);
156 void setTriggerOverride(Trigger trigger);
157 void callOnSubscribe(bool v);
158 void createNewTrackLink(int& id, SignalLink*& trackLink);
159 void disconnectTrackLink(int id);
160 ExecutionContext* executionContext() const;
161 void clearExecutionContext();
162
163 protected:
164 boost::shared_ptr<SignalBasePrivate> _p;
165 friend class SignalBasePrivate;
166 };
167
168 template <typename... P> class Signal;
169
170 template<typename T>
171 class SignalF: public SignalBase, public boost::function<T>
172 {
173 public:
179 SignalF(OnSubscribers onSubscribers = OnSubscribers());
180 SignalF(ExecutionContext* execContext, OnSubscribers onSubscribers);
181 using FunctionType = T;
182 virtual qi::Signature signature() const;
183 using boost::function<T>::operator();
184
185 #ifdef DOXYGEN
186
209 SignalSubscriber connect(...);
210 #else
211 template <typename F>
212 SignalSubscriber connect(F c);
213 SignalSubscriber connect(AnyFunction func);
214 SignalSubscriber connect(const SignalSubscriber& sub);
215 template <typename U>
216 SignalSubscriber connect(SignalF<U>& signal);
217 template <typename... P>
218 SignalSubscriber connect(Signal<P...>& signal);
219
220 template <typename F, typename Arg0, typename... Args>
221 SignalSubscriber connect(F&& func, Arg0&& arg0, Args&&... args);
222
223 SignalSubscriber connect(const AnyObject& obj, unsigned int slot);
224 SignalSubscriber connect(const AnyObject& obj, const std::string& slot);
225 #endif
226
227 private:
228 template< class ForcedSignalType, class SignalType >
229 SignalSubscriber connectSignal(SignalType& signal);
230 };
231
236 template<typename... P>
237 class Signal: public SignalF<void(P...)>
238 {
239 public:
240 typedef void(FunctionType)(P...); // FIXME: VS2013 fails if this is replaced by `using`
241 using ParentType = SignalF<FunctionType>;
242 using OnSubscribers = typename ParentType::OnSubscribers;
243 Signal(OnSubscribers onSubscribers = OnSubscribers())
244 : ParentType(onSubscribers) {}
245 explicit Signal(ExecutionContext* execContext, OnSubscribers onSubscribers = OnSubscribers())
246 : ParentType(execContext, onSubscribers) {}
247 using boost::function<FunctionType>::operator();
248 };
249
250 template <>
251 class Signal<void> : public Signal<>
252 {};
253
254 struct SignalSubscriberPrivate;
255
263 QI_WARNING_PUSH()
264 QI_WARNING_DISABLE(4996, deprecated-declarations) // ignore linkId deprecation warnings
265 class QI_API SignalSubscriber
266 {
267 QI_WARNING_POP()
268 public:
269 friend class FunctorCall;
270 friend class ManageablePrivate;
271 friend class SignalBase;
272 friend class SignalBasePrivate;
273
274 SignalSubscriber();
275
276 SignalSubscriber(AnyFunction func, MetaCallType callType = MetaCallType_Auto);
277 SignalSubscriber(AnyFunction func, ExecutionContext* ec);
278 SignalSubscriber(const AnyObject& target, unsigned int method);
279
280 // This is copiable but not movable (never invalid).
281 SignalSubscriber(const SignalSubscriber& other);
282 SignalSubscriber& operator=(const SignalSubscriber& other);
283
284 ~SignalSubscriber();
285
293 void call(const GenericFunctionParameters& args, MetaCallType callType);
294
295 void call(const std::shared_ptr<GenericFunctionParameters>& args,
296 MetaCallType callType);
297
298 SignalSubscriber setCallType(MetaCallType ct);
299
301 SignalLink link() const;
302 operator SignalLink() const;
303
307 Signature signature() const;
308
309 private:
310 std::shared_ptr<SignalSubscriberPrivate> _p;
311
312 void callImpl(const GenericFunctionParameters& args);
313
314 boost::optional<ExecutionContext*> executionContextFor(MetaCallType callType) const;
315
316 // Call the subscriber with the given arguments, which can be passed by
317 // value or by pointer (any `Readable` will do).
318 //
319 // (GenericFunctionParameters || Readable<GenericFunctionParameters>) Args
320 template<typename Args>
321 void callWithValueOrPtr(const Args& args, MetaCallType callType);
322
323 public:
324 QI_API_DEPRECATED_MSG("please use link() instead or cast to qi::SignalLink")
325 SignalLink linkId;
326 };
327
328 using SignalSubscriberPtr = boost::shared_ptr<SignalSubscriber>;
329
330 struct SignalSubscriberPrivate
331 {
332 SignalSubscriberPrivate();
333 ~SignalSubscriberPrivate();
334
335 // Non-copyable
336 SignalSubscriberPrivate(const SignalSubscriberPrivate&) = delete;
337 SignalSubscriberPrivate& operator=(const SignalSubscriberPrivate&) = delete;
338
339 // Source information
340 boost::weak_ptr<SignalBasePrivate> source;
342 SignalLink linkId = SignalBase::invalidSignalLink;
343
344 // Target information, kept here to be able to introspect a Subscriber
345 // Mode 1: Direct functor call
346 AnyFunction handler;
347 MetaCallType threadingModel = MetaCallType_Direct;
348
349 // Mode 2: metaCall
350 boost::scoped_ptr<AnyWeakObject> target;
351 unsigned int method = 0;
352
353 // If enabled is set to false, no more callback will trigger
354 std::atomic<bool> enabled{true};
355
356 // ExecutionContext on which to schedule the call
357 std::atomic<ExecutionContext*> executionContext{nullptr};
358 };
359 } // qi
360
361 #ifdef _MSC_VER
362 # pragma warning( pop )
363 #endif
364
365 #include <qi/type/detail/signal.hxx>
366
367 QI_NO_TYPE(qi::SignalBase)
368
369 #endif // _QITYPE_SIGNAL_HPP_
qi::SignalSubscriberPrivate::target
boost::scoped_ptr< AnyWeakObject > target
Definition: signal.hpp:350
qi::GenericFunctionParameters
Definition: anyfunction.hpp:266
qi::SignalSubscriberPrivate::SignalSubscriberPrivate
SignalSubscriberPrivate()
QI_API
#define QI_API
Definition: api.hpp:33
qi::SignalSubscriberPrivate::linkId
SignalLink linkId
Uid that can be passed to GenericObject::disconnect()
Definition: signal.hpp:342
qi::Future
Definition: executioncontext.hpp:20
qi::SignalSubscriberPrivate::executionContext
std::atomic< ExecutionContext * > executionContext
Definition: signal.hpp:357
qi::AnyFunction
Definition: anyfunction.hpp:149
qi::SignalSubscriberPtr
boost::shared_ptr< SignalSubscriber > SignalSubscriberPtr
Definition: signal.hpp:328
qi::SignalBase::invalidSignalLink
static const SignalLink invalidSignalLink
Definition: signal.hpp:151
qi::Signature
Definition: signature.hpp:66
qi::SignalBase::_p
boost::shared_ptr< SignalBasePrivate > _p
Definition: signal.hpp:164
qi::MetaCallType_Auto
Honor the default behavior.
Definition: typeobject.hpp:26
qi::ExecutionContext
Definition: executioncontext.hpp:63
qi::Signal
Definition: signal.hpp:168
qi::Signal::Signal
Signal(ExecutionContext *execContext, OnSubscribers onSubscribers=OnSubscribers())
Definition: signal.hpp:245
qi::SignalSubscriberPrivate::enabled
std::atomic< bool > enabled
Definition: signal.hpp:354
qi::SignalSubscriberPrivate
Definition: signal.hpp:330
qi::SignalF::signature
virtual qi::Signature signature() const
Definition: signal.hxx:165
qi::SignalF< void(const AnyValue &)>::FunctionType
void(const AnyValue &) FunctionType
Definition: signal.hpp:181
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
QI_API_DEPRECATED_MSG
#define QI_API_DEPRECATED_MSG(msg__)
Compiler flags to mark a function as deprecated. It will generate a compiler warning.
Definition: macro.hpp:55
qi::SignalBase
Definition: signal.hpp:42
qi::SignalSubscriberPrivate::~SignalSubscriberPrivate
~SignalSubscriberPrivate()
qi::SignalSubscriberPrivate::threadingModel
MetaCallType threadingModel
Definition: signal.hpp:347
macro.hpp
Various macros for qi. (deprecated, export API, disallow copy, ..) <includename>qi/macro.hpp</includename> .
qi::SignalSubscriberPrivate::source
boost::weak_ptr< SignalBasePrivate > source
Definition: signal.hpp:340
qi::MetaCallType
MetaCallType
Definition: typeobject.hpp:24
typeobject.hpp
qi::Object< Empty >
qi::SignalSubscriberPrivate::operator=
SignalSubscriberPrivate & operator=(const SignalSubscriberPrivate &)=delete
qi::Signal::OnSubscribers
typename ParentType::OnSubscribers OnSubscribers
Definition: signal.hpp:242
qi::Signal::Signal
Signal(OnSubscribers onSubscribers=OnSubscribers())
Definition: signal.hpp:243
qi::SignalSubscriberPrivate::handler
AnyFunction handler
Definition: signal.hpp:346
qi::QI_WARNING_DISABLE
QI_WARNING_DISABLE(4996, deprecated-declarations) class SignalSubscriber
Definition: signal.hpp:264
signal.hxx
atomic.hpp
qi::SignalBase::Trigger
boost::function< void(const GenericFunctionParameters &params, MetaCallType callType)> Trigger
Definition: signal.hpp:154
qi::AutoAnyReference
Definition: anyreference.hpp:409
qi::SignalLink
qi::uint64_t SignalLink
Definition: signal.hpp:36
qi::SignalF::connect
SignalSubscriber connect(...)
Definition: signal.hxx:19
anyfunction.hpp
qi::SignalF::SignalF
SignalF(OnSubscribers onSubscribers=OnSubscribers())
Definition: signal.hxx:150
qi::uint64_t
uint64_t uint64_t
Definition: types.hpp:66
QI_NO_TYPE
#define QI_NO_TYPE(T)
Definition: typeinterface.hpp:48
qi::SignalSubscriberPrivate::method
unsigned int method
Definition: signal.hpp:351