libqi-api  2.4.3.28
 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:
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 */
37 {
38 public:
39  /* We need a per-instance offset from effective type to Proxy.
40  * Avoid code explosion by putting it per-instance
41  */
42  typedef boost::function<Proxy*(void*)> ToProxy;
44  : toProxy(toProxy)
45  {
46  }
47  virtual const MetaObject& metaObject(void* instance)
48  {
49  Proxy* ptr = toProxy(instance);
50  return ptr->asObject().metaObject();
51  }
52  virtual qi::Future<AnyReference> metaCall(void* instance, AnyObject context, unsigned int method, const GenericFunctionParameters& params, MetaCallType callType, Signature returnSignature)
53  {
54  Proxy* ptr = toProxy(instance);
55  return ptr->asObject().metaCall(method, params, callType, returnSignature);
56  }
57  virtual void metaPost(void* instance, AnyObject context, unsigned int signal, const GenericFunctionParameters& params)
58  {
59  Proxy* ptr = toProxy(instance);
60  ptr->asObject().metaPost(signal, params);
61  }
62  virtual qi::Future<SignalLink> connect(void* instance, AnyObject context, unsigned int event, const SignalSubscriber& subscriber)
63  {
64  Proxy* ptr = toProxy(instance);
65  return ptr->asObject().connect(event, subscriber);
66  }
67  virtual qi::Future<void> disconnect(void* instance, AnyObject context, SignalLink linkId)
68  {
69  Proxy* ptr = toProxy(instance);
70  return ptr->asObject().disconnect(linkId);
71  }
72  virtual const std::vector<std::pair<TypeInterface*, int> >& parentTypes()
73  {
74  static std::vector<std::pair<TypeInterface*, int> > empty;
75  return empty;
76  }
77  virtual qi::Future<AnyValue> property(void* instance, AnyObject context, unsigned int id)
78  {
79  Proxy* ptr = toProxy(instance);
80  GenericObject* obj = ptr->asObject().asGenericObject();
81  return obj->type->property(obj->value, context, id);
82  }
83  virtual qi::Future<void> setProperty(void* instance, AnyObject context, unsigned int id, AnyValue value)
84  {
85  Proxy* ptr = toProxy(instance);
86  GenericObject* obj = ptr->asObject().asGenericObject();
87  return obj->type->setProperty(obj->value, context, id, value);
88  }
92 };
93 
94 /* We limit usage of per-class type for generated proxies
95  *to non-interface mode
96  * where it is needed.
97  */
98 template<typename T> struct TypeProxyWrapper: public TypeProxy
99 {
100  typedef boost::function<Proxy*(void*)> ToProxy;
102  : TypeProxy(toProxy)
103  {
104  }
107 };
108 // Needed for legacy code
109 //template<> struct TypeImpl<Proxy>: public TypeProxy {};
110 
111 namespace detail
112 {
113  // FIXME: inline that in QI_REGISTER_PROXY_INTERFACE maybe
114  template<typename ProxyImpl> Proxy* static_proxy_cast(void* storage)
115  {
116  return static_cast<Proxy*>((ProxyImpl*)storage);
117  }
118 
119  template<typename ProxyImpl>
121  {
122  static TypeProxy * result = 0;
123  if (!result)
124  result = new TypeProxyWrapper<ProxyImpl>(&static_proxy_cast<ProxyImpl>);
125  return result;
126  }
127 
128  template<typename ProxyImpl>
130  {
131  static TypeProxy * result = 0;
132  if (!result)
133  result = new TypeProxy(&static_proxy_cast<ProxyImpl>);
134  return result;
135  }
136 
137  template<typename ProxyImpl>
139  {
140  boost::shared_ptr<ProxyImpl> sp(new ProxyImpl(ptr));
141  return AnyReference::from(sp).clone();
142  }
143 }
144 
151 template<typename Proxy, typename Interface>
153 {
154  qiLogVerbose("qitype.type") << "ProxyInterface registration " << typeOf<Interface>()->infoString();
155  // Runtime-register TypeInterface for Proxy, using ProxyInterface with
156  // proper static_cast (from Proxy template to qi::Proxy) helper.
157  registerType(typeid(Proxy), detail::makeProxyInterface<Proxy>());
159  map[typeOf<Interface>()->info()] = boost::function<AnyReference(AnyObject)>(&detail::makeProxy<Proxy>);
160  return true;
161 }
162 
168 template<typename ProxyType>
170 {
171  /* In non-interface mode, we need one different registered type
172  * per Proxy class, otherwise they will all land in the same
173  * bucket of proxyGeneratorMap.
174  * In interface mode this problem is absent because the TypeInfo
175  * of the interface is used (not the one of the proxy).
176  */
177  registerType(typeid(ProxyType), detail::makeProxyInterfaceWrapper<ProxyType>());
179  map[typeOf<ProxyType>()->info()] = boost::function<AnyReference(AnyObject)>(&detail::makeProxy<ProxyType>);
180  return true;
181 }
182 
183 }
184 
185 #define QI_REGISTER_PROXY(Proxy) \
186  namespace { \
187  static bool BOOST_PP_CAT(_qi_register_proxy_, Proxy) = \
188  ::qi::registerProxy<Proxy>(); \
189  }
190 
191 #define QI_REGISTER_PROXY_INTERFACE(Proxy, Interface) \
192  namespace { \
193  static bool BOOST_PP_CAT(_qi_register_proxy_, Proxy) = \
194  ::qi::registerProxyInterface<Proxy, Interface>(); \
195  }
196 
197 #endif
TypeProxyWrapper(ToProxy toProxy)
GenericObject * asGenericObject() const
Definition: object.hxx:523
#define QI_API
Definition: api.hpp:34
qi::FutureSync< void > disconnect(SignalLink linkId) const
Definition: object.hxx:120
_QI_BOUNCE_TYPE_METHODS(Methods)
bool registerProxyInterface()
boost::function< Proxy *(void *)> ToProxy
T & asT()
Definition: object.hxx:493
virtual qi::Future< AnyValue > property(void *instance, AnyObject context, unsigned int id)
#define qiLogDebug(...)
Definition: log.hpp:69
#define qiLogVerbose(...)
Log in verbose mode. This level is not shown by default.
Definition: log.hpp:80
TypeProxy * makeProxyInterface()
DefaultTypeImplMethods< Proxy > Methods
qi::FutureSync< SignalLink > connect(const std::string &eventName, FUNCTOR_TYPE callback, MetaCallType threadingModel=MetaCallType_Auto) const
Definition: object.hxx:105
virtual qi::Future< void > setProperty(void *instance, AnyObject context, unsigned int id, AnyValue value)=0
virtual qi::Future< AnyValue > property(void *instance, AnyObject context, unsigned int id)=0
virtual qi::Future< void > disconnect(void *instance, AnyObject context, SignalLink linkId)
Disconnect an event link. Returns if disconnection was successful.
bool registerType(const std::type_info &typeId, TypeInterface *type)
Runtime Type factory setter.
TypeProxy * makeProxyInterfaceWrapper()
TypeProxy(ToProxy toProxy)
ProxyGeneratorMap & proxyGeneratorMap()
Object< Empty > asObject() const
virtual const MetaObject & metaObject(void *instance)
virtual qi::Future< AnyReference > metaCall(void *instance, AnyObject context, unsigned int method, const GenericFunctionParameters &params, MetaCallType callType, Signature returnSignature)
const MetaObject & metaObject() const
Definition: object.hxx:71
virtual qi::Future< SignalLink > connect(void *instance, AnyObject context, unsigned int event, const SignalSubscriber &subscriber)
void metaPost(unsigned int event, const GenericFunctionParameters &params) const
Definition: object.hxx:84
ObjectTypeInterface * type
virtual void metaPost(void *instance, AnyObject context, unsigned int signal, const GenericFunctionParameters &params)
MetaCallType
Definition: typeobject.hpp:19
Object< Empty > _obj
DefaultTypeImplMethods< T > Methods
Proxy(AnyObject obj)
AnyReference makeProxy(AnyObject ptr)
Object< Empty > AnyObject
Definition: anyobject.hpp:21
AnyReference clone() const
_QI_BOUNCE_TYPE_METHODS(Methods)
boost::function< Proxy *(void *)> ToProxy
qi::Future< AnyReference > metaCall(unsigned int method, const GenericFunctionParameters &params, MetaCallType callType=MetaCallType_Auto, Signature returnSignature=Signature()) const
Definition: object.hxx:72
virtual const std::vector< std::pair< TypeInterface *, int > > & parentTypes()
std::map< TypeInfo, boost::function< AnyReference(AnyObject)> > ProxyGeneratorMap
Definition: object.hxx:45
static AnyReference from(const T &ref)
qi::uint64_t SignalLink
Definition: signal.hpp:33
bool registerProxy()
virtual qi::Future< void > setProperty(void *instance, AnyObject context, unsigned int id, AnyValue value)
Proxy * static_proxy_cast(void *storage)
int context()
Get log context.
Description of the signals and methods accessible on an ObjectTypeInterface.
Definition: metaobject.hpp:25