libqi-api  2.8.7.4
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
object.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 _QI_TYPE_DETAIL_OBJECT_HXX_
8 #define _QI_TYPE_DETAIL_OBJECT_HXX_
9 
10 #include <functional>
11 #include <boost/mpl/if.hpp>
12 
13 #include <qi/future.hpp>
15 #include <qi/type/typeobject.hpp>
18 #include <qi/type/metasignal.hpp>
19 #include <qi/type/metamethod.hpp>
20 #include <qi/type/metaobject.hpp>
21 #include <qi/objectuid.hpp>
22 
23 // Visual defines interface...
24 #ifdef interface
25 #undef interface
26 #endif
27 
28 #include <type_traits>
29 
30 namespace qi {
31 
32 // This id is used to identify a null Object. It is useful for example in Objects serialization.
33 static const unsigned int nullObjectId = 0;
34 
35 class Empty {};
36 
37 namespace detail {
38  using ProxyGeneratorMap = std::map<TypeInfo, boost::function<AnyReference(AnyObject)>>;
40 
41  /* On ubuntu (and maybe other platforms), the linking is done by default with
42  * --as-needed.
43  * Proxy libraries constist only of static initialization functions which add
44  * the proxy factories to the global maps, thus there is no direct dependency
45  * between the program and the library (no function call whatsoever) and the
46  * dependency gets dropped by the linker.
47  * This class is specialized when including interfaces which have proxies
48  * and the function is defined in the .so to force a dependency.
49  */
50  template <typename T>
52  {
53  bool dummyCall() { return true; }
54  };
55 
56  // bounce to a genericobject obtained by (O*)this->asAnyObject()
57  /* Everything need to be const:
58  * anyobj.call bounces to anyobj.asObject().call, and the
59  * second would work on const object
60  */
61  template<typename O> class GenericObjectBounce
62  {
63  public:
64  const MetaObject &metaObject() const { return go()->metaObject(); }
65  inline qi::Future<AnyReference> metaCall(unsigned int method, const GenericFunctionParameters& params, MetaCallType callType = MetaCallType_Auto, Signature returnSignature=Signature()) const
66  {
67  return go()->metaCall(method, params, callType, returnSignature);
68  }
69  inline int findMethod(const std::string& name, const GenericFunctionParameters& parameters) const
70  {
71  return go()->findMethod(name, parameters);
72  }
73  inline qi::Future<AnyReference> metaCall(const std::string &nameWithOptionalSignature, const GenericFunctionParameters& params, MetaCallType callType = MetaCallType_Auto, Signature returnSignature=Signature()) const
74  {
75  return go()->metaCall(nameWithOptionalSignature, params, callType, returnSignature);
76  }
77  inline void metaPost(unsigned int event, const GenericFunctionParameters& params) const
78  {
79  return go()->metaPost(event, params);
80  }
81  inline void metaPost(const std::string &nameWithOptionalSignature, const GenericFunctionParameters &in) const
82  {
83  return go()->metaPost(nameWithOptionalSignature, in);
84  }
85  template <typename... Args>
86  inline void post(const std::string& eventName, Args&&... args) const
87  {
88  return go()->post(eventName, std::forward<Args>(args)...);
89  }
90  template <typename FUNCTOR_TYPE>
91  inline qi::FutureSync<SignalLink> connect(const std::string& eventName, FUNCTOR_TYPE callback,
92  MetaCallType threadingModel = MetaCallType_Auto) const
93  {
94  return go()->connect(eventName, callback, threadingModel);
95  }
96  inline qi::FutureSync<SignalLink> connect(const std::string &name, const SignalSubscriber& functor) const
97  {
98  return go()->connect(name, functor);
99  }
100  inline qi::FutureSync<SignalLink> connect(unsigned int signal, const SignalSubscriber& subscriber) const
101  {
102  return go()->connect(signal, subscriber);
103  }
104  // Cannot inline here, AnyObject not fully declared
105  qi::FutureSync<SignalLink> connect(unsigned int signal, AnyObject target, unsigned int slot) const;
107  {
108  return go()->disconnect(linkId);
109  }
110  template<typename T>
111  inline qi::FutureSync<T> property(const std::string& name) const
112  {
113  return go()->template property<T>(name);
114  }
115  template<typename T>
116  inline qi::FutureSync<void> setProperty(const std::string& name, const T& val) const
117  {
118  return go()->setProperty(name, val);
119  }
120  inline qi::FutureSync<AnyValue> property(unsigned int id) const
121  {
122  return go()->property(id);
123  }
124  inline qi::FutureSync<void> setProperty(unsigned int id, const AnyValue &val) const
125  {
126  return go()->setProperty(id, val);
127  }
129  {
130  return go()->executionContext().get();
131  }
132  inline bool isStatsEnabled() const
133  {
134  return go()->isStatsEnabled();
135  }
136  inline void enableStats(bool enable) const
137  {
138  return go()->enableStats(enable);
139  }
140  inline ObjectStatistics stats() const
141  {
142  return go()->stats();
143  }
144  inline void clearStats() const
145  {
146  return go()->clearStats();
147  }
148  inline bool isTraceEnabled() const
149  {
150  return go()->isTraceEnabled();
151  }
152  inline void enableTrace(bool enable)
153  {
154  return go()->enableTrace(enable);
155  }
156  inline void forceExecutionContext(boost::shared_ptr<qi::ExecutionContext> ec)
157  {
158  return go()->forceExecutionContext(ec);
159  }
160  template <typename R, typename... Args>
161  qi::Future<R> async(const std::string& methodName, Args&&... args) const
162  {
163  return go()->template async<R>(methodName, std::forward<Args>(args)...);
164  }
165  template <typename R, typename... Args>
166  R call(const std::string& methodName, Args&&... args) const
167  {
168  return go()->template call<R>(methodName, std::forward<Args>(args)...);
169  }
170 
171  private:
172  inline GenericObject* go() const
173  {
174  GenericObject* g = static_cast<const O*>(this)->asGenericObject();
175  if (!g)
176  throw std::runtime_error("This object is null");
177  return g;
178  }
179  };
180 
181  template <typename T>
183  {
184  using Defined = std::false_type;
185  };
186 }
187 
188 // these methods are used by advertiseFactory and arguments are specified explicitely, we can't used forwarding here
189 template <typename T, typename... Args>
190 typename boost::enable_if<typename detail::InterfaceImplTraits<T>::Defined, qi::Object<T> >::type constructObject(
191  Args... args)
192 {
193  return boost::make_shared<typename detail::InterfaceImplTraits<T>::ImplType>(std::forward<Args>(args)...);
194 }
195 template <typename T, typename... Args>
196 typename boost::disable_if<typename detail::InterfaceImplTraits<T>::Defined, qi::Object<T> >::type constructObject(
197  Args&&... args)
198 {
199  return Object<T>(new T(std::forward<Args>(args)...));
200 }
201 
202 // QI_REGISTER_IMPLEMENTATION_H associates an interface type to an
203 // implementation type that might be unrelated (no inheritance or conversion).
204 // However, not like QI_REGISTER_IMPLEMENTATION(note the absence of `_H`),
205 // QI_REGISTER_IMPLEMENTATION_H also generates special proxy types wrapping
206 // the real implementation object.
207 // These wrappers are then used as implementation details by libqi
208 // when an object of the implementation type is stored in a qi::Object.
209 // The wrappers handle the thread-safety and the different kinds of API
210 // (returning or not futures, for example) while not modifying the original type.
211 #define QI_REGISTER_IMPLEMENTATION_H(interface, impl)\
212 namespace qi\
213 {\
214  namespace detail\
215  {\
216  template <>\
217  struct InterfaceImplTraits<interface>\
218  {\
219  using Defined = std::true_type;\
220  using InterfaceType = interface;\
221  using ImplType = impl;\
222  using AsyncType = interface##LocalAsync<boost::shared_ptr<ImplType>>;\
223  using SyncType = interface##LocalSync<boost::shared_ptr<ImplType>>;\
224  };\
225 \
226  template<>\
227  struct InterfaceImplTraits<impl>:\
228  public InterfaceImplTraits<interface>\
229  {};\
230  }\
231 }
232 
243 template<typename T> class Object :
244  public detail::GenericObjectBounce<Object<T>>
245 {
246  // see qi::Future constructors below
247  struct None {
249  };
250 public:
251  Object();
252 
253  template<typename U> Object(const Object<U>& o);
254  template<typename U> Object<T>& operator=(const Object<U>& o);
255  // Templates above do not replace default ctor or copy operator
256  Object(const Object& o);
257  Object<T>& operator=(const Object& o);
258  // Disable the ctor taking future if T is Empty, as it would conflict with
259  // We use None to disable it. The method must be instantiable because when we
260  // export the class under windows, all functions are instanciated
261  // Future cast operator
262  using MaybeAnyObject = typename boost::mpl::if_<typename boost::is_same<T, Empty>::type, None, Object<Empty>>::type;
263  Object(const qi::Future<MaybeAnyObject>& fobj);
265 
267 
273  Object(GenericObject* go);
274  Object(T* ptr);
275  Object(GenericObject* go, boost::function<void(GenericObject*)> deleter);
276  Object(T* ptr, boost::function<void(T*)> deleter);
278 
280  template<typename U> Object(GenericObject* go, boost::shared_ptr<U> other);
281  template<typename U> Object(boost::shared_ptr<U> other);
282  bool isValid() const;
283  explicit operator bool() const;
284  operator Object<Empty>() const;
285 
286  // Generates `>`, `<=`, `>=` in terms of `<`.
288  friend KA_GENERATE_REGULAR_OP_LESS_OR_EQUAL(Object)
289  friend KA_GENERATE_REGULAR_OP_GREATER_OR_EQUAL(Object)
290 
293  ObjectUid uid() const;
294 
295  QI_API_DEPRECATED_MSG("Use qi::Object::uid() instead.")
296  PtrUid ptrUid() const { return uid(); }
297 
298  boost::shared_ptr<T> asSharedPtr();
299 
300  T& asT() const;
301  T* operator->() const;
302  T& operator *() const;
303  bool unique() const;
305  void reset();
306  unsigned use_count() const { return _obj.use_count();}
307 
308  static ObjectTypeInterface* interface();
309  // Check or obtain T interface, or throw
310  void checkT();
311  // no-op deletor callback
313  static void noDeleteT(T*) {qiLogDebug("qi.object") << "AnyObject noop T deleter";}
314  static void noDelete(GenericObject*) {qiLogDebug("qi.object") << "AnyObject noop deleter";}
315  // deletor callback that deletes only the GenericObject and not the content
316  static void deleteGenericObjectOnly(GenericObject* obj) { qiLogDebug("qi.object") << "AnyObject GO deleter"; delete obj;}
317 
318  static void deleteCustomDeleter(GenericObject* obj, boost::function<void(T*)> deleter)
319  {
320  qiLogDebug("qi.object") << "custom deleter";
321  deleter((T*)obj->value);
322  delete obj;
323  }
325 private:
326  friend class GenericObject;
327 
328  template <typename> friend class Object;
329  template <typename> friend class WeakObject;
330 
332  {
333  init(obj);
334  }
335 
336  void init(detail::ManagedObjectPtr obj);
337 
338  static void deleteObject(GenericObject* obj)
339  {
340  qiLogDebug("qi.object") << "deleteObject " << obj << " "
341  << obj->value << " " << obj->type->infoString();
342  obj->type->destroy(obj->value);
343  delete obj;
344  }
345 
346  /* Do not change this, Object<T> must be binary-equivalent to
347  * ManagedObjectPtr.
348  */
350 };
351 
352 template<typename T> class WeakObject
353 {
354 public:
356  template<typename U> WeakObject(const Object<U>& o)
357  : _ptr(o._obj) {}
358  Object<T> lock() { return Object<T>(_ptr.lock());}
359  boost::weak_ptr<GenericObject> _ptr;
360 };
362 
363 template<typename T> inline ObjectTypeInterface* Object<T>::interface()
364 {
365  TypeInterface* type = typeOf<T>();
366  if (type->kind() != TypeKind_Object)
367  {
368  std::stringstream err;
369  err << "Object<T> can only be used on registered object types. ("
370  << type->infoString() << ")(" << type->kind() << ')';
371  throw std::runtime_error(err.str());
372  }
373  ObjectTypeInterface* otype = static_cast<ObjectTypeInterface*>(type);
374  return otype;
375 }
376 
377 template<typename T> inline Object<T>::Object() {}
378 
379 template<typename T>
380 template<typename U>
381 inline Object<T>::Object(const Object<U>& o)
382 {
383  static bool unused = qi::detail::ForceProxyInclusion<T>().dummyCall();
384  (void)unused;
385 
386  /* An Object<T> created by convert may be in fact an object that does
387  * not implement the T interface.
388  * Checking and converting on first access to T& is not enough:
389  * Object<Iface> o = obj.call("fetchOne"); // this one might be incorrect
390  * someVector.push_back(o); // pushes the incorrect one
391  * o->someIfaceOperation(); // will upgrade o, but not the one in someVector
392  *
393  * So we check as early as we can, in all copy pathes, and back-propagate
394  * the upgrade to the source of the copy
395  */
396  const_cast<Object<U>&>(o).checkT();
397  init(o._obj);
398 }
399 template<typename T>
400 template<typename U>
402 {
403  static bool unused = qi::detail::ForceProxyInclusion<T>().dummyCall();
404  (void)unused;
405 
406  const_cast<Object<U>&>(o).checkT();
407  init(o._obj);
408 
409  return *this;
410 }
411 template<typename T> inline Object<T>::Object(const Object<T>& o)
412 {
413  const_cast<Object<T>&>(o).checkT();
414  init(o._obj);
415 }
416 template<typename T> inline Object<T>& Object<T>::operator=(const Object<T>& o)
417 {
418  if (this == &o)
419  return *this;
420 
421  const_cast<Object<T>&>(o).checkT();
422  init(o._obj);
423 
424  return *this;
425 }
426 template<typename T> inline Object<T>::Object(GenericObject* go)
427 {
428  init(detail::ManagedObjectPtr(go, &deleteObject));
429 }
430 template<typename T> inline Object<T>::Object(GenericObject* go, boost::function<void(GenericObject*)> deleter)
431 {
432  init(detail::ManagedObjectPtr(go, deleter));
433 }
434 template<typename T> template<typename U> Object<T>::Object(GenericObject* go, boost::shared_ptr<U> other)
435 {
436  init(detail::ManagedObjectPtr(other, go));
437  // Notify the shared_from_this of GenericObject
438  _obj->_internal_accept_owner(&other, go);
439 }
440 namespace detail
441 {
442  // Low-level constructor from type, for factorization purpose only
443  template<typename T>
445  ObjectTypeInterface* oit,
446  boost::shared_ptr<T> other,
447  const boost::optional<ObjectUid>& maybeUid = boost::none)
448  {
449  return ManagedObjectPtr(
450  new GenericObject(oit, other.get(), maybeUid),
451  [other](GenericObject* object) mutable {
452  other.reset();
453  delete object;
454  });
455  }
456 
457  // Constructing an AnyObject from a registered implementation.
458  template<typename From>
460  Object<Empty>&,
461  boost::shared_ptr<From>& other,
462  std::true_type)
463  { // Bounce on a specialized object constructor
465  }
466 
467  // Constructing an AnyObject from an arbitrary type
468  template<typename From>
470  Object<Empty>&,
471  boost::shared_ptr<From>& other,
472  std::false_type)
473  { // Bounce on a specialized object constructor
474  return qi::Object<From>(other).managedObjectPtr();
475  }
476 
477  // Directly constructing object of the same type
478  template<typename ToSameAsFrom>
481  boost::shared_ptr<ToSameAsFrom>& other,
482  std::false_type)
483  { // It may throw if type is not registered
484  return managedObjectFromSharedPtr(dst.interface(), other);
485  }
486 
487  // Original pointer is not recognized as an implementation to construct a specialized object
488  template<typename To, typename From>
490  Object<To>& dst,
491  boost::shared_ptr<From>& other,
492  std::false_type)
493  {
494  static_assert(
495  std::is_base_of<typename std::decay<To>::type, typename std::decay<From>::type>::value,
496  "Cannot construct object from instance, because it is not a direct base or an associated implementation");
497  auto asDestinationType = boost::static_pointer_cast<To>(other);
498  return managedObjectFromSharedPtr(dst.interface(), asDestinationType);
499  }
500 
501  // Original pointer is recognized as an implementation to construct a specialized object
502  template<typename To, typename From>
504  Object<To>&,
505  boost::shared_ptr<From>& other,
506  std::true_type)
507  {
508  using SyncProxyType = typename InterfaceImplTraits<From>::SyncType;
509  // We want the uid value to match the real impl object, not the proxy object we are using here.
510  const auto realImplUid = os::ptrUid(other.get());
511  auto localProxy = boost::make_shared<SyncProxyType>(other);
512  return managedObjectFromSharedPtr(qi::Object<To>::interface(), std::move(localProxy), realImplUid);
513  }
514 }
515 
516 template<typename T> template<typename U> Object<T>::Object(boost::shared_ptr<U> other)
517 {
519  *this, other, typename qi::detail::InterfaceImplTraits<U>::Defined{});
520 }
521 
522 template<typename T> inline Object<T>::Object(T* ptr)
523 {
524  ObjectTypeInterface* otype = interface();
525  _obj = detail::ManagedObjectPtr(new GenericObject(otype, ptr), &deleteObject);
526 }
527 template<typename T> inline Object<T>::Object(T* ptr, boost::function<void(T*)> deleter)
528 {
529  ObjectTypeInterface* otype = interface();
530  if (deleter)
531  _obj = detail::ManagedObjectPtr(new GenericObject(otype, ptr),
533  else
534  _obj = detail::ManagedObjectPtr(new GenericObject(otype, ptr), &deleteObject);
535 }
536 template<typename T> inline Object<T>::Object(const qi::Future<MaybeAnyObject>& fobj)
537 {
538  static bool unused = qi::detail::ForceProxyInclusion<T>().dummyCall();
539  (void)unused;
540 
541  init(fobj.value()._obj);
542 }
543 template<typename T> inline Object<T>::Object(const qi::FutureSync<MaybeAnyObject>& fobj)
544 {
545  static bool unused = qi::detail::ForceProxyInclusion<T>().dummyCall();
546  (void)unused;
547 
548  init(fobj.value()._obj);
549 }
550 
551 template<typename T> inline boost::shared_ptr<T> Object<T>::asSharedPtr()
552 {
553  checkT();
554  return boost::shared_ptr<T>(&asT(), boost::bind(&keepManagedObjectPtr, _obj));
555 }
556 
557 template<typename T> inline void Object<T>::init(detail::ManagedObjectPtr obj)
558 {
559  _obj = obj;
560  if (!boost::is_same<T, Empty>::value && obj)
561  checkT();
562  _obj = obj;
563 }
564 
570 template<typename T, typename U>
571 bool operator==(const Object<T>& a, const Object<U>& b)
572 {
574  return a.asGenericObject()->uid == b.asGenericObject()->uid;
575 }
576 
577 template<typename T, typename U>
578 bool operator!=(const Object<T>& a, const Object<U>& b)
579 {
580  return !(a == b);
581 }
582 
583 template<typename T>
584 bool operator<(const Object<T>& a, const Object<T>& b)
585 {
586  QI_ASSERT(a.asGenericObject() && b.asGenericObject());
587  return a.asGenericObject()->uid < b.asGenericObject()->uid;
588 }
589 
590 template<typename T>
591 bool Object<T>::isValid() const
592 {
593  return _obj && _obj->type;
594 }
595 
596 template<typename T>
598 {
599  return isValid();
600 }
601 
602 template<typename T> Object<T>::operator Object<Empty>() const { return Object<Empty>(_obj);}
604 template<typename T> void Object<T>::checkT()
605 {
606  if (boost::is_same<T, Empty>::value || !_obj)
607  return;
608 
609  const auto isMatchingType = [&] {
610  return _obj->type->info() == typeOf<T>()->info()
611  || _obj->type->inherits(typeOf<T>()) != ObjectTypeInterface::INHERITS_FAILED;
612  };
613 
614  if (!isMatchingType())
615  { // No T interface, try upgrading _obj
617  detail::ProxyGeneratorMap::iterator it = map.find(typeOf<T>()->info());
618  if (it != map.end())
619  {
620  qiLogDebug("qitype.anyobject") << "Upgrading Object to specialized proxy.";
621  AnyReference ref = it->second(AnyObject(_obj));
622  _obj = ref.to<detail::ManagedObjectPtr>();
623  ref.destroy();
624  QI_ASSERT(isMatchingType());
625  return;
626  }
627  throw std::runtime_error(std::string() + "Object does not have interface " + typeOf<T>()->infoString());
628  }
629 }
630 template<typename T> ObjectUid Object<T>::uid() const
631 {
632  QI_ASSERT(_obj);
633  return _obj->uid;
634 }
635 template<typename T> T& Object<T>::asT() const
636 {
637  const_cast<Object<T>* >(this)->checkT();
638  return *static_cast<T*>(_obj->value);
639 }
640 template<typename T> T* Object<T>::operator->() const
641 {
642  return &asT();
643 }
644 template<typename T> T& Object<T>::operator *() const
645 {
646  return asT();
647 }
648 template<typename T> bool Object<T>::unique() const
649 {
650  return _obj.unique();
651 }
652 template<typename T> GenericObject* Object<T>::asGenericObject() const
653 {
654  return _obj.get();
655 }
656 template<typename T> void Object<T>::reset()
657 {
658  _obj.reset();
659 }
660 
661 namespace detail
662 {
663  template<typename O>
664  inline qi::FutureSync<SignalLink> GenericObjectBounce<O>::connect(unsigned int signal, AnyObject target, unsigned int slot) const
665  {
666  return go()->connect(signal, target, slot);
667  }
668 }
669 
670 /* Pretend that Object<T> is exactly shared_ptr<GenericObject>
671  * Which it is in terms of memory layout.
672  * But as a consequence, convert will happily create Object<T> for any T
673  * without checking it.
674  * Object<T> is handling this through the checkT() method.
675  */
676 template<typename T>
677 class QI_API TypeImpl<Object<T>> :
678  public TypeImpl<boost::shared_ptr<GenericObject>>
679 {
680 };
681 
682 #ifdef _MSC_VER
683 /* Because we use types marked with QI_API and inheriting from Object<Empty>
684  * (through AnyObject), then Object<Empty> functions must be explicitly
685  * exported/imported to avoid link issues with MSVC.
686  */
687 template class QI_API Object<Empty>;
688 #endif
689 
690 }
691 
692 namespace std
693 {
695  template<typename T>
696  struct hash<qi::Object<T>>
697  {
698  std::size_t operator()(const qi::Object<T>& o) const
699  {
701  return hash<qi::ObjectUid>{}(o.asGenericObject()->uid);
702  }
703  };
704 } // namespace std
705 
706 #endif // _QITYPE_DETAIL_OBJECT_HXX_
boost::shared_ptr< GenericObject > ManagedObjectPtr
boost::shared_ptr< T > asSharedPtr()
Definition: object.hxx:551
GenericObject * asGenericObject() const
Definition: object.hxx:652
PtrUid ptrUid() const
Definition: object.hxx:296
static void noDeleteT(T *)
Definition: object.hxx:313
ObjectUid uid
Uid of "value".
boost::enable_if< typename detail::InterfaceImplTraits< T >::Defined, qi::Object< T > >::type constructObject(Args...args)
Definition: object.hxx:190
boost::weak_ptr< GenericObject > _ptr
Definition: object.hxx:359
#define QI_API
Definition: api.hpp:33
qi::Future< AnyReference > metaCall(const std::string &nameWithOptionalSignature, const GenericFunctionParameters &params, MetaCallType callType=MetaCallType_Auto, Signature returnSignature=Signature()) const
Definition: object.hxx:73
qi::FutureSync< void > setProperty(const std::string &name, const T &val) const
Definition: object.hxx:116
qi::FutureSync< void > disconnect(SignalLink linkId) const
Definition: object.hxx:106
qi::FutureSync< SignalLink > connect(const std::string &eventName, FUNCTOR_TYPE callback, MetaCallType threadingModel=MetaCallType_Direct)
qi::FutureSync< AnyValue > property(unsigned int id) const
Definition: object.hxx:120
void enableStats(bool enable)
Set statistics gathering status.
int findMethod(const std::string &name, const GenericFunctionParameters &parameters) const
Definition: object.hxx:69
std::size_t operator()(const qi::Object< T > &o) const
Definition: object.hxx:698
void enableStats(bool enable) const
Definition: object.hxx:136
#define qiLogDebug(...)
Definition: log.hpp:76
bool unique() const
Definition: object.hxx:648
std::map< unsigned int, MethodStatistics > ObjectStatistics
Definition: manageable.hpp:120
virtual TypeKind kind()
Definition: type.hxx:99
void checkT()
Check tha value actually has the T interface.
Definition: object.hxx:604
qi::FutureSync< SignalLink > connect(unsigned int signal, const SignalSubscriber &subscriber) const
Definition: object.hxx:100
Honor the default behavior.
Definition: typeobject.hpp:26
qi::FutureSync< T > property(const std::string &name) const
Definition: object.hxx:111
#define QI_ASSERT(expr__)
Definition: assert.hpp:27
const ValueType & value(int msecs=FutureTimeout_Infinite) const
Definition: future_fwd.hpp:742
qi::FutureSync< SignalLink > connect(const std::string &eventName, FUNCTOR_TYPE callback, MetaCallType threadingModel=MetaCallType_Auto) const
Definition: object.hxx:91
void enableTrace(bool enable)
Definition: object.hxx:152
bool isStatsEnabled() const
int findMethod(const std::string &name, const GenericFunctionParameters &parameters)
Find method named name callable with arguments parameters.
T & asT() const
Definition: object.hxx:635
void post(const std::string &eventName, Args &&...args) const
Definition: object.hxx:86
friend KA_GENERATE_REGULAR_OP_GREATER(Object) friend KA_GENERATE_REGULAR_OP_LESS_OR_EQUAL(Object) friend KA_GENERATE_REGULAR_OP_GREATER_OR_EQUAL(Object) ObjectUid uid() const
static void deleteGenericObjectOnly(GenericObject *obj)
Definition: object.hxx:316
R call(const std::string &methodName, Args &&...args) const
Definition: object.hxx:166
Object< T > lock()
Definition: object.hxx:358
unsigned use_count() const
Definition: object.hxx:306
void destroy()
Deletes storage.
static const auto INHERITS_FAILED
Definition: typeobject.hpp:63
WeakObject(const Object< U > &o)
Definition: object.hxx:356
ProxyGeneratorMap & proxyGeneratorMap()
void forceExecutionContext(boost::shared_ptr< qi::ExecutionContext > ec)
Definition: object.hxx:156
T to() const
Convert to anything or throw trying.
T * operator->() const
Definition: object.hxx:640
qi::FutureSync< void > disconnect(SignalLink linkId)
Disconnect an event link. Returns if disconnection was successful.
Object< T > & operator=(const Object< U > &o)
Definition: object.hxx:401
detail::ManagedObjectPtr managedObjectPtr()
Definition: object.hxx:324
bool operator==(const Signature &lhs, const Signature &rhs)
#define QI_API_DEPRECATED_MSG(msg__)
Compiler flags to mark a function as deprecated. It will generate a compiler warning.
Definition: macro.hpp:55
std::map< TypeInfo, boost::function< AnyReference(AnyObject)>> ProxyGeneratorMap
Definition: object.hxx:38
const MetaObject & metaObject() const
Definition: object.hxx:64
qi::FutureSync< void > setProperty(const std::string &name, const T &val)
void metaPost(unsigned int event, const GenericFunctionParameters &params) const
Definition: object.hxx:77
ObjectTypeInterface * type
void post(const std::string &eventName, qi::AutoAnyReference p1=qi::AutoAnyReference(), qi::AutoAnyReference p2=qi::AutoAnyReference(), qi::AutoAnyReference p3=qi::AutoAnyReference(), qi::AutoAnyReference p4=qi::AutoAnyReference(), qi::AutoAnyReference p5=qi::AutoAnyReference(), qi::AutoAnyReference p6=qi::AutoAnyReference(), qi::AutoAnyReference p7=qi::AutoAnyReference(), qi::AutoAnyReference p8=qi::AutoAnyReference())
void metaPost(unsigned int event, const GenericFunctionParameters &params)
virtual void destroy(void *)=0
Free all resources of a storage.
void enableTrace(bool enable)
qi::FutureSync< void > setProperty(unsigned int id, const AnyValue &val) const
Definition: object.hxx:124
qi::FutureSync< T > property(const std::string &name)
MetaCallType
Definition: typeobject.hpp:24
const char * infoString()
static ObjectTypeInterface * interface()
Definition: object.hxx:363
typename boost::mpl::if_< typename boost::is_same< Empty, Empty >::type, None, Object< Empty >>::type MaybeAnyObject
Definition: object.hxx:262
ManagedObjectPtr managedObjectFromSharedPtr(ObjectTypeInterface *oit, boost::shared_ptr< T > other, const boost::optional< ObjectUid > &maybeUid=boost::none)
Definition: object.hxx:444
qi::FutureSync< SignalLink > connect(const std::string &name, const SignalSubscriber &functor) const
Definition: object.hxx:96
qi::Future< R > async(const std::string &methodName, Args &&...args) const
Definition: object.hxx:161
boost::shared_ptr< ExecutionContext > executionContext() const
const MetaObject & metaObject()
Object< Empty > AnyObject
Definition: anyobject.hpp:21
T & operator*() const
Definition: object.hxx:644
bool isTraceEnabled() const
static void noDelete(GenericObject *)
Definition: object.hxx:314
ObjectStatistics stats() const
Definition: object.hxx:140
PtrUid ptrUid(void *address)
const ValueType & value(int msecs=FutureTimeout_Infinite) const
Return the value associated to a Future.
Definition: future_fwd.hpp:249
void reset()
Definition: object.hxx:656
qi::Future< AnyReference > metaCall(unsigned int method, const GenericFunctionParameters &params, MetaCallType callType=MetaCallType_Auto, Signature returnSignature=Signature()) const
Definition: object.hxx:65
void forceExecutionContext(boost::shared_ptr< ExecutionContext > eventLoop)
Override all ThreadingModel and force dispatch to given event loop.
qi::uint64_t SignalLink
Definition: signal.hpp:36
void clearStats()
Reset all statistical data.
static void keepManagedObjectPtr(detail::ManagedObjectPtr)
Definition: object.hxx:312
qi::Future< AnyReference > metaCall(const std::string &nameWithOptionalSignature, const GenericFunctionParameters &params, MetaCallType callType=MetaCallType_Auto, Signature returnSignature=Signature())
bool isValid() const
Definition: object.hxx:591
bool operator!=(const Signature &lhs, const Signature &rhs)
Definition: signature.hpp:157
ObjectStatistics stats() const
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...
std::enable_if< std::is_function< RF >::value, boost::function< RF > >::type bind(AF &&fun, Arg0 &&arg0, Args &&...args)
Definition: trackable.hxx:308
void metaPost(const std::string &nameWithOptionalSignature, const GenericFunctionParameters &in) const
Definition: object.hxx:81
static void deleteCustomDeleter(GenericObject *obj, boost::function< void(T *)> deleter)
Definition: object.hxx:318
ExecutionContext * executionContext() const
Definition: object.hxx:128
Description of the signals and methods accessible on an ObjectTypeInterface.
Definition: metaobject.hpp:25