- 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
objecttypebuilder.hxx
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_OBJECTTYPEBUILDER_HXX_
8 #define _QITYPE_DETAIL_OBJECTTYPEBUILDER_HXX_
9
10 #include <boost/function_types/is_member_function_pointer.hpp>
11 #include <boost/mpl/front.hpp>
12 #include <qi/type/objecttypebuilder.hpp>
13 #include <qi/type/metamethod.hpp>
14 #include <qi/actor.hpp>
15
16 namespace qi {
17
18 namespace detail {
19 template <typename T>
20 qi::Strand* callWithVoid(qi::Strand* (T::*member)() const, void* instance)
21 {
22 return (static_cast<T*>(instance)->*member)();
23 }
24
25 template <typename T>
26 typename boost::enable_if<boost::is_base_of<Actor, T>, AnyFunction>::type
27 getStrandAccessor()
28 {
29 return AnyFunction::from(boost::function<qi::Strand*(void*)>(
30 boost::bind(&callWithVoid<T>, &T::strand, _1)));
31 }
32 template <typename T>
33 typename boost::disable_if<boost::is_base_of<Actor, T>, AnyFunction>::type
34 getStrandAccessor()
35 {
36 return AnyFunction();
37 }
38 }
39
40 template<typename T> void ObjectTypeBuilderBase::buildFor(bool autoRegister)
41 {
42 // We are erasing T here: we must pass everything the builder need to know about t:
43 // - typeid
44 // - cloner/deleter
45 // - serializer, ...
46 // => wee need all TypeInterface* methods, but we do not want another TypeInterface*
47 // to anwser to typeOf<T>
48 xBuildFor(new DefaultTypeImpl<T>(), autoRegister, detail::getStrandAccessor<T>());
49
50 if (std::is_base_of<Actor, T>::value)
51 setThreadingModel(ObjectThreadingModel_SingleThread);
52 else
53 setThreadingModel(ObjectThreadingModel_MultiThread);
54 }
55
56 template <typename FUNCTION_TYPE>
57 unsigned int ObjectTypeBuilderBase::advertiseMethod(const std::string& name,
58 FUNCTION_TYPE function,
59 MetaCallType threadingModel,
60 int id)
61 {
62 MetaMethodBuilder builder;
63 AnyFunction f = AnyFunction::from(function);
64 builder.setName(name);
65 builder.setSignature(f);
66
67 // throw on error
68 return xAdvertiseMethod(builder, f, threadingModel, id);
69 }
70
71 template <typename FUNCTION_TYPE>
72 unsigned int ObjectTypeBuilderBase::advertiseMethod(MetaMethodBuilder& builder,
73 FUNCTION_TYPE function,
74 MetaCallType threadingModel,
75 int id)
76 {
77 AnyFunction f = AnyFunction::from(function);
78 builder.setSignature(f);
79
80 // throw on error
81 return xAdvertiseMethod(builder, f, threadingModel, id);
82 }
83
84 template<typename U>
85 void ObjectTypeBuilderBase::inherits(std::ptrdiff_t offset)
86 {
87 return inherits(typeOf<
88 typename boost::remove_reference<U>::type>(), offset);
89 }
90
91 template<typename T>
92 template<typename U>
93 void ObjectTypeBuilder<T>::inherits()
94 {
95 qiLogCategory("qitype.objectbuilder");
96 // Compute the offset between T and U
97 T* ptr = reinterpret_cast<T*>(0x10000);
98 U* pptr = ptr;
99 std::ptrdiff_t offset = reinterpret_cast<intptr_t>(pptr) - reinterpret_cast<intptr_t>(ptr);
100 qiLogDebug() << "Offset check T(" << qi::typeIdRuntime(ptr).name() << ")= " << ptr
101 << ", U(" << qi::typeIdRuntime(pptr).name() << ")= " << pptr << ", T-U= " << offset;
102 return ObjectTypeBuilderBase::inherits<U>(offset);
103 }
104
105 namespace detail
106 {
107 template<typename F, typename T> void checkRegisterParent(
108 ObjectTypeBuilder<T>& , boost::false_type) {}
109 template<typename F, typename T> void checkRegisterParent(
110 ObjectTypeBuilder<T>& builder, boost::true_type)
111 {
112 using ArgsType = typename boost::function_types::parameter_types<F>::type;
113 using DecoratedClassType = typename boost::mpl::front<ArgsType>::type;
114 using ClassType = typename boost::remove_reference<DecoratedClassType>::type;
115 builder.template inherits<ClassType>();
116 }
117 };
118
119 template <typename T>
120 template <typename FUNCTION_TYPE>
121 unsigned int ObjectTypeBuilder<T>::advertiseMethod(const std::string& name, FUNCTION_TYPE function, MetaCallType threadingModel, int id)
122 {
123 // Intercept advertise to auto-register parent type if this is a parent method
124 // Note: if FUNCTION_TYPE is a grandparent method, we will incorrectly add it
125 // as a child
126 detail::checkRegisterParent<FUNCTION_TYPE>(
127 *this,
128 typename boost::function_types::is_member_function_pointer<FUNCTION_TYPE >::type());
129
130 // throw on error
131 return ObjectTypeBuilderBase::advertiseMethod(name, function, threadingModel, id);
132 }
133
134 template <typename T>
135 template <typename FUNCTION_TYPE>
136 unsigned int ObjectTypeBuilder<T>::advertiseMethod(MetaMethodBuilder& name, FUNCTION_TYPE function, MetaCallType threadingModel, int id)
137 {
138 // Intercept advertise to auto-register parent type if this is a parent method
139 // Note: if FUNCTION_TYPE is a grandparent method, we will incorrectly add it
140 // as a child
141 detail::checkRegisterParent<FUNCTION_TYPE>(
142 *this,
143 typename boost::function_types::is_member_function_pointer<FUNCTION_TYPE >::type());
144
145 // throw on error
146 return ObjectTypeBuilderBase::advertiseMethod(name, function, threadingModel, id);
147 }
148
149 template <typename T>
150 AnyObject ObjectTypeBuilder<T>::object(T* ptr, boost::function<void (GenericObject*)> onDestroy)
151 {
152 return ObjectTypeBuilderBase::object(static_cast<void*>(ptr), onDestroy);
153 }
154
155
156 template<typename T>
157 void ObjectTypeBuilder<T>::registerType()
158 {
159 ::qi::registerType(qi::typeId<T>(), type());
160 }
161
162 template<typename A>
163 typename boost::enable_if<typename detail::Accessor<A>::is_accessor, SignalBase*>::type
164 signalAccess(A acc, void* instance)
165 {
166 using class_type = typename detail::Accessor<A>::class_type;
167 return &detail::Accessor<A>::access((class_type*)instance, acc);
168 }
169
170 template<typename A>
171 typename boost::enable_if<typename detail::Accessor<A>::is_accessor, PropertyBase*>::type
172 propertyAccess(A acc, void* instance)
173 {
174 using class_type = typename detail::Accessor<A>::class_type;
175 return &detail::Accessor<A>::access((class_type*)instance, acc);
176 }
177
178 template<typename A>
179 unsigned int
180 ObjectTypeBuilderBase::advertiseSignal(const std::string& eventName, A accessor, int id, bool isSignalProperty)
181 {
182 SignalMemberGetter fun = boost::bind(&signalAccess<A>, accessor, _1);
183 using FunctionType = typename detail::Accessor<A>::value_type::FunctionType;
184 return xAdvertiseSignal(eventName,
185 detail::FunctionSignature<FunctionType>::signature(), fun, id, isSignalProperty);
186 }
187
188 template <typename A>
189 unsigned int ObjectTypeBuilderBase::advertiseProperty(const std::string& name, A accessor)
190 {
191 unsigned int id = advertiseSignal(name, accessor, -1, true);
192 PropertyMemberGetter pg = boost::bind(&propertyAccess<A>, accessor, _1);
193 using PropertyType = typename detail::Accessor<A>::value_type::PropertyType;
194 return xAdvertiseProperty(name, typeOf<PropertyType>()->signature(), pg, id);
195 }
196
197 template <typename T> unsigned int ObjectTypeBuilderBase::advertiseSignal(const std::string& name, SignalMemberGetter getter, int id, bool isSignalProperty)
198 {
199 return xAdvertiseSignal(name, detail::FunctionSignature<T>::signature(), getter, id, isSignalProperty);
200 }
201
202 template<typename T>
203 inline unsigned int ObjectTypeBuilderBase::advertiseProperty(const std::string& eventName, PropertyMemberGetter getter)
204 {
205 return xAdvertiseProperty(eventName, typeOf<T>()->signature(), getter);
206 }
207
208
209 namespace detail
210 {
211 static const char* interfaceMarker = "_interface_";
212 static const auto interfaceMarkerLength = strlen(interfaceMarker);
213
214 // Trait that detect inheritance from PropertyBase SignalBase or none of the above.
215
216 template<typename T, bool b> struct SigPropInheritsSignal
217 {};
218 template<typename T, bool b> struct SigPropInheritsProperty
219 {};
220
221 template<typename T> struct SigProp : public
222 SigPropInheritsProperty<T, boost::is_base_of<PropertyBase, T>::value> {};
223
224 template<typename T> struct SigPropInheritsProperty<T, true>
225 {
226 static const unsigned value = 2;
227 };
228 template<typename T> struct SigPropInheritsProperty<T, false>
229 : public SigPropInheritsSignal<T, boost::is_base_of<SignalBase, T>::value> {};
230
231 template<typename T> struct SigPropInheritsSignal<T, true>
232 {
233 static const unsigned value = 1;
234 };
235 template<typename T> struct SigPropInheritsSignal<T, false>
236 {
237 static const unsigned value = 0;
238 };
239
240 template<unsigned> struct Dummy {};
241 template<typename A> unsigned int advertise(ObjectTypeBuilderBase* builder, const std::string& name, A accessor, Dummy<0>)
242 {
243 return builder->advertiseMethod(name, accessor);
244 }
245 template<typename A> unsigned int advertise(ObjectTypeBuilderBase* builder, const std::string& name, A accessor, Dummy<1>)
246 {
247 std::string n = name;
248 if (n.size() > interfaceMarkerLength && n.substr(0, interfaceMarkerLength) == interfaceMarker)
249 n = name.substr(interfaceMarkerLength);
250 return builder->advertiseSignal(n, accessor);
251 }
252 template<typename A> unsigned int advertise(ObjectTypeBuilderBase* builder, const std::string& name, A accessor, Dummy<2>)
253 {
254 std::string n = name;
255 if (n.size() > interfaceMarkerLength && n.substr(0, interfaceMarkerLength) == interfaceMarker)
256 n = name.substr(interfaceMarkerLength);
257 return builder->advertiseProperty(n, accessor);
258 }
259 template<typename A> unsigned int advertiseBounce(ObjectTypeBuilderBase* builder, const std::string& name, A accessor, boost::true_type)
260 {
261 return advertise(builder, name, accessor,
262 Dummy<detail::SigProp<typename detail::Accessor<A>::value_type>::value>());
263 }
264 template<typename A> unsigned int advertiseBounce(ObjectTypeBuilderBase* builder, const std::string& name, A accessor, boost::false_type)
265 {
266 return builder->advertiseMethod(name, accessor);
267 }
268 }
269 template<typename T>
270 unsigned int
271 ObjectTypeBuilderBase::advertiseId(const std::string& name, T element)
272 {
273 return detail::advertiseBounce(this, name, element, typename detail::Accessor<T>::is_accessor());
274 }
275 template<typename T>
276 ObjectTypeBuilderBase&
277 ObjectTypeBuilderBase::advertise(const std::string& name, T element)
278 {
279 detail::advertiseBounce(this, name, element, typename detail::Accessor<T>::is_accessor());
280 return *this;
281 }
282
283 }
284
285
286 #endif // _QITYPE_DETAIL_OBJECTTYPEBUILDER_HXX_
qi::ObjectTypeBuilderBase::xAdvertiseProperty
unsigned int xAdvertiseProperty(const std::string &name, const qi::Signature &signature, PropertyMemberGetter getter, int id=-1)
qi::detail::Dummy
Definition: objecttypebuilder.hxx:240
qi::ObjectTypeBuilderBase::buildFor
void buildFor(bool autoRegister=true)
Declare the class type for which this StaticBuilder is.
Definition: objecttypebuilder.hxx:40
objecttypebuilder.hpp
qi::MetaMethodBuilder
Definition: metamethod.hpp:69
qi::detail::callWithVoid
qi::Strand * callWithVoid(qi::Strand *(T::*member)() const, void *instance)
Definition: objecttypebuilder.hxx:20
qi::registerType
bool registerType(const TypeIndex &typeId, TypeInterface *type)
Runtime Type factory setter.
qiLogCategory
#define qiLogCategory(Cat)
Definition: log.hpp:53
qi::AnyFunction
Definition: anyfunction.hpp:149
qi::ObjectTypeBuilderBase::xBuildFor
void xBuildFor(TypeInterface *type, bool autoRegister, qi::AnyFunction strandAccessor)
qi::detail::SigPropInheritsProperty
Definition: objecttypebuilder.hxx:218
qiLogDebug
#define qiLogDebug(...)
Definition: log.hpp:76
qi::ObjectTypeBuilderBase::SignalMemberGetter
boost::function< SignalBase *(void *)> SignalMemberGetter
Definition: objecttypebuilder.hpp:42
qi::ObjectTypeBuilder::object
AnyObject object(T *ptr, boost::function< void(GenericObject *)> onDestroy=boost::function< void(GenericObject *)>())
Definition: objecttypebuilder.hxx:150
qi::ObjectTypeBuilderBase::advertiseMethod
unsigned int advertiseMethod(const std::string &name, FUNCTION_TYPE function, MetaCallType threadingModel=MetaCallType_Auto, int id=-1)
Definition: objecttypebuilder.hxx:57
qi::ObjectTypeBuilder::registerType
virtual void registerType()
Register type to typeOf<T>, to avoid both TypeImpl<T> and type() being present.
Definition: objecttypebuilder.hxx:157
qi::ObjectTypeBuilderBase::advertise
ObjectTypeBuilderBase & advertise(const std::string &name, T element)
Definition: objecttypebuilder.hxx:277
qi::ObjectTypeBuilderBase::advertiseId
unsigned int advertiseId(const std::string &name, T element)
Definition: objecttypebuilder.hxx:271
qi::ObjectThreadingModel_MultiThread
Object is thread safe, multiple calls can occur in different threads in parallel. ...
Definition: manageable.hpp:38
qi::MetaMethodBuilder::setName
void setName(const std::string &name)
qi::ObjectTypeBuilderBase::object
AnyObject object(void *ptr, boost::function< void(GenericObject *)> onDestroy=boost::function< void(GenericObject *)>())
qi::ObjectTypeBuilder::inherits
void inherits()
Definition: objecttypebuilder.hxx:93
qi::typeIdRuntime
TypeIndex typeIdRuntime(const T &val)
Definition: typeinterface.hpp:38
actor.hpp
qi::Strand
Definition: strand.hpp:125
qi::detail::checkRegisterParent
void checkRegisterParent(ObjectTypeBuilder< T > &, boost::false_type)
Definition: objecttypebuilder.hxx:107
qi::ObjectTypeBuilderBase::PropertyMemberGetter
boost::function< PropertyBase *(void *)> PropertyMemberGetter
Definition: objecttypebuilder.hpp:43
qi::GenericObject
Definition: genericobject.hpp:41
qi::ObjectTypeBuilderBase::inherits
void inherits(std::ptrdiff_t offset)
Definition: objecttypebuilder.hxx:85
qi::SignalBase
Definition: signal.hpp:42
qi::ObjectTypeBuilderBase::advertiseSignal
unsigned int advertiseSignal(const std::string &eventName, A accessor, int id=-1, bool isSignalProperty=false)
Definition: objecttypebuilder.hxx:180
qi::MetaCallType
MetaCallType
Definition: typeobject.hpp:24
qi::ObjectTypeBuilderBase::setThreadingModel
void setThreadingModel(ObjectThreadingModel model)
qi::ObjectTypeBuilderBase
Definition: objecttypebuilder.hpp:36
qi::ObjectTypeBuilder
Definition: objecttypebuilder.hpp:115
qi::Object< Empty >
qi::typeOf
TypeInterface * typeOf()
Definition: type.hxx:94
qi::signalAccess
boost::enable_if< typename detail::Accessor< A >::is_accessor, SignalBase * >::type signalAccess(A acc, void *instance)
Definition: objecttypebuilder.hxx:164
qi::ObjectTypeBuilderBase::xAdvertiseSignal
unsigned int xAdvertiseSignal(const std::string &name, const qi::Signature &signature, SignalMemberGetter getter, int id=-1, bool isSignalProperty=false)
qi::log::env::QI_DEFAULT_LOGHANDLER::name
char const *const name
metamethod.hpp
qi::AnyFunction::from
static AnyFunction from(F &&func)
qi::ObjectThreadingModel_SingleThread
Object is not thread safe, all method calls must occur in the same thread.
Definition: manageable.hpp:36
qi::ObjectTypeBuilder::advertiseMethod
unsigned int advertiseMethod(const std::string &name, FUNCTION_TYPE function, MetaCallType threadingModel=MetaCallType_Auto, int id=-1)
Definition: objecttypebuilder.hxx:121
qi::ObjectTypeBuilderBase::advertiseProperty
unsigned int advertiseProperty(const std::string &propertyName, A accessor)
Definition: objecttypebuilder.hxx:189
qi::detail::advertiseBounce
unsigned int advertiseBounce(ObjectTypeBuilderBase *builder, const std::string &name, A accessor, boost::true_type)
Definition: objecttypebuilder.hxx:259
qi::detail::FunctionSignature
Definition: functionsignature.hxx:103
qi::detail::SigProp
Definition: objecttypebuilder.hxx:221
qi::detail::advertise
unsigned int advertise(ObjectTypeBuilderBase *builder, const std::string &name, A accessor, Dummy< 0 >)
Definition: objecttypebuilder.hxx:241
qi::detail::getStrandAccessor
boost::enable_if< boost::is_base_of< Actor, T >, AnyFunction >::type getStrandAccessor()
Definition: objecttypebuilder.hxx:27
qi::MetaMethodBuilder::setSignature
void setSignature(const AnyFunction &f)
qi::propertyAccess
boost::enable_if< typename detail::Accessor< A >::is_accessor, PropertyBase * >::type propertyAccess(A acc, void *instance)
Definition: objecttypebuilder.hxx:172
qi::detail::SigPropInheritsSignal
Definition: objecttypebuilder.hxx:216
qi::DefaultTypeImpl< T >
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::ObjectTypeBuilderBase::xAdvertiseMethod
unsigned int xAdvertiseMethod(MetaMethodBuilder &builder, AnyFunction func, MetaCallType threadingModel=MetaCallType_Auto, int id=-1)