25 using std::ostringstream;
42 if (type_handle != TypeHandle::none()) {
46 if (&type_handle == &rnode->_ref) {
49 assert(rnode->_name == name);
54 NameRegistry::iterator ri;
55 ri = _name_registry.find(name);
57 if (ri == _name_registry.end()) {
62 new_handle._index = (int)_handle_registry.size();
65 _handle_registry.push_back(rnode);
66 _name_registry[name] = rnode;
67 _derivations_fresh =
false;
69 type_handle = new_handle;
74 assert(rnode->_name == (*ri).first);
75 assert(rnode->_handle._index >= 0 &&
76 rnode->_handle._index < (
int)_handle_registry.size());
77 assert(_handle_registry[rnode->_handle._index] == rnode);
78 assert(rnode->_handle._index != 0);
81 if (&type_handle == &rnode->_ref) {
84 if (type_handle == rnode->_handle) {
93 cerr <<
"Reregistering " << name <<
"\n";
94 type_handle = rnode->_handle;
99 if (type_handle != rnode->_handle) {
102 <<
"Attempt to register type " << name <<
" more than once!\n";
109 type_handle = rnode->_handle;
124 NameRegistry::iterator ri;
125 ri = _name_registry.find(name);
127 if (ri == _name_registry.end()) {
135 new_handle->_index = (int)_handle_registry.size();
138 _handle_registry.push_back(rnode);
139 _name_registry[name] = rnode;
140 _derivations_fresh =
false;
163 assert(cnode !=
nullptr);
165 assert(pnode !=
nullptr);
169 TypeRegistryNode::Classes::iterator ni;
170 ni = find(cnode->_parent_classes.begin(), cnode->_parent_classes.end(),
173 if (ni == cnode->_parent_classes.end()) {
174 cnode->_parent_classes.push_back(pnode);
175 pnode->_child_classes.push_back(cnode);
176 _derivations_fresh =
false;
193 if (rnode !=
nullptr) {
194 NameRegistry::iterator ri =
195 _name_registry.insert(NameRegistry::value_type(name, rnode)).first;
197 if ((*ri).second != rnode) {
200 <<
"Name " << name <<
" already assigned to TypeHandle " 201 << rnode->_name <<
"; cannot reassign to " << type <<
"\n";
216 record_python_type(
TypeHandle type, PyObject *python_type) {
220 if (rnode !=
nullptr) {
221 rnode->_python_type = python_type;
237 NameRegistry::const_iterator ri;
238 ri = _name_registry.find(name);
239 if (ri != _name_registry.end()) {
240 handle = (*ri).second->_handle;
254 if (id < 0 ||id >= (
int)_handle_registry.size()) {
256 <<
"Invalid TypeHandle index " <<
id 257 <<
"! Is memory corrupt?\n";
258 return TypeHandle::none();
261 return _handle_registry[id]->_handle;
276 assert(rnode !=
nullptr);
277 string name = rnode->_name;
304 assert(child_node !=
nullptr);
305 assert(base_node !=
nullptr);
307 freshen_derivations();
318 get_num_typehandles() {
320 int num_types = (int)_handle_registry.size();
332 if (n >= 0 && n < (
int)_handle_registry.size()) {
333 rnode = _handle_registry[n];
337 if (rnode !=
nullptr) {
338 return rnode->_handle;
341 return TypeHandle::none();
349 get_num_root_classes() {
351 freshen_derivations();
352 int num_roots = (int)_root_classes.size();
363 freshen_derivations();
365 if (n >= 0 && n < (
int)_root_classes.size()) {
366 handle = _root_classes[n]->_handle;
368 handle = TypeHandle::none();
390 assert(rnode !=
nullptr);
391 int num_parents = (int)rnode->_parent_classes.size();
405 assert(rnode !=
nullptr);
406 if (index >= 0 && index < (
int)rnode->_parent_classes.size()) {
407 handle = rnode->_parent_classes[index]->_handle;
409 handle = TypeHandle::none();
427 assert(rnode !=
nullptr);
428 int num_children = (int)rnode->_child_classes.size();
442 assert(rnode !=
nullptr);
443 if (index >= 0 && index < (
int)rnode->_child_classes.size()) {
444 handle = rnode->_child_classes[index]->_handle;
446 handle = TypeHandle::none();
469 assert(child_node !=
nullptr &&
470 base_node !=
nullptr);
471 freshen_derivations();
489 HandleRegistry::iterator ri;
491 for (ri = reg->_handle_registry.begin();
492 ri != reg->_handle_registry.end();
495 if (rnode !=
nullptr && rnode->_handle != rnode->_ref) {
496 cerr <<
"Reregistering " << rnode->_name <<
"\n";
522 _handle_registry.push_back(
nullptr);
524 _derivations_fresh =
false;
529 assert(
sizeof(uint8_t) == 1 &&
sizeof(int8_t) == 1);
530 assert(
sizeof(uint16_t) == 2 &&
sizeof(int16_t) == 2);
531 assert(
sizeof(uint32_t) == 4 &&
sizeof(int32_t) == 4);
532 assert(
sizeof(uint64_t) == 8 &&
sizeof(int64_t) == 8);
534 assert(
sizeof(PN_float32) == 4);
535 assert(
sizeof(PN_float64) == 8);
542 init_global_pointer() {
553 rebuild_derivations() {
556 _root_classes.clear();
558 HandleRegistry::iterator hi;
559 for (hi = _handle_registry.begin();
560 hi != _handle_registry.end();
563 if (node !=
nullptr) {
570 for (hi = _handle_registry.begin();
571 hi != _handle_registry.end();
574 if (node !=
nullptr && node->_parent_classes.empty()) {
575 _root_classes.push_back(node);
588 do_write(ostream &out)
const {
591 HandleRegistry::const_iterator hi;
592 for (hi = _handle_registry.begin();
593 hi != _handle_registry.end();
596 if (root !=
nullptr && root->_parent_classes.empty()) {
597 write_node(out, 2, root);
607 write_node(ostream &out,
int indent_level,
const TypeRegistryNode *node)
const {
608 indent(out, indent_level) << node->_handle.
get_index() <<
" " << node->_name;
609 if (!node->_parent_classes.empty()) {
610 out <<
" : " << node->_parent_classes[0]->_name;
611 for (
int pi = 1; pi < (int)node->_parent_classes.size(); pi++) {
612 out <<
", " << node->_parent_classes[pi]->_name;
617 for (
int i = 0; i < (int)node->_child_classes.size(); i++) {
618 write_node(out, indent_level + 2, node->_child_classes[i]);
632 if (handle._index == 0) {
635 if (
object !=
nullptr) {
640 handle =
object->force_init_type();
643 if (handle._index == 0) {
646 <<
"Unable to force_init_type() on unregistered TypeHandle.\n";
653 if (handle._index > 0 && handle._index < (
int)_handle_registry.size()) {
655 if (rnode !=
nullptr) {
656 name << rnode->_name;
657 name <<
" (index " << handle._index <<
")";
659 name <<
"NULL (index " << handle._index <<
")";
662 name <<
"index " << handle._index;
665 if (handle == object->get_type()) {
668 <<
"Type " << name.str() <<
" was unregistered!\n";
673 <<
"Attempt to reference unregistered TypeHandle. Type is of some\n" 674 <<
"class derived from type " << name.str() <<
" that doesn't define\n" 675 <<
"a good force_init_type() method.\n";
683 <<
"Attempt to reference unregistered TypeHandle!\n" 684 <<
"Registered TypeHandles are:\n";
690 if (handle._index < 0 ||
691 handle._index >= (
int)_handle_registry.size()) {
693 <<
"Invalid TypeHandle index " << handle._index
694 <<
"! Is memory corrupt?\n";
699 return _handle_registry[handle._index];
706 get_best_parent_from_Set(
int id,
const std::set<int> &this_set) {
708 if (this_set.find(
id) != this_set.end()) {
713 if (th == TypeHandle::none()) {
bool is_derived_from(TypeHandle child, TypeHandle base, TypedObject *child_object)
Returns true if the first type is derived from the second type, false otherwise.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
int get_best_parent_from_Set(const std::set< int > &legal_vals) const
Return the Index of the BEst fit Classs from a set.
void clear_subtree()
Removes any subtree definition previously set up via define_subtree(), in preparation for rebuilding ...
TypeHandle find_type_by_id(int id) const
Looks for a previously-registered type with the given id number (as returned by TypeHandle::get_index...
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.
get_root_class
Returns the nth root class in the system.
std::string get_name(TypeHandle type, TypedObject *object) const
Returns the name of the indicated type.
void record_alternate_name(TypeHandle type, const std::string &name)
Indicates an alternate name for the same type.
int get_num_child_classes(TypeHandle child, TypedObject *child_object) const
Returns the number of child classes that the indicated type is known to have.
This is an abstract class that all classes which use TypeHandle, and also provide virtual functions t...
TypeHandle register_dynamic_type(const std::string &name)
Registers a new type on-the-fly, presumably at runtime.
TypeHandle find_type(const std::string &name) const
Looks for a previously-registered type of the given name.
This is a single entry in the TypeRegistry.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
TypeHandle get_parent_class(TypeHandle child, int index) const
Returns the nth parent class of this type.
TypeHandle get_parent_towards(TypeHandle child, TypeHandle base, TypedObject *child_object)
Returns the parent of the indicated child class that is in a direct line of inheritance to the indica...
bool register_type(TypeHandle &type_handle, const std::string &name)
Creates a new Type of the given name and assigns a unique value to the type_handle.
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...
int get_num_parent_classes(TypeHandle child, TypedObject *child_object) const
Returns the number of parent classes that the indicated type is known to have.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
std::ostream & indent(std::ostream &out, int indent_level)
A handy function for doing text formatting.
get_index
Returns the integer index associated with this TypeHandle.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
TypeHandle get_child_class(TypeHandle child, int index) const
Returns the nth child class of this type.
static void reregister_types()
Walks through the TypeRegistry tree and makes sure that each type that was previously registered is *...
get_typehandle
Returns the nth TypeHandle in the system.
static TypeRegistry * ptr()
Returns the pointer to the global TypeRegistry object.
The TypeRegistry class maintains all the assigned TypeHandles in a given system.
void define_subtree()
Indicates that this TypeRegistryNode is the top of a subtree within the inheritance graph (typically,...
A fake mutex implementation for single-threaded applications that don't need any synchronization cont...
void write(std::ostream &out) const
Makes an attempt to format the entire TypeRegistry in a nice way that shows the derivation tree as in...
TypeHandle is the identifier used to differentiate C++ class types.
void record_derivation(TypeHandle child, TypeHandle parent)
Records that the type referenced by child inherits directly from the type referenced by parent.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.