- 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.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_OBJECTTYPEBUILDER_HPP_
8 #define _QI_TYPE_OBJECTTYPEBUILDER_HPP_
9
10 #include <qi/api.hpp>
11 #include <string>
12
13 #include <boost/function.hpp>
14 #include <qi/signature.hpp>
15 #include <sstream>
16 #include <qi/type/typeinterface.hpp>
17 #include <qi/type/detail/staticobjecttype.hpp>
18 #include <qi/type/detail/accessor.hxx>
19 #include <qi/type/detail/object.hxx>
20 #include <qi/property.hpp>
21
22 namespace qi {
23
24 namespace detail {
25 struct ObjectTypeData;
26 }
27
28 class MetaObject;
29
30 class SignalBase;
31 class ObjectTypeInterface;
32 class TypeInterface;
33 template<typename T> class SignalF;
34 class ObjectTypeBuilderPrivate;
35
36 class QI_API ObjectTypeBuilderBase
37 {
38 public:
39 ObjectTypeBuilderBase();
40 ~ObjectTypeBuilderBase();
41
42 using SignalMemberGetter = boost::function<SignalBase* (void*)>;
43 using PropertyMemberGetter = boost::function<PropertyBase* (void*)>;
44
46 void setDescription(const std::string& description);
47
48 // input: template-based
49
51 template<typename T> void buildFor(bool autoRegister = true);
52
53 template <typename FUNCTION_TYPE>
54 inline unsigned int advertiseMethod(const std::string& name, FUNCTION_TYPE function, MetaCallType threadingModel = MetaCallType_Auto, int id = -1);
55
56 template <typename FUNCTION_TYPE>
57 inline unsigned int advertiseMethod(MetaMethodBuilder& name, FUNCTION_TYPE function, MetaCallType threadingModel = MetaCallType_Auto, int id = -1);
58
59 template<typename A>
60 unsigned int advertiseSignal(const std::string& eventName, A accessor, int id = -1, bool isSignalProperty = false);
61
62 template <typename T>
63 inline unsigned int advertiseSignal(const std::string& name, SignalMemberGetter getter, int id = -1, bool isSignalProperty = false);
64
65 template <typename A>
66 inline unsigned int advertiseProperty(const std::string& propertyName, A accessor);
67
68 template<typename T>
69 inline unsigned int advertiseProperty(const std::string& eventName, PropertyMemberGetter getter);
70
74 template<typename T, typename... Args>
75 inline unsigned int advertiseFactory(const std::string& name)
76 {
77 return advertiseMethod(name, &constructObject<T, Args...>);
78 }
79
80 template<typename P>
81 void inherits(std::ptrdiff_t offset);
82
83 // Advertise anything, dispatch on {method, event, property} based on T.
84 template<typename T>
85 ObjectTypeBuilderBase& advertise(const std::string& name, T element);
86 // Like advertise, but return the id
87 template<typename T>
88 unsigned int advertiseId(const std::string& name, T element);
89 // input: type-erased
90
91 unsigned int xAdvertiseMethod(MetaMethodBuilder& builder, AnyFunction func, MetaCallType threadingModel = MetaCallType_Auto, int id = -1);
92 unsigned int xAdvertiseSignal(const std::string &name, const qi::Signature& signature, SignalMemberGetter getter, int id = -1, bool isSignalProperty = false);
93 unsigned int xAdvertiseProperty(const std::string& name, const qi::Signature& signature, PropertyMemberGetter getter, int id = -1);
94 void xBuildFor(TypeInterface* type, bool autoRegister, qi::AnyFunction strandAccessor);
95 void inherits(TypeInterface* parentType, std::ptrdiff_t offset);
96
97 // Configuration
98
99 void setThreadingModel(ObjectThreadingModel model);
100
101 // output
102 const MetaObject& metaObject();
103 AnyObject object(void* ptr, boost::function<void (GenericObject*)> onDestroy = boost::function<void (GenericObject*)>());
104 ObjectTypeInterface* type();
105
107 inline virtual void registerType() {};
108
109 const detail::ObjectTypeData& typeData();
110 private:
111 ObjectTypeBuilderPrivate* _p;
112 };
113
114 template<typename T>
115 class ObjectTypeBuilder : public ObjectTypeBuilderBase
116 {
117 public:
118 ObjectTypeBuilder(bool autoRegister=true)
119 {
120 buildFor<T>(autoRegister);
121 }
122
128 template<typename U> void inherits();
129
130 template <typename FUNCTION_TYPE>
131 inline unsigned int advertiseMethod(const std::string& name,
132 FUNCTION_TYPE function,
133 MetaCallType threadingModel = MetaCallType_Auto,
134 int id = -1);
135
136 template <typename FUNCTION_TYPE>
137 inline unsigned int advertiseMethod(MetaMethodBuilder& name,
138 FUNCTION_TYPE function,
139 MetaCallType threadingModel = MetaCallType_Auto,
140 int id = -1);
141
142
144 inline virtual void registerType();
145
146 inline AnyObject object(T* ptr, boost::function<void (GenericObject*)> onDestroy = boost::function<void (GenericObject*)>());
147 };
148 }
149
150 #include <qi/type/detail/objecttypebuilder.hxx>
151
158 #define QI_OBJECT_BUILDER_ADVERTISE(builder, cls, name) \
159 builder.advertise(BOOST_PP_STRINGIZE(name), &cls::name)
160
171 #define QI_OBJECT_BUILDER_ADVERTISE_OVERLOAD(builder, cls, name, ret, args) \
172 builder.advertiseMethod(BOOST_PP_STRINGIZE(name), static_cast<ret (cls::*)args>(&cls::name))
173
174 #define __QI_REGISTER_ELEMENT(_, name, field) \
175 b.advertise(BOOST_PP_STRINGIZE(field), & name::field); // do not remove the space
176
184 #define QI_REGISTER_OBJECT(name, ...) \
185 static bool BOOST_PP_CAT(__qi_registration, __LINE__) QI_ATTR_UNUSED = [] \
186 { \
187 ::qi::ObjectTypeBuilder<name> b; \
188 QI_VAARGS_APPLY(__QI_REGISTER_ELEMENT, name, __VA_ARGS__) \
189 b.registerType(); \
190 return true; \
191 }();
192
193 #define QI_REGISTER_MT_OBJECT(name, ...) \
194 static bool BOOST_PP_CAT(__qi_registration, __LINE__) QI_ATTR_UNUSED = [] \
195 { \
196 ::qi::ObjectTypeBuilder<name> b; \
197 b.setThreadingModel(qi::ObjectThreadingModel_MultiThread); \
198 QI_VAARGS_APPLY(__QI_REGISTER_ELEMENT, name, __VA_ARGS__) \
199 b.registerType(); \
200 return true; \
201 }();
202
209 #define QI_REGISTER_IMPLEMENTATION(parent, name) \
210 static bool BOOST_PP_CAT(__qi_registration_func, __LINE__)() \
211 { \
212 qi::detail::ForceProxyInclusion<parent>().dummyCall(); \
213 qi::registerType(qi::typeId<name>(), qi::typeOf<parent>()); \
214 name* ptr = static_cast<name*>(reinterpret_cast<void*>(0x10000)); \
215 parent* pptr = ptr; \
216 intptr_t offset = reinterpret_cast<intptr_t>(pptr) - reinterpret_cast<intptr_t>(ptr); \
217 if (offset) \
218 { \
219 qiLogError("qitype.register") << "non-zero offset for implementation " << #name << " of " << #parent \
220 << ", call will fail at runtime"; \
221 throw std::runtime_error("non-zero offset between implementation and interface"); \
222 } \
223 return true; \
224 } \
225 static bool BOOST_PP_CAT(__qi_registration, __LINE__) = BOOST_PP_CAT(__qi_registration_func, __LINE__)();
226
227 #define _QI_REGISTER_TEMPLATE_OBJECT(name, model, ...) \
228 namespace qi \
229 { \
230 template <> \
231 class QI_API TypeOfTemplate<name> : public detail::StaticObjectTypeBase \
232 { \
233 public: \
234 virtual TypeInterface* templateArgument() = 0; \
235 }; \
236 template <typename T> \
237 class TypeOfTemplateImpl<name, T> : public TypeOfTemplate<name> \
238 { \
239 public: \
240 TypeOfTemplateImpl() \
241 { \
242 /* early self registering to avoid recursive init */ \
243 ::qi::registerType(qi::typeId<name<T>>(), this); \
244 ObjectTypeBuilder<name<T> > b(false); \
245 b.setThreadingModel(model); \
246 QI_VAARGS_APPLY(__QI_REGISTER_ELEMENT, name<T>, __VA_ARGS__) \
247 this->initialize(b.metaObject(), b.typeData()); \
248 } \
249 TypeInterface* templateArgument() override { return typeOf<T>(); } \
250 using Methods = DefaultTypeImplMethods<name<T>>; \
251 _QI_BOUNCE_TYPE_METHODS(Methods); \
252 }; \
253 } \
254 QI_TEMPLATE_TYPE_DECLARE(name)
255
260 #define QI_TEMPLATE_OBJECT(name, ...) \
261 _QI_REGISTER_TEMPLATE_OBJECT(name, ObjectThreadingModel_SingleThread, \
262 __VA_ARGS__)
263
266 #define QI_REGISTER_TEMPLATE_OBJECT(name, ...) \
267 QI_TEMPLATE_OBJECT(name, __VA_ARGS__)
268
271 #define QI_MT_TEMPLATE_OBJECT(name, ...) \
272 _QI_REGISTER_TEMPLATE_OBJECT(name, ObjectThreadingModel_MultiThread, \
273 __VA_ARGS__)
274
275 // sometimes we need to use type-erased futures, but only those two methods are needed, so register our futures as
276 // normal objects with these methods
277 namespace qi
278 {
279 template <>
280 class QI_API TypeOfTemplate<qi::Future> : public detail::StaticObjectTypeBase
281 {
282 public:
283 virtual TypeInterface* templateArgument() = 0;
284 };
285 template <>
286 class QI_API TypeOfTemplate<qi::FutureSync> : public detail::StaticObjectTypeBase
287 {
288 public:
289 virtual TypeInterface* templateArgument() = 0;
290 };
291 template <template<typename> class FutT, typename T>
292 class TypeOfTemplateFutImpl : public TypeOfTemplate<FutT>
293 {
294 public:
295 TypeOfTemplateFutImpl()
296 {
297 /* early self registering to avoid recursive init */
298 ::qi::registerType(qi::typeId<FutT<T>>(), this);
299 ObjectTypeBuilder<FutT<T> > b(false);
300 b.setThreadingModel(qi::ObjectThreadingModel_MultiThread);
301 #define ADVERTISE(meth) \
302 b.advertiseMethod(#meth, &FutT<T>::meth)
303 ADVERTISE(_connect);
304 ADVERTISE(error);
305 ADVERTISE(hasError);
306 ADVERTISE(isCanceled);
307 ADVERTISE(cancel);
308 b.advertiseMethod("value",
309 (const typename FutT<T>::ValueType& (FutT<T>::*)(int) const) &FutT<T>::value);
310 ADVERTISE(waitUntil);
311 ADVERTISE(waitFor);
312 ADVERTISE(isRunning);
313 ADVERTISE(isFinished);
314 ADVERTISE(isValid);
315 #undef ADVERTISE
316 // this method is useful to get a future<anyvalue> through a simple async call
317 // it is used in libqi-python
318 b.advertiseMethod("_getSelf",
319 static_cast<qi::Future<T>(*)(FutT<T>*)>(
320 [](FutT<T>* fut) -> qi::Future<T> {
321 return *fut;
322 }));
323 this->initialize(b.metaObject(), b.typeData());
324 }
325 TypeInterface* templateArgument() override
326 {
327 return typeOf<T>();
328 }
329 using Methods = DefaultTypeImplMethods<FutT<T>>;
330 _QI_BOUNCE_TYPE_METHODS(Methods);
331 };
332 template <typename T>
333 class TypeOfTemplateImpl<qi::Future, T> : public TypeOfTemplateFutImpl<qi::Future, T> {};
334 template <typename T>
335 class TypeOfTemplateImpl<qi::FutureSync, T> : public TypeOfTemplateFutImpl<qi::FutureSync, T> {};
336 }
337 QI_TEMPLATE_TYPE_DECLARE(qi::Future)
338 QI_TEMPLATE_TYPE_DECLARE(qi::FutureSync)
339
340 QI_MT_TEMPLATE_OBJECT(qi::Promise, setValue, setError, setCanceled, future, value, trigger);
341
342 namespace qi { namespace detail {
343 template<typename T> struct TypeManager<Future<T> >: public TypeManagerDefaultStruct<Future<T> > {};
344 template<typename T> struct TypeManager<FutureSync<T> >: public TypeManagerDefaultStruct<FutureSync<T> > {};
345 template<typename T> struct TypeManager<Promise<T> >: public TypeManagerDefaultStruct<Promise<T> > {};
346 }}
347
348 #endif // _QITYPE_OBJECTTYPEBUILDER_HPP_
qi::detail::setValue
void setValue(qi::Promise< R > &p, const boost::function< R()> &f)
Definition: executioncontext.hpp:148
qi::typeId
TypeIndex typeId()
Definition: typeinterface.hpp:33
ADVERTISE
#define ADVERTISE(meth)
qi::detail::ObjectTypeData
Definition: staticobjecttype.hpp:24
QI_API
#define QI_API
Definition: api.hpp:33
qi::ObjectTypeBuilderBase::typeData
const detail::ObjectTypeData & typeData()
qi::detail::TypeManager
Definition: typeimpl.hxx:111
qi::MetaMethodBuilder
Definition: metamethod.hpp:69
qi::registerType
bool registerType(const TypeIndex &typeId, TypeInterface *type)
Runtime Type factory setter.
qi::Future
Definition: executioncontext.hpp:20
qi::AnyFunction
Definition: anyfunction.hpp:149
qi::ObjectTypeBuilderBase::SignalMemberGetter
boost::function< SignalBase *(void *)> SignalMemberGetter
Definition: objecttypebuilder.hpp:42
qi::Signature
Definition: signature.hpp:66
qi::ObjectTypeBuilder::object
AnyObject object(T *ptr, boost::function< void(GenericObject *)> onDestroy=boost::function< void(GenericObject *)>())
Definition: objecttypebuilder.hxx:150
qi::MetaCallType_Auto
Honor the default behavior.
Definition: typeobject.hpp:26
qi::ObjectTypeBuilderBase::registerType
virtual void registerType()
Register type to typeof. Called by type()
Definition: objecttypebuilder.hpp:107
qi::TypeOfTemplate
class QITYPE_TEMPLATE_API TypeOfTemplate
Definition: type.hxx:136
qi::TypeOfTemplateFutImpl::TypeOfTemplateFutImpl
TypeOfTemplateFutImpl()
Definition: objecttypebuilder.hpp:295
api.hpp
dll import/export and compiler message
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::ObjectThreadingModel_MultiThread
Object is thread safe, multiple calls can occur in different threads in parallel. ...
Definition: manageable.hpp:38
qi::detail::TypeManagerDefaultStruct
Definition: typeimpl.hxx:80
qi::ObjectTypeBuilder::inherits
void inherits()
Definition: objecttypebuilder.hxx:93
qi::TypeInterface
Definition: typeinterface.hpp:129
signature.hpp
objecttypebuilder.hxx
property.hpp
qi::ObjectTypeBuilderBase::PropertyMemberGetter
boost::function< PropertyBase *(void *)> PropertyMemberGetter
Definition: objecttypebuilder.hpp:43
qi::GenericObject
Definition: genericobject.hpp:41
qi::ObjectTypeBuilder::ObjectTypeBuilder
ObjectTypeBuilder(bool autoRegister=true)
Definition: objecttypebuilder.hpp:118
QI_MT_TEMPLATE_OBJECT
#define QI_MT_TEMPLATE_OBJECT(name,...)
Definition: objecttypebuilder.hpp:271
qi::TypeOfTemplateFutImpl::_QI_BOUNCE_TYPE_METHODS
_QI_BOUNCE_TYPE_METHODS(Methods)
qi::detail::StaticObjectTypeBase
Definition: staticobjecttype.hpp:61
object.hxx
qi::DefaultTypeImplMethods
Definition: typeimpl.hxx:228
qi::ObjectTypeInterface
Definition: typeobject.hpp:48
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
Definition: object.hxx:243
qi::TypeOfTemplateImpl
Definition: type.hxx:139
accessor.hxx
qi::log::env::QI_DEFAULT_LOGHANDLER::name
char const *const name
qi::FutureSync
Definition: future_fwd.hpp:70
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::TypeOfTemplateFutImpl::templateArgument
TypeInterface * templateArgument() override
Definition: objecttypebuilder.hpp:325
staticobjecttype.hpp
typeinterface.hpp
qi::ObjectTypeBuilderBase::metaObject
const MetaObject & metaObject()
qi::Promise
Definition: future_fwd.hpp:71
qi::ObjectTypeBuilderBase::advertiseFactory
unsigned int advertiseFactory(const std::string &name)
Definition: objecttypebuilder.hpp:75
qi::detail::advertise
unsigned int advertise(ObjectTypeBuilderBase *builder, const std::string &name, A accessor, Dummy< 0 >)
Definition: objecttypebuilder.hxx:241
qi::ObjectThreadingModel
ObjectThreadingModel
Possible thread models for an object.
Definition: manageable.hpp:33
qi::TypeOfTemplateFutImpl
Definition: objecttypebuilder.hpp:292
QI_TEMPLATE_TYPE_DECLARE
QI_TEMPLATE_TYPE_DECLARE(qi::Promise)
qi::MetaObject
Description of the signals and methods accessible on an ObjectTypeInterface.
Definition: metaobject.hpp:25