- 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
proxyregister.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 _QITYPE_DETAIL_PROXY_REGISTER_HPP_
8 #define _QITYPE_DETAIL_PROXY_REGISTER_HPP_
9
10 namespace qi
11 {
12
16 class QI_API Proxy : public boost::noncopyable
17 {
18 public:
19 Proxy(AnyObject obj) : _obj(obj) {qiLogDebug("qitype.proxy") << "Initializing " << this;}
20 Proxy() {}
21 ~Proxy() { qiLogDebug("qitype.proxy") << "Finalizing on " << this;}
22 Object<Empty> asObject() const;
23 protected:
24 Object<Empty> _obj;
25 };
26
27 inline AnyObject Proxy::asObject() const
28 {
29 qiLogDebug("qitype.proxy") << "asObject " << this << ' ' << &_obj.asT();
30 return AnyObject(_obj);
31 }
32
33 /* A proxy instance can have members: signals and properties, inherited from interface.
34 * So it need a type of its own, we cannot pretend it's a AnyObject.
35 */
36 template<class InterfaceType, class ProxyType>
37 class TypeProxy: public ObjectTypeInterface
38 {
39 public:
40 /* We need a per-instance offset from effective type to Proxy.
41 * Avoid code explosion by putting it per-instance
42 */
43 using ToProxy = boost::function<Proxy*(void*)>;
44 TypeProxy(ToProxy toProxy)
45 : toProxy(toProxy)
46 {
47 }
48 const MetaObject& metaObject(void* instance) override
49 {
50 Proxy* ptr = toProxy(instance);
51 return ptr->asObject().metaObject();
52 }
53
54 ObjectUid uid(void* instance) const override
55 {
56 QI_ASSERT_TRUE(instance);
57 Proxy* ptr = toProxy(instance);
58 return ptr->asObject().uid();
59 }
60
61 qi::Future<AnyReference> metaCall(void* instance, AnyObject context, unsigned int method, const GenericFunctionParameters& params, MetaCallType callType, Signature returnSignature) override
62 {
63 Proxy* ptr = toProxy(instance);
64 return ptr->asObject().metaCall(method, params, callType, returnSignature);
65 }
66 void metaPost(void* instance, AnyObject context, unsigned int signal, const GenericFunctionParameters& params) override
67 {
68 Proxy* ptr = toProxy(instance);
69 ptr->asObject().metaPost(signal, params);
70 }
71 qi::Future<SignalLink> connect(void* instance, AnyObject context, unsigned int event, const SignalSubscriber& subscriber) override
72 {
73 Proxy* ptr = toProxy(instance);
74 return ptr->asObject().connect(event, subscriber);
75 }
76 qi::Future<void> disconnect(void* instance, AnyObject context, SignalLink linkId) override
77 {
78 Proxy* ptr = toProxy(instance);
79 return ptr->asObject().disconnect(linkId);
80 }
81 const std::vector<std::pair<TypeInterface*, std::ptrdiff_t> >& parentTypes() override
82 {
83 using ReturnType = typename std::decay<decltype(parentTypes())>::type;
84 static ReturnType* parents = nullptr;
85
86 static const auto init = []{ return new ReturnType{
87 { qi::typeOf<InterfaceType>(), []{
88 ProxyType* ptr = static_cast<ProxyType*>(reinterpret_cast<void*>(0x10000));
89 InterfaceType* pptr = ptr;
90 std::ptrdiff_t offset = reinterpret_cast<intptr_t>(pptr)-reinterpret_cast<intptr_t>(ptr);
91 return offset;
92 }()
93 }
94 };
95 };
96
97 QI_ONCE(parents = init());
98
99 return *parents;
100 }
101 qi::Future<AnyValue> property(void* instance, AnyObject context, unsigned int id) override
102 {
103 Proxy* ptr = toProxy(instance);
104 GenericObject* obj = ptr->asObject().asGenericObject();
105 return obj->type->property(obj->value, context, id);
106 }
107 qi::Future<void> setProperty(void* instance, AnyObject context, unsigned int id, AnyValue value) override
108 {
109 Proxy* ptr = toProxy(instance);
110 GenericObject* obj = ptr->asObject().asGenericObject();
111 return obj->type->setProperty(obj->value, context, id, value);
112 }
113 using Methods = DefaultTypeImplMethods<Proxy>;
114 _QI_BOUNCE_TYPE_METHODS(Methods);
115 ToProxy toProxy;
116 };
117
118 namespace detail
119 {
120 // FIXME: inline that in QI_REGISTER_PROXY_INTERFACE maybe
121 template<typename ProxyImpl> Proxy* static_proxy_cast(void* storage)
122 {
123 return static_cast<Proxy*>((ProxyImpl*)storage);
124 }
125
126 template<class InterfaceType, typename ProxyImpl>
127 TypeProxy<InterfaceType, ProxyImpl>* makeProxyInterface()
128 {
129 static TypeProxy<InterfaceType, ProxyImpl>* result = 0;
130 if (!result)
131 result = new TypeProxy<InterfaceType, ProxyImpl>(&static_proxy_cast<ProxyImpl>);
132 return result;
133 }
134
135 template<typename ProxyImpl>
136 AnyReference makeProxy(AnyObject ptr)
137 {
138 boost::shared_ptr<ProxyImpl> sp(new ProxyImpl(ptr));
139 return AnyReference::from(sp).clone();
140 }
141 }
142
149 template<typename Proxy, typename Interface>
150 bool registerProxyInterface()
151 {
152 qiLogVerbose("qitype.type") << "ProxyInterface registration " << typeOf<Interface>()->infoString();
153 // Runtime-register TypeInterface for Proxy, using ProxyInterface with
154 // proper static_cast (from Proxy template to qi::Proxy) helper.
155 registerType(qi::typeId<Proxy>(), detail::makeProxyInterface<Interface, Proxy>());
156 detail::ProxyGeneratorMap& map = detail::proxyGeneratorMap();
157 map[typeOf<Interface>()->info()] = boost::function<AnyReference(AnyObject)>(&detail::makeProxy<Proxy>);
158 return true;
159 }
160
161 }
162
163 #define QI_REGISTER_PROXY(Proxy) \
164 namespace { \
165 static bool BOOST_PP_CAT(_qi_register_proxy_, Proxy) QI_ATTR_UNUSED = \
166 ::qi::registerProxy<Proxy>(); \
167 }
168
169 #define QI_REGISTER_PROXY_INTERFACE(Proxy, Interface) \
170 namespace { \
171 static bool BOOST_PP_CAT(_qi_register_proxy_, Proxy) QI_ATTR_UNUSED = \
172 ::qi::registerProxyInterface<Proxy, Interface>(); \
173 }
174
175 #endif
qi::Object::asGenericObject
GenericObject * asGenericObject() const
Definition: object.hxx:652
qi::AnyValue
Definition: anyvalue.hpp:19
qi::GenericFunctionParameters
Definition: anyfunction.hpp:266
qi::TypeProxy::_QI_BOUNCE_TYPE_METHODS
_QI_BOUNCE_TYPE_METHODS(Methods)
QI_API
#define QI_API
Definition: api.hpp:33
qi::detail::GenericObjectBounce::disconnect
qi::FutureSync< void > disconnect(SignalLink linkId) const
Definition: object.hxx:106
qi::TypeProxy::property
qi::Future< AnyValue > property(void *instance, AnyObject context, unsigned int id) override
Definition: proxyregister.hpp:101
qi::registerProxyInterface
bool registerProxyInterface()
Definition: proxyregister.hpp:150
qi::TypeProxy::toProxy
ToProxy toProxy
Definition: proxyregister.hpp:115
qi::registerType
bool registerType(const TypeIndex &typeId, TypeInterface *type)
Runtime Type factory setter.
qi::Future
Definition: executioncontext.hpp:20
qi::TypeProxy::disconnect
qi::Future< void > disconnect(void *instance, AnyObject context, SignalLink linkId) override
Disconnect an event link. Returns if disconnection was successful.
Definition: proxyregister.hpp:76
qi::TypeProxy::metaObject
const MetaObject & metaObject(void *instance) override
Definition: proxyregister.hpp:48
qi::Proxy::~Proxy
~Proxy()
Definition: proxyregister.hpp:21
qi::TypeProxy::ToProxy
boost::function< Proxy *(void *)> ToProxy
Definition: proxyregister.hpp:43
qiLogDebug
#define qiLogDebug(...)
Definition: log.hpp:76
qi::AnyReference
Definition: anyreference.hpp:360
qi::Signature
Definition: signature.hpp:66
qiLogVerbose
#define qiLogVerbose(...)
Log in verbose mode. This level is not shown by default.
Definition: log.hpp:87
qi::Proxy
Definition: proxyregister.hpp:16
qi::TypeProxy::setProperty
qi::Future< void > setProperty(void *instance, AnyObject context, unsigned int id, AnyValue value) override
Definition: proxyregister.hpp:107
qi::detail::GenericObjectBounce::connect
qi::FutureSync< SignalLink > connect(const std::string &eventName, FUNCTOR_TYPE callback, MetaCallType threadingModel=MetaCallType_Auto) const
Definition: object.hxx:91
qi::ObjectTypeInterface::setProperty
virtual qi::Future< void > setProperty(void *instance, AnyObject context, unsigned int id, AnyValue value)=0
qi::Object::asT
T & asT() const
Definition: object.hxx:635
qi::ObjectTypeInterface::property
virtual qi::Future< AnyValue > property(void *instance, AnyObject context, unsigned int id)=0
qi::TypeProxy::metaPost
void metaPost(void *instance, AnyObject context, unsigned int signal, const GenericFunctionParameters &params) override
Definition: proxyregister.hpp:66
qi::TypeProxy::parentTypes
const std::vector< std::pair< TypeInterface *, std::ptrdiff_t > > & parentTypes() override
Definition: proxyregister.hpp:81
qi::TypeProxy::connect
qi::Future< SignalLink > connect(void *instance, AnyObject context, unsigned int event, const SignalSubscriber &subscriber) override
Definition: proxyregister.hpp:71
qi::detail::makeProxyInterface
TypeProxy< InterfaceType, ProxyImpl > * makeProxyInterface()
Definition: proxyregister.hpp:127
qi::detail::proxyGeneratorMap
ProxyGeneratorMap & proxyGeneratorMap()
qi::Proxy::asObject
Object< Empty > asObject() const
Definition: proxyregister.hpp:27
qi::GenericObject
Definition: genericobject.hpp:41
qi::Proxy::Proxy
Proxy()
Definition: proxyregister.hpp:20
qi::detail::ProxyGeneratorMap
std::map< TypeInfo, boost::function< AnyReference(AnyObject)>> ProxyGeneratorMap
Definition: object.hxx:38
qi::detail::GenericObjectBounce::metaObject
const MetaObject & metaObject() const
Definition: object.hxx:64
qi::detail::GenericObjectBounce::metaPost
void metaPost(unsigned int event, const GenericFunctionParameters &params) const
Definition: object.hxx:77
qi::GenericObject::type
ObjectTypeInterface * type
Definition: genericobject.hpp:139
qi::DefaultTypeImplMethods
Definition: typeimpl.hxx:228
qi::ObjectTypeInterface
Definition: typeobject.hpp:48
QI_ONCE
#define QI_ONCE(code)
Execute code once, parallel calls are blocked until code finishes.
Definition: atomic.hpp:420
qi::MetaCallType
MetaCallType
Definition: typeobject.hpp:24
qi::Proxy::_obj
Object< Empty > _obj
Definition: proxyregister.hpp:24
qi::TypeInterface::infoString
const char * infoString()
Definition: typeinterface.hpp:178
qi::TypeInterface::info
virtual const TypeInfo & info()=0
Get the TypeInfo corresponding to this type.
qi::Proxy::Proxy
Proxy(AnyObject obj)
Definition: proxyregister.hpp:19
qi::Object< Empty >
qi::detail::makeProxy
AnyReference makeProxy(AnyObject ptr)
Definition: proxyregister.hpp:136
qi::TypeProxy::uid
ObjectUid uid(void *instance) const override
Definition: proxyregister.hpp:54
qi::AnyObject
Object< Empty > AnyObject
Definition: anyobject.hpp:21
QI_ASSERT_TRUE
#define QI_ASSERT_TRUE(expr__)
Definition: assert.hpp:31
qi::detail::AnyReferenceBase::clone
AnyReference clone() const
Definition: anyreference.hxx:18
qi::detail::GenericObjectBounce::metaCall
qi::Future< AnyReference > metaCall(unsigned int method, const GenericFunctionParameters &params, MetaCallType callType=MetaCallType_Auto, Signature returnSignature=Signature()) const
Definition: object.hxx:65
qi::TypeProxy::metaCall
qi::Future< AnyReference > metaCall(void *instance, AnyObject context, unsigned int method, const GenericFunctionParameters &params, MetaCallType callType, Signature returnSignature) override
Definition: proxyregister.hpp:61
qi::detail::AnyReferenceBase::from
static AnyReference from(const T &ref)
Definition: anyreference.hxx:64
qi::SignalLink
qi::uint64_t SignalLink
Definition: signal.hpp:36
qi::GenericObject::value
void * value
Definition: genericobject.hpp:140
qi::detail::static_proxy_cast
Proxy * static_proxy_cast(void *storage)
Definition: proxyregister.hpp:121
qi::TypeProxy::TypeProxy
TypeProxy(ToProxy toProxy)
Definition: proxyregister.hpp:44
qi::log::init
void init(qi::LogLevel verb=qi::LogLevel_Info, qi::LogContext context=qi::LogContextAttr_ShortVerbosity|qi::LogContextAttr_Tid|qi::LogContextAttr_Category, bool synchronous=true)
Initialization of the logging system Creates and registers the default log handler according to QI_DE...
qi::PtrUid
Definition: ptruid.hpp:33
qi::TypeProxy
Definition: proxyregister.hpp:37
qi::log::context
int context()
Get log context.
qi::MetaObject
Description of the signals and methods accessible on an ObjectTypeInterface.
Definition: metaobject.hpp:25