19 bool TypeRegistryNode::_paranoid_inheritance =
false;
26 _handle(handle), _name(name), _ref(ref)
29 memset(_memory_usage, 0,
sizeof(_memory_usage));
47 if (child->_inherit._top == base->_inherit._top) {
48 assert(child->_inherit._top !=
nullptr);
51 Inherit::is_derived_from(child->_inherit, base->_inherit);
54 if (_paranoid_inheritance) {
55 bool paranoid_derives = check_derived_from(child, base);
56 if (derives != paranoid_derives) {
58 <<
"Inheritance test for " << child->_name
59 <<
" from " << base->_name <<
" failed!\n" 60 <<
"Result: " << derives <<
" should have been: " 61 << paranoid_derives <<
"\n" 62 <<
"Classes are in the same single inheritance subtree, children of " 63 << child->_inherit._top->_name <<
"\n" 65 << child->_name <<
" has mask " << child->_inherit._mask
66 <<
" and bits " << child->_inherit._bits <<
"\n" 67 << base->_name <<
" has mask " << base->_inherit._mask
68 <<
" and bits " << base->_inherit._bits <<
"\n" 70 return paranoid_derives;
95 TopInheritance::const_iterator ti =
96 lower_bound(child_top->_top_inheritance.begin(),
97 child_top->_top_inheritance.end(),
98 Inherit(base_top, 0, 0));
100 while (ti != child_top->_top_inheritance.end() &&
101 (*ti)._top == base_top &&
107 const Inherit &connection = (*ti);
112 derives = Inherit::is_derived_from(connection, base->_inherit);
118 if (_paranoid_inheritance) {
119 bool paranoid_derives = check_derived_from(child, base);
120 if (derives != paranoid_derives) {
122 <<
"Inheritance test for " << child->_name
123 <<
" from " << base->_name <<
" failed!\n" 124 <<
"Result: " << derives <<
" should have been: " 125 << paranoid_derives <<
"\n" 126 << child->_name <<
" is a descendent of " 127 << child_top->_name <<
"\n" 128 << base->_name <<
" is a descendent of " 129 << base_top->_name <<
"\n";
130 return paranoid_derives;
151 return child->_handle;
154 Classes::const_iterator ni;
155 for (ni = child->_parent_classes.begin();
156 ni != child->_parent_classes.end(); ++ni) {
158 return (*ni)->_handle;
162 return TypeHandle::none();
172 _inherit = Inherit();
173 _top_inheritance.clear();
195 r_build_subtrees(
this, 0, 0);
203 void TypeRegistryNode::
205 TypeRegistryNode::SubtreeMaskType bits) {
243 if (top !=
this && _parent_classes.size() != 1) {
244 assert(!_parent_classes.empty());
249 _top_inheritance.insert(_top_inheritance.end(),
250 top->_top_inheritance.begin(),
251 top->_top_inheritance.end());
252 _top_inheritance.push_back(Inherit(top, bit_count, bits));
255 if (_visit_count == (
int)_parent_classes.size()) {
258 assert(_inherit._top ==
nullptr);
259 sort(_top_inheritance.begin(), _top_inheritance.end());
266 assert(_inherit._top ==
nullptr);
268 assert(bit_count < (
int)(
sizeof(SubtreeMaskType) * 8));
270 _inherit = Inherit(top, bit_count, bits);
273 int num_children = (int)_child_classes.size();
275 int i = num_children - 1;
283 more_bits = std::max(more_bits, 1);
285 assert(more_bits < (
int)(
sizeof(SubtreeMaskType) * 8));
287 if (bit_count + more_bits > (
int)(
sizeof(SubtreeMaskType) * 8)) {
292 _top_inheritance = top->_top_inheritance;
293 _top_inheritance.push_back(_inherit);
294 sort(_top_inheritance.begin(), _top_inheritance.end());
295 _inherit = Inherit();
300 for (i = 0; i < num_children; i++) {
302 SubtreeMaskType next_bits = ((SubtreeMaskType)i << bit_count);
304 child->r_build_subtrees(top, bit_count + more_bits,
315 PyObject *TypeRegistryNode::
316 r_get_python_type()
const {
317 Classes::const_iterator ni;
318 for (ni = _parent_classes.begin(); ni != _parent_classes.end(); ++ni) {
320 if (parent->_python_type !=
nullptr) {
321 return parent->_python_type;
323 }
else if (!parent->_parent_classes.empty()) {
324 PyObject *py_type = parent->r_get_python_type();
325 if (py_type !=
nullptr) {
340 bool TypeRegistryNode::
347 Classes::const_iterator ni;
348 for (ni = child->_parent_classes.begin();
349 ni != child->_parent_classes.end();
351 if (check_derived_from(*ni, base)) {
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void clear_subtree()
Removes any subtree definition previously set up via define_subtree(), in preparation for rebuilding ...
static TypeHandle get_parent_towards(const TypeRegistryNode *child, const TypeRegistryNode *base)
Returns the first parent class of child that is a descendant of the indicated base class.
This is a single entry in the TypeRegistry.
static bool is_derived_from(const TypeRegistryNode *child, const TypeRegistryNode *base)
Returns true if the child RegistryNode represents a class that inherits directly or indirectly from t...
void define_subtree()
Indicates that this TypeRegistryNode is the top of a subtree within the inheritance graph (typically,...
TypeHandle is the identifier used to differentiate C++ class types.