- 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
proxyproperty.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_PROXYPROPERTY_HPP_
8 #define _QI_TYPE_PROXYPROPERTY_HPP_
9
10 #include <qi/log.hpp>
11 #include <qi/property.hpp>
12 #include <qi/anyfunction.hpp>
13
14
15 namespace qi
16 {
21 template < typename T, template< class...> class PropertyType = Property >
22 class ProxyProperty: public PropertyType<T>
23 {
24 public:
25 using SignalType = SignalF<void (const T&)>;
26 using ThisProxyType = ProxyProperty;
27 ProxyProperty() {}
28 /* The signal bounce code is completely duplicated from SignalProxy.
29 * Unfortunately factoring this is not trivial:
30 * onSubscribe needs to be passed to Signal constructor, and we want to keep
31 * it that way.
32 */
33 ProxyProperty(AnyObject object, const std::string& propertyName)
34 {
35 setup(object, propertyName);
36 }
37 void setup(AnyObject object, const std::string& propertyName);
38 ~ProxyProperty();
39 Future<void> onSubscribe(bool enable, GenericObject* object, const std::string& propertyName, SignalLink link);
40 AnyReference bounceEvent(const AnyReferenceVector args);
41 void triggerOverride(const GenericFunctionParameters& params, MetaCallType, GenericObject* object, const std::string& propertyName);
42 private:
43 T getter(GenericObject* object, const std::string& propertyName);
44 bool setter(T&, const T&, GenericObject* object, const std::string& propertyName);
45 };
46
47 template<typename T, template< class...> class PropertyType>
48 void makeProxyProperty(PropertyType<T>& target, AnyObject object, const std::string& signalName)
49 {
50 ProxyProperty<T, PropertyType>& proxy = static_cast<ProxyProperty<T, PropertyType> &>(target);
51 proxy.setup(object, signalName);
52 }
53 template<typename T, template< class...> class PropertyType>
54 void makeProxyProperty(ProxyProperty<T, PropertyType>& target, AnyObject object, const std::string& signalName)
55 {
56 target.setup(object, signalName);
57 }
58
59 template<typename T, template< class...> class PropertyType>
60 ProxyProperty<T, PropertyType>::~ProxyProperty()
61 {
62 SignalType::disconnectAll();
63 }
64
65 template<typename T, template< class...> class PropertyType>
66 void ProxyProperty<T, PropertyType>::setup(AnyObject object, const std::string& propertyName)
67 {
68 // signal part
69 SignalBase::setOnSubscribers(boost::bind(&ThisProxyType::onSubscribe, this, _1,
70 object.asGenericObject(), propertyName, SignalBase::invalidSignalLink));
71 SignalBase::setTriggerOverride(boost::bind(&ThisProxyType::triggerOverride, this, _1, _2,
72 object.asGenericObject(), propertyName));
73
74 // property part
75 this->_getter = boost::bind(&ThisProxyType::getter, this, object.asGenericObject(), propertyName);
76 this->_setter = boost::bind(&ThisProxyType::setter, this, _1, _2, object.asGenericObject(), propertyName);
77 }
78
79 template<typename T, template< class...> class PropertyType>
80 Future<void> ProxyProperty<T, PropertyType>::onSubscribe(bool enable, GenericObject* object, const std::string& propertyName, SignalLink link)
81 {
82 if (enable)
83 {
84 link = object->connect(propertyName,
85 SignalSubscriber(
86 AnyFunction::fromDynamicFunction(boost::bind(&ThisProxyType::bounceEvent, this, _1))
87 )).value();
88 }
89 else
90 {
91 bool ok = !object->disconnect(link).hasError();
92 if (!ok)
93 qiLogError("qitype.proxysignal") << "Failed to disconnect from parent signal";
94 link = SignalBase::invalidSignalLink;
95 }
96 // rebind onSubscribe since link changed
97 SignalBase::setOnSubscribers(boost::bind(&ThisProxyType::onSubscribe, this, _1,
98 object, propertyName, link));
99 return Future<void>{nullptr};
100 }
101
102 template<typename T, template< class...> class PropertyType>
103 AnyReference ProxyProperty<T, PropertyType>::bounceEvent(const AnyReferenceVector args)
104 {
105 // Receive notify from backend, trigger on our signal, bypassing our trigger overload
106 SignalType::callSubscribers(args);
107 return AnyReference(typeOf<void>());
108 }
109
110 template<typename T, template< class...> class PropertyType>
111 void ProxyProperty<T, PropertyType>::triggerOverride(const GenericFunctionParameters& params, MetaCallType,
112 GenericObject* object, const std::string& propertyName)
113 {
114 // Just forward to backend, which will notify us in bouceEvent(),
115 // and then we will notify our local Subscribers
116 object->metaPost(propertyName, params);
117 }
118 template<typename T, template< class...> class PropertyType>
119 T ProxyProperty<T, PropertyType>::getter(GenericObject* object, const std::string& propertyName)
120 {
121 return object->property<T>(propertyName).value();
122 }
123 template<typename T, template< class...> class PropertyType>
124 bool ProxyProperty<T, PropertyType>::setter(T& target, const T& v, GenericObject* object, const std::string& propertyName)
125 {
126 // no need to fill target it's never used since we have a getter
127 object->setProperty(propertyName, v).value(); // throw on remote error
128 // Prevent local subscribers from being called
129 return false;
130 }
131 }
132 #endif // _QITYPE_PROXYPROPERTY_HPP_
qi::ProxyProperty
Definition: proxyproperty.hpp:22
qi::ProxyProperty::ProxyProperty
ProxyProperty(AnyObject object, const std::string &propertyName)
Definition: proxyproperty.hpp:33
qi::GenericFunctionParameters
Definition: anyfunction.hpp:266
qi::Future::connect
void connect(const AF &fun, FutureCallbackType type=FutureCallbackType_Auto)
Definition: future_fwd.hpp:545
qi::ProxyProperty::onSubscribe
Future< void > onSubscribe(bool enable, GenericObject *object, const std::string &propertyName, SignalLink link)
Definition: proxyproperty.hpp:80
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::ProxyProperty::bounceEvent
AnyReference bounceEvent(const AnyReferenceVector args)
Definition: proxyproperty.hpp:103
qi::SignalBase::setTriggerOverride
void setTriggerOverride(Trigger trigger)
qiLogError
#define qiLogError(...)
Log in error mode.
Definition: log.hpp:120
property.hpp
qi::makeProxyProperty
void makeProxyProperty(PropertyType< T > &target, AnyObject object, const std::string &signalName)
Definition: proxyproperty.hpp:48
qi::GenericObject
Definition: genericobject.hpp:41
qi::ProxyProperty::setup
void setup(AnyObject object, const std::string &propertyName)
Definition: proxyproperty.hpp:66
qi::SignalF< void(const T &)>
qi::AnyReferenceVector
std::vector< AnyReference > AnyReferenceVector
Definition: anyreference.hpp:26
qi::ProxyProperty::~ProxyProperty
~ProxyProperty()
Definition: proxyproperty.hpp:60
qi::ProxyProperty::triggerOverride
void triggerOverride(const GenericFunctionParameters &params, MetaCallType, GenericObject *object, const std::string &propertyName)
Definition: proxyproperty.hpp:111
qi::MetaCallType
MetaCallType
Definition: typeobject.hpp:24
qi::Object< Empty >
qi::AnyFunction::fromDynamicFunction
static AnyFunction fromDynamicFunction(DynamicFunction f)
log.hpp
Convenient log macro.
qi::SignalLink
qi::uint64_t SignalLink
Definition: signal.hpp:36
anyfunction.hpp
qi::ProxyProperty::ProxyProperty
ProxyProperty()
Definition: proxyproperty.hpp:27
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