typeHandle.h 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. /**
  2. * PANDA 3D SOFTWARE
  3. * Copyright (c) Carnegie Mellon University. All rights reserved.
  4. *
  5. * All use of this software is subject to the terms of the revised BSD
  6. * license. You should have received a copy of this license along
  7. * with this source code in a file named "LICENSE."
  8. *
  9. * @file typeHandle.h
  10. * @author drose
  11. * @date 1998-10-23
  12. */
  13. #ifndef TYPEHANDLE_H
  14. #define TYPEHANDLE_H
  15. #include "dtoolbase.h"
  16. #include <set>
  17. /**
  18. * The following illustrates the convention for declaring a type that uses
  19. * TypeHandle. In this example, ThisThingie inherits from TypedObject, which
  20. * automatically supplies some type-differentiation functions at the cost of
  21. * one virtual function, get_type(); however, this inheritance is optional,
  22. * and may be omitted to avoid the virtual function pointer overhead. (If you
  23. * do use TypedObject, be sure to consider whether your destructor should also
  24. * be virtual.)
  25. *
  26. * @code
  27. * class ThatThingie : public SimpleTypedObject {
  28. * public:
  29. * static TypeHandle get_class_type() {
  30. * return _type_handle;
  31. * }
  32. * static void init_type() {
  33. * register_type(_type_handle, "ThatThingie");
  34. * }
  35. *
  36. * private:
  37. * static TypeHandle _type_handle;
  38. * };
  39. *
  40. * class ThisThingie : public ThatThingie, publid TypedObject {
  41. * public:
  42. * static TypeHandle get_class_type() {
  43. * return _type_handle;
  44. * }
  45. * static void init_type() {
  46. * ThatThingie::init_type();
  47. * TypedObject::init_type();
  48. * register_type(_type_handle, "ThisThingie",
  49. * ThatThingie::get_class_type(),
  50. * TypedObject::get_class_type());
  51. * }
  52. * virtual TypeHandle get_type() const {
  53. * return get_class_type();
  54. * }
  55. *
  56. * private:
  57. * static TypeHandle _type_handle;
  58. * };
  59. * @endcode
  60. */
  61. class TypedObject;
  62. /**
  63. * TypeHandle is the identifier used to differentiate C++ class types. Any
  64. * C++ classes that inherit from some base class, and must be differentiated
  65. * at run time, should store a static TypeHandle object that can be queried
  66. * through a static member function named get_class_type(). Most of the time,
  67. * it is also desirable to inherit from TypedObject, which provides some
  68. * virtual functions to return the TypeHandle for a particular instance.
  69. *
  70. * At its essence, a TypeHandle is simply a unique identifier that is assigned
  71. * by the TypeRegistry. The TypeRegistry stores a tree of TypeHandles, so
  72. * that ancestry of a particular type may be queried, and the type name may be
  73. * retrieved for run-time display.
  74. */
  75. class EXPCL_DTOOL_DTOOLBASE TypeHandle final {
  76. PUBLISHED:
  77. TypeHandle() noexcept = default;
  78. enum MemoryClass {
  79. MC_singleton,
  80. MC_array,
  81. MC_deleted_chain_active,
  82. MC_deleted_chain_inactive,
  83. MC_limit // Not a real value, just a placeholder for the maximum
  84. // enum value.
  85. };
  86. // The default constructor must do nothing, because we can't guarantee
  87. // ordering of static initializers. If the constructor tried to initialize
  88. // its value, it might happen after the value had already been set
  89. // previously by another static initializer!
  90. PY_EXTENSION(static TypeHandle make(PyTypeObject *classobj));
  91. INLINE bool operator == (const TypeHandle &other) const;
  92. INLINE bool operator != (const TypeHandle &other) const;
  93. INLINE bool operator < (const TypeHandle &other) const;
  94. INLINE bool operator <= (const TypeHandle &other) const;
  95. INLINE bool operator > (const TypeHandle &other) const;
  96. INLINE bool operator >= (const TypeHandle &other) const;
  97. INLINE int compare_to(const TypeHandle &other) const;
  98. INLINE size_t get_hash() const;
  99. INLINE std::string get_name(TypedObject *object = nullptr) const;
  100. INLINE bool is_derived_from(TypeHandle parent,
  101. TypedObject *object = nullptr) const;
  102. INLINE int get_num_parent_classes(TypedObject *object = nullptr) const;
  103. INLINE TypeHandle get_parent_class(int index) const;
  104. INLINE int get_num_child_classes(TypedObject *object = nullptr) const;
  105. INLINE TypeHandle get_child_class(int index) const;
  106. INLINE TypeHandle get_parent_towards(TypeHandle ancestor,
  107. TypedObject *object = nullptr) const;
  108. size_t get_memory_usage(MemoryClass memory_class) const;
  109. void inc_memory_usage(MemoryClass memory_class, size_t size);
  110. void dec_memory_usage(MemoryClass memory_class, size_t size);
  111. INLINE int get_index() const;
  112. INLINE void output(std::ostream &out) const;
  113. constexpr static TypeHandle none() { return TypeHandle(0); }
  114. INLINE operator bool () const;
  115. MAKE_PROPERTY(index, get_index);
  116. MAKE_PROPERTY(name, get_name);
  117. MAKE_SEQ_PROPERTY(parent_classes, get_num_parent_classes, get_parent_class);
  118. MAKE_SEQ_PROPERTY(child_classes, get_num_child_classes, get_child_class);
  119. PY_EXTENSION(PyObject *__reduce__() const);
  120. PY_EXTENSION(void __setstate__(PyObject *));
  121. public:
  122. #ifdef HAVE_PYTHON
  123. PyTypeObject *get_python_type() const;
  124. PyObject *wrap_python(void *ptr, PyTypeObject *cast_from = nullptr) const;
  125. #endif // HAVE_PYTHON
  126. void *allocate_array(size_t size) RETURNS_ALIGNED(MEMORY_HOOK_ALIGNMENT);
  127. void *reallocate_array(void *ptr, size_t size) RETURNS_ALIGNED(MEMORY_HOOK_ALIGNMENT);
  128. void deallocate_array(void *ptr);
  129. constexpr static TypeHandle from_index(int index) { return TypeHandle(index); }
  130. private:
  131. constexpr TypeHandle(int index);
  132. int _index;
  133. friend class TypeRegistry;
  134. };
  135. // It's handy to be able to output a TypeHandle directly, and see the type
  136. // name.
  137. INLINE std::ostream &operator << (std::ostream &out, TypeHandle type) {
  138. type.output(out);
  139. return out;
  140. }
  141. EXPCL_DTOOL_DTOOLBASE std::ostream &operator << (std::ostream &out, TypeHandle::MemoryClass mem_class);
  142. // We must include typeRegistry at this point so we can call it from our
  143. // inline functions. This is a circular include that is strategically placed
  144. // to do no harm.
  145. /* okcircular */
  146. #include "typeRegistry.h"
  147. #include "typeHandle.I"
  148. #endif