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