- 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
proxysignal.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_TYPE_PROXYSIGNAL_HPP_
8 #define _QI_TYPE_PROXYSIGNAL_HPP_
9
10 #include <boost/bind.hpp>
11 #include <qi/signal.hpp>
12 #include <qi/anyfunction.hpp>
13 #include <qi/anyobject.hpp>
14
15 namespace qi
16 {
17
19 template<typename T>
20 class ProxySignal: public SignalF<T>
21 {
22 public:
23 using SignalType = SignalF<T>;
24 ProxySignal(AnyObject object, const std::string& signalName)
25 : SignalType()
26 {
27 setup(object, signalName);
28 }
29 ProxySignal() {}
30 ~ProxySignal();
31 void setup(AnyObject object, const std::string& signalName)
32 {
33 SignalBase::setOnSubscribers(boost::bind(&ProxySignal<T>::onSubscribe, this, _1,
34 object.asGenericObject(), signalName, SignalBase::invalidSignalLink));
35 SignalBase::setTriggerOverride(boost::bind(&ProxySignal<T>::triggerOverride, this, _1, _2,
36 object.asGenericObject(), signalName));
37 }
38 Future<void> onSubscribe(bool enable, GenericObject* object, std::string signalName, SignalLink link);
39 AnyReference bounceEvent(const AnyReferenceVector args);
40 void triggerOverride(const GenericFunctionParameters& params,
41 MetaCallType callType, GenericObject* object, std::string signalName);
42 };
43
44 template<typename T>
45 void makeProxySignal(SignalF<T>& target, AnyObject object, const std::string& signalName)
46 {
47 ProxySignal<T>& proxy = static_cast<ProxySignal<T> &>(target);
48 proxy.setup(object, signalName);
49 }
50
51 template<typename T>
52 void makeProxySignal(ProxySignal<T>& target, AnyObject object, const std::string& signalName)
53 {
54 target.setup(object, signalName);
55 }
56
57 template<typename T>
58 ProxySignal<T>::~ProxySignal()
59 {
60 SignalType::disconnectAll(); // will invoke onsubscribe
61 }
62
63 template<typename T>
64 qi::Future<void> ProxySignal<T>::onSubscribe(bool enable, GenericObject* object, std::string signalName,
65 SignalLink link)
66 {
67 Future<SignalLink> connectingOrDisconnecting = [=]
68 {
69 if (enable)
70 {
71 return object->connect(
72 signalName, SignalSubscriber(
73 AnyFunction::fromDynamicFunction(
74 boost::bind(&ProxySignal<T>::bounceEvent, this, _1)))).async();
75 }
76 else
77 {
78 return object->disconnect(link).async().then([](Future<void> f)
79 {
80 bool ok = !f.hasError();
81 if (!ok)
82 qiLogError("qitype.proxysignal") << "Failed to disconnect from parent signal";
83 return SignalBase::invalidSignalLink;
84 });
85 }
86 }();
87
88 boost::weak_ptr<SignalBasePrivate> weakP = this->_p;
89 return connectingOrDisconnecting.andThen([=](SignalLink link)
90 { // link changed, rebind ourselve if we're still alive
91 if (auto p = weakP.lock())
92 {
93 this->setOnSubscribers([=](bool enable) // TODO: remove `this->` after upgrading from GCC4.8
94 // Currently necessary because of a bug in g++4.8
95 {
96 return onSubscribe(enable, object, signalName, link);
97 });
98 }
99 });
100 }
101
102 template<typename T>
103 AnyReference ProxySignal<T>::bounceEvent(const AnyReferenceVector args)
104 {
105 // Trigger on our signal, bypassing our trigger overload
106 SignalType::callSubscribers(args);
107 return AnyReference(typeOf<void>());
108 }
109
110 template<typename T>
111 void ProxySignal<T>::triggerOverride(const GenericFunctionParameters& params, MetaCallType,
112 GenericObject* object, std::string signalName)
113 {
114 // Just forward to backend, which will notify us in bouceEvent(),
115 // and then we will notify our local Subscribers
116 object->metaPost(signalName, params);
117 }
118
119 }
120
121
122
123 #endif // _QITYPE_PROXYSIGNAL_HPP_
qi::ProxySignal::~ProxySignal
~ProxySignal()
Definition: proxysignal.hpp:58
qi::GenericFunctionParameters
Definition: anyfunction.hpp:266
qi::Future::connect
void connect(const AF &fun, FutureCallbackType type=FutureCallbackType_Auto)
Definition: future_fwd.hpp:545
qi::Future< void >
qi::AnyReference
Definition: anyreference.hpp:360
qi::SignalBase::invalidSignalLink
static const SignalLink invalidSignalLink
Definition: signal.hpp:151
qi::SignalBase::setOnSubscribers
void setOnSubscribers(OnSubscribers onSubscribers)
qi::ProxySignal::onSubscribe
Future< void > onSubscribe(bool enable, GenericObject *object, std::string signalName, SignalLink link)
Definition: proxysignal.hpp:64
qi::ProxySignal::ProxySignal
ProxySignal(AnyObject object, const std::string &signalName)
Definition: proxysignal.hpp:24
qi::SignalBase::setTriggerOverride
void setTriggerOverride(Trigger trigger)
qiLogError
#define qiLogError(...)
Log in error mode.
Definition: log.hpp:120
qi::ProxySignal
Signal proxy, using an AnyObject and signal id as backend.
Definition: proxysignal.hpp:20
qi::GenericObject
Definition: genericobject.hpp:41
qi::SignalF
Definition: signal.hpp:171
qi::AnyReferenceVector
std::vector< AnyReference > AnyReferenceVector
Definition: anyreference.hpp:26
signal.hpp
qi::MetaCallType
MetaCallType
Definition: typeobject.hpp:24
qi::Object< Empty >
qi::Future::andThen
auto andThen(FutureCallbackType type, F &&func) -> Future< typename std::decay< typename std::result_of< F(ValueType)>::type >::type >
Same as then(), but the callback is called only if this future finishes with a value.
Definition: future_fwd.hpp:506
qi::AnyFunction::fromDynamicFunction
static AnyFunction fromDynamicFunction(DynamicFunction f)
qi::ProxySignal::bounceEvent
AnyReference bounceEvent(const AnyReferenceVector args)
Definition: proxysignal.hpp:103
qi::makeProxySignal
void makeProxySignal(SignalF< T > &target, AnyObject object, const std::string &signalName)
Definition: proxysignal.hpp:45
qi::SignalLink
qi::uint64_t SignalLink
Definition: signal.hpp:36
anyfunction.hpp
anyobject.hpp
qi::ProxySignal::setup
void setup(AnyObject object, const std::string &signalName)
Definition: proxysignal.hpp:31
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::ProxySignal::triggerOverride
void triggerOverride(const GenericFunctionParameters &params, MetaCallType callType, GenericObject *object, std::string signalName)
Definition: proxysignal.hpp:111
qi::ProxySignal::ProxySignal
ProxySignal()
Definition: proxysignal.hpp:29
qi::Future::hasError
bool hasError(int msecs=FutureTimeout_Infinite) const
Definition: future_fwd.hpp:348