diff --git a/dtool/src/dtoolbase/typeHandle.cxx b/dtool/src/dtoolbase/typeHandle.cxx index 15fac6b60f..30d499bf01 100644 --- a/dtool/src/dtoolbase/typeHandle.cxx +++ b/dtool/src/dtoolbase/typeHandle.cxx @@ -153,6 +153,19 @@ deallocate_array(void *ptr) { PANDA_FREE_ARRAY(ptr); } +/** + * Returns the internal void pointer that is stored for interrogate's benefit. + */ +PyObject *TypeHandle:: +get_python_type() const { + TypeRegistryNode *rnode = TypeRegistry::ptr()->look_up(*this, nullptr); + if (rnode != nullptr) { + return rnode->get_python_type(); + } else { + return nullptr; + } +} + /** * Return the Index of the BEst fit Classs from a set */ diff --git a/dtool/src/dtoolbase/typeHandle.h b/dtool/src/dtoolbase/typeHandle.h index 97dc445443..ed5ab3f586 100644 --- a/dtool/src/dtoolbase/typeHandle.h +++ b/dtool/src/dtoolbase/typeHandle.h @@ -138,6 +138,8 @@ PUBLISHED: MAKE_SEQ_PROPERTY(child_classes, get_num_child_classes, get_child_class); public: + PyObject *get_python_type() const; + void *allocate_array(size_t size) RETURNS_ALIGNED(MEMORY_HOOK_ALIGNMENT); void *reallocate_array(void *ptr, size_t size) RETURNS_ALIGNED(MEMORY_HOOK_ALIGNMENT); void deallocate_array(void *ptr); diff --git a/dtool/src/dtoolbase/typeRegistry.cxx b/dtool/src/dtoolbase/typeRegistry.cxx index 23cdb5ebfb..d18ca61244 100644 --- a/dtool/src/dtoolbase/typeRegistry.cxx +++ b/dtool/src/dtoolbase/typeRegistry.cxx @@ -207,6 +207,22 @@ record_alternate_name(TypeHandle type, const string &name) { _lock->unlock(); } +/** + * Records the given Python type pointer in the type registry for the benefit + * of interrogate. + */ +void TypeRegistry:: +record_python_type(TypeHandle type, PyObject *python_type) { + _lock->lock(); + + TypeRegistryNode *rnode = look_up(type, nullptr); + if (rnode != nullptr) { + rnode->_python_type = python_type; + } + + _lock->unlock(); +} + /** * Looks for a previously-registered type of the given name. Returns its * TypeHandle if it exists, or TypeHandle::none() if there is no such type. diff --git a/dtool/src/dtoolbase/typeRegistry.h b/dtool/src/dtoolbase/typeRegistry.h index dc7df60541..4a6bd5d1e0 100644 --- a/dtool/src/dtoolbase/typeRegistry.h +++ b/dtool/src/dtoolbase/typeRegistry.h @@ -45,6 +45,7 @@ PUBLISHED: void record_derivation(TypeHandle child, TypeHandle parent); void record_alternate_name(TypeHandle type, const std::string &name); + void record_python_type(TypeHandle type, PyObject *python_type); TypeHandle find_type(const std::string &name) const; TypeHandle find_type_by_id(int id) const; diff --git a/dtool/src/dtoolbase/typeRegistryNode.I b/dtool/src/dtoolbase/typeRegistryNode.I index 4328a47d79..1556e63847 100644 --- a/dtool/src/dtoolbase/typeRegistryNode.I +++ b/dtool/src/dtoolbase/typeRegistryNode.I @@ -11,6 +11,19 @@ * @date 2001-08-06 */ +/** + * Returns the Python type object associated with this node. + */ +INLINE PyObject *TypeRegistryNode:: +get_python_type() const { + if (_python_type != nullptr || _parent_classes.empty()) { + return _python_type; + } else { + // Recurse through parent classes. + return r_get_python_type(); + } +} + /** * */ diff --git a/dtool/src/dtoolbase/typeRegistryNode.cxx b/dtool/src/dtoolbase/typeRegistryNode.cxx index f809ddcc0b..19b4629236 100644 --- a/dtool/src/dtoolbase/typeRegistryNode.cxx +++ b/dtool/src/dtoolbase/typeRegistryNode.cxx @@ -308,6 +308,29 @@ r_build_subtrees(TypeRegistryNode *top, int bit_count, } } +/** + * Recurses through the parent nodes to find the best Python type object to + * represent objects of this type. + */ +PyObject *TypeRegistryNode:: +r_get_python_type() const { + Classes::const_iterator ni; + for (ni = _parent_classes.begin(); ni != _parent_classes.end(); ++ni) { + const TypeRegistryNode *parent = *ni; + if (parent->_python_type != nullptr) { + return parent->_python_type; + + } else if (!parent->_parent_classes.empty()) { + PyObject *py_type = parent->r_get_python_type(); + if (py_type != nullptr) { + return py_type; + } + } + } + + return nullptr; +} + /** * A recursive function to double-check the result of is_derived_from(). This * is the slow, examine-the-whole-graph approach, as opposed to the clever and diff --git a/dtool/src/dtoolbase/typeRegistryNode.h b/dtool/src/dtoolbase/typeRegistryNode.h index dd888cbf59..7dd7f387cc 100644 --- a/dtool/src/dtoolbase/typeRegistryNode.h +++ b/dtool/src/dtoolbase/typeRegistryNode.h @@ -37,6 +37,8 @@ public: static TypeHandle get_parent_towards(const TypeRegistryNode *child, const TypeRegistryNode *base); + INLINE PyObject *get_python_type() const; + void clear_subtree(); void define_subtree(); @@ -46,6 +48,7 @@ public: typedef std::vector Classes; Classes _parent_classes; Classes _child_classes; + PyObject *_python_type = nullptr; AtomicAdjust::Integer _memory_usage[TypeHandle::MC_limit]; @@ -77,6 +80,8 @@ private: void r_build_subtrees(TypeRegistryNode *top, int bit_count, SubtreeMaskType bits); + PyObject *r_get_python_type() const; + static bool check_derived_from(const TypeRegistryNode *child, const TypeRegistryNode *base); diff --git a/dtool/src/interrogate/interfaceMakerPythonNative.cxx b/dtool/src/interrogate/interfaceMakerPythonNative.cxx index 8d2b0f2288..60d2dd6466 100644 --- a/dtool/src/interrogate/interfaceMakerPythonNative.cxx +++ b/dtool/src/interrogate/interfaceMakerPythonNative.cxx @@ -821,10 +821,54 @@ write_prototypes(ostream &out_code, ostream *out_h) { } } + out_code << "/**\n"; + out_code << " * Declarations for exported classes\n"; + out_code << " */\n"; + + out_code << "static const Dtool_TypeDef exports[] = {\n"; + + for (oi = _objects.begin(); oi != _objects.end(); ++oi) { + Object *object = (*oi).second; + + if (object->_itype.is_class() || object->_itype.is_struct()) { + CPPType *type = object->_itype._cpptype; + + if (isExportThisRun(type) && is_cpp_type_legal(type)) { + string class_name = type->get_local_name(&parser); + string safe_name = make_safe_name(class_name); + + out_code << " {\"" << class_name << "\", &Dtool_" << safe_name << "},\n"; + } + } + } + + out_code << " {nullptr, nullptr},\n"; + out_code << "};\n\n"; + out_code << "/**\n"; out_code << " * Extern declarations for imported classes\n"; out_code << " */\n"; + // Write out a table of the externally imported types that will be filled in + // upon module initialization. + if (!_external_imports.empty()) { + out_code << "#ifndef LINK_ALL_STATIC\n"; + out_code << "static Dtool_TypeDef imports[] = {\n"; + + int idx = 0; + for (CPPType *type : _external_imports) { + string class_name = type->get_local_name(&parser); + string safe_name = make_safe_name(class_name); + + out_code << " {\"" << class_name << "\", nullptr},\n"; + out_code << "#define Dtool_Ptr_" << safe_name << " (imports[" << idx << "].type)\n"; + ++idx; + } + out_code << " {nullptr, nullptr},\n"; + out_code << "};\n"; + out_code << "#endif\n\n"; + } + for (CPPType *type : _external_imports) { string class_name = type->get_local_name(&parser); string safe_name = make_safe_name(class_name); @@ -834,7 +878,9 @@ write_prototypes(ostream &out_code, ostream *out_h) { out_code << "#ifndef LINK_ALL_STATIC\n"; // out_code << "IMPORT_THIS struct Dtool_PyTypedObject Dtool_" << // safe_name << ";\n"; - out_code << "static struct Dtool_PyTypedObject *Dtool_Ptr_" << safe_name << ";\n"; + //if (has_get_class_type_function(type)) { + // out_code << "static struct Dtool_PyTypedObject *Dtool_Ptr_" << safe_name << ";\n"; + //} // out_code << "#define Dtool_Ptr_" << safe_name << " &Dtool_" << // safe_name << "\n"; out_code << "IMPORT_THIS void // Dtool_PyModuleClassInit_" << safe_name << "(PyObject *module);\n"; @@ -1258,36 +1304,36 @@ write_module_support(ostream &out, ostream *out_h, InterrogateModuleDef *def) { Objects::iterator oi; - out << "void Dtool_" << def->library_name << "_RegisterTypes() {\n"; + out << "void Dtool_" << def->library_name << "_RegisterTypes() {\n" + " TypeRegistry *registry = TypeRegistry::ptr();\n" + " nassertv(registry != nullptr);\n"; + for (oi = _objects.begin(); oi != _objects.end(); ++oi) { Object *object = (*oi).second; - if (object->_itype.is_class() || - object->_itype.is_struct()) { - if (is_cpp_type_legal(object->_itype._cpptype) && - isExportThisRun(object->_itype._cpptype)) { - string class_name = make_safe_name(object->_itype.get_scoped_name()); - bool is_typed = has_get_class_type_function(object->_itype._cpptype); + if (object->_itype.is_class() || object->_itype.is_struct()) { + CPPType *type = object->_itype._cpptype; + if (is_cpp_type_legal(type) && isExportThisRun(type)) { + string class_name = object->_itype.get_scoped_name(); + string safe_name = make_safe_name(class_name); + bool is_typed = has_get_class_type_function(type); if (is_typed) { - if (has_init_type_function(object->_itype._cpptype)) { + out << " {\n"; + if (has_init_type_function(type)) { // Call the init_type function. This isn't necessary for all // types as many of them are automatically initialized at static // init type, but for some extension classes it's useful. - out << " " << object->_itype._cpptype->get_local_name(&parser) + out << " " << type->get_local_name(&parser) << "::init_type();\n"; } - out << " Dtool_" << class_name << "._type = " - << object->_itype._cpptype->get_local_name(&parser) - << "::get_class_type();\n" - << " RegisterRuntimeTypedClass(Dtool_" << class_name << ");\n"; - + out << " TypeHandle handle = " << type->get_local_name(&parser) + << "::get_class_type();\n"; + out << " Dtool_" << safe_name << "._type = handle;\n"; + out << " registry->record_python_type(handle, " + "(PyObject *)&Dtool_" << safe_name << ");\n"; + out << " }\n"; } else { - out << "#ifndef LINK_ALL_STATIC\n" - << " RegisterNamedClass(\"" << object->_itype.get_scoped_name() - << "\", Dtool_" << class_name << ");\n" - << "#endif\n"; - - if (IsPandaTypedObject(object->_itype._cpptype->as_struct_type())) { + if (IsPandaTypedObject(type->as_struct_type())) { nout << object->_itype.get_scoped_name() << " derives from TypedObject, " << "but does not define a get_class_type() function.\n"; } @@ -1297,23 +1343,6 @@ write_module_support(ostream &out, ostream *out_h, InterrogateModuleDef *def) { } out << "}\n\n"; - out << "void Dtool_" << def->library_name << "_ResolveExternals() {\n"; - out << "#ifndef LINK_ALL_STATIC\n"; - out << " // Resolve externally imported types.\n"; - - for (CPPType *type : _external_imports) { - string class_name = type->get_local_name(&parser); - string safe_name = make_safe_name(class_name); - - if (has_get_class_type_function(type)) { - out << " Dtool_Ptr_" << safe_name << " = LookupRuntimeTypedClass(" << class_name << "::get_class_type());\n"; - } else { - out << " Dtool_Ptr_" << safe_name << " = LookupNamedClass(\"" << class_name << "\");\n"; - } - } - out << "#endif\n"; - out << "}\n\n"; - out << "void Dtool_" << def->library_name << "_BuildInstants(PyObject *module) {\n"; out << " (void) module;\n"; @@ -1466,9 +1495,14 @@ write_module_support(ostream &out, ostream *out_h, InterrogateModuleDef *def) { out << " {nullptr, nullptr, 0, nullptr}\n" << "};\n\n"; - out << "struct LibraryDef " << def->library_name << "_moddef = {python_simple_funcs};\n"; + out << "extern const struct LibraryDef " << def->library_name << "_moddef = {python_simple_funcs, exports, "; + if (_external_imports.empty()) { + out << "nullptr};\n"; + } else { + out << "imports};\n"; + } if (out_h != nullptr) { - *out_h << "extern struct LibraryDef " << def->library_name << "_moddef;\n"; + *out_h << "extern const struct LibraryDef " << def->library_name << "_moddef;\n"; } } diff --git a/dtool/src/interrogate/interrogate_module.cxx b/dtool/src/interrogate/interrogate_module.cxx index 5c5cc9d9ab..986033fd3c 100644 --- a/dtool/src/interrogate/interrogate_module.cxx +++ b/dtool/src/interrogate/interrogate_module.cxx @@ -286,9 +286,8 @@ int write_python_table_native(std::ostream &out) { vector_string::const_iterator ii; for (ii = libraries.begin(); ii != libraries.end(); ++ii) { printf("Referencing Library %s\n", (*ii).c_str()); - out << "extern LibraryDef " << *ii << "_moddef;\n"; + out << "extern const struct LibraryDef " << *ii << "_moddef;\n"; out << "extern void Dtool_" << *ii << "_RegisterTypes();\n"; - out << "extern void Dtool_" << *ii << "_ResolveExternals();\n"; out << "extern void Dtool_" << *ii << "_BuildInstants(PyObject *module);\n"; } @@ -339,12 +338,9 @@ int write_python_table_native(std::ostream &out) { for (ii = libraries.begin(); ii != libraries.end(); ii++) { out << " Dtool_" << *ii << "_RegisterTypes();\n"; } - for (ii = libraries.begin(); ii != libraries.end(); ii++) { - out << " Dtool_" << *ii << "_ResolveExternals();\n"; - } out << "\n"; - out << " LibraryDef *defs[] = {"; + out << " const LibraryDef *defs[] = {"; for(ii = libraries.begin(); ii != libraries.end(); ii++) { out << "&" << *ii << "_moddef, "; } @@ -386,12 +382,9 @@ int write_python_table_native(std::ostream &out) { for (ii = libraries.begin(); ii != libraries.end(); ii++) { out << " Dtool_" << *ii << "_RegisterTypes();\n"; } - for (ii = libraries.begin(); ii != libraries.end(); ii++) { - out << " Dtool_" << *ii << "_ResolveExternals();\n"; - } out << "\n"; - out << " LibraryDef *defs[] = {"; + out << " const LibraryDef *defs[] = {"; for(ii = libraries.begin(); ii != libraries.end(); ii++) { out << "&" << *ii << "_moddef, "; } diff --git a/dtool/src/interrogatedb/py_panda.I b/dtool/src/interrogatedb/py_panda.I index 69f8961463..f5f504ca97 100644 --- a/dtool/src/interrogatedb/py_panda.I +++ b/dtool/src/interrogatedb/py_panda.I @@ -26,7 +26,7 @@ template INLINE bool DtoolInstance_GetPointer(PyObject *self, T *&into) { if (DtoolInstance_Check(self)) { - Dtool_PyTypedObject *target_class = Dtool_RuntimeTypeDtoolType(get_type_handle(T).get_index()); + Dtool_PyTypedObject *target_class = (Dtool_PyTypedObject *)get_type_handle(T).get_python_type(); if (target_class != nullptr) { if (_IS_FINAL(T)) { if (DtoolInstance_TYPE(self) == target_class) { @@ -116,28 +116,28 @@ INLINE long Dtool_EnumValue_AsLong(PyObject *value) { */ template INLINE PyObject * DTool_CreatePyInstance(const T *obj, bool memory_rules) { - Dtool_PyTypedObject *known_class = Dtool_RuntimeTypeDtoolType(get_type_handle(T).get_index()); + Dtool_PyTypedObject *known_class = (Dtool_PyTypedObject *)get_type_handle(T).get_python_type(); nassertr(known_class != nullptr, nullptr); return DTool_CreatePyInstance((void*) obj, *known_class, memory_rules, true); } template INLINE PyObject * DTool_CreatePyInstance(T *obj, bool memory_rules) { - Dtool_PyTypedObject *known_class = Dtool_RuntimeTypeDtoolType(get_type_handle(T).get_index()); + Dtool_PyTypedObject *known_class = (Dtool_PyTypedObject *)get_type_handle(T).get_python_type(); nassertr(known_class != nullptr, nullptr); return DTool_CreatePyInstance((void*) obj, *known_class, memory_rules, false); } template INLINE PyObject * DTool_CreatePyInstanceTyped(const T *obj, bool memory_rules) { - Dtool_PyTypedObject *known_class = Dtool_RuntimeTypeDtoolType(get_type_handle(T).get_index()); + Dtool_PyTypedObject *known_class = (Dtool_PyTypedObject *)get_type_handle(T).get_python_type(); nassertr(known_class != nullptr, nullptr); return DTool_CreatePyInstanceTyped((void*) obj, *known_class, memory_rules, true, obj->get_type().get_index()); } template INLINE PyObject * DTool_CreatePyInstanceTyped(T *obj, bool memory_rules) { - Dtool_PyTypedObject *known_class = Dtool_RuntimeTypeDtoolType(get_type_handle(T).get_index()); + Dtool_PyTypedObject *known_class = (Dtool_PyTypedObject *)get_type_handle(T).get_python_type(); nassertr(known_class != nullptr, nullptr); return DTool_CreatePyInstanceTyped((void*) obj, *known_class, memory_rules, false, obj->get_type().get_index()); } diff --git a/dtool/src/interrogatedb/py_panda.cxx b/dtool/src/interrogatedb/py_panda.cxx index c29796def6..68264daf0b 100644 --- a/dtool/src/interrogatedb/py_panda.cxx +++ b/dtool/src/interrogatedb/py_panda.cxx @@ -29,10 +29,6 @@ PyMemberDef standard_type_members[] = { {nullptr} /* Sentinel */ }; -static RuntimeTypeMap runtime_type_map; -static RuntimeTypeSet runtime_type_set; -static NamedTypeMap named_type_map; - /** */ @@ -431,7 +427,7 @@ PyObject *DTool_CreatePyInstanceTyped(void *local_this_in, Dtool_PyTypedObject & // IF the class is possibly a run time typed object if (type_index > 0) { // get best fit class... - Dtool_PyTypedObject *target_class = Dtool_RuntimeTypeDtoolType(type_index); + Dtool_PyTypedObject *target_class = (Dtool_PyTypedObject *)TypeHandle::from_index(type_index).get_python_type(); if (target_class != nullptr) { // cast to the type... void *new_local_this = target_class->_Dtool_DowncastInterface(local_this_in, &known_class_type); @@ -507,109 +503,30 @@ void Dtool_Accum_MethDefs(PyMethodDef in[], MethodDefmap &themap) { } } -// ** HACK ** alert.. Need to keep a runtime type dictionary ... that is -// forward declared of typed object. We rely on the fact that typed objects -// are uniquly defined by an integer. -void -RegisterNamedClass(const string &name, Dtool_PyTypedObject &otype) { - std::pair result = - named_type_map.insert(NamedTypeMap::value_type(name, &otype)); - - if (!result.second) { - // There was already a class with this name in the dictionary. - interrogatedb_cat.warning() - << "Double definition for class " << name << "\n"; - } -} - -void -RegisterRuntimeTypedClass(Dtool_PyTypedObject &otype) { - int type_index = otype._type.get_index(); - - if (type_index == 0) { - interrogatedb_cat.warning() - << "Class " << otype._PyType.tp_name - << " has a zero TypeHandle value; check that init_type() is called.\n"; - - } else if (type_index < 0 || type_index >= TypeRegistry::ptr()->get_num_typehandles()) { - interrogatedb_cat.warning() - << "Class " << otype._PyType.tp_name - << " has an illegal TypeHandle value; check that init_type() is called.\n"; - +/** + * Returns a borrowed reference to the global type dictionary. + */ +Dtool_TypeMap *Dtool_GetGlobalTypeMap() { + PyObject *capsule = PySys_GetObject("_interrogate_types"); + if (capsule != nullptr) { + return (Dtool_TypeMap *)PyCapsule_GetPointer(capsule, nullptr); } else { - std::pair result = - runtime_type_map.insert(RuntimeTypeMap::value_type(type_index, &otype)); - if (!result.second) { - // There was already an entry in the dictionary for type_index. - Dtool_PyTypedObject *other_type = (*result.first).second; - interrogatedb_cat.warning() - << "Classes " << otype._PyType.tp_name - << " and " << other_type->_PyType.tp_name - << " share the same TypeHandle value (" << type_index - << "); check class definitions.\n"; - - } else { - runtime_type_set.insert(type_index); - } - } -} - -Dtool_PyTypedObject * -LookupNamedClass(const string &name) { - NamedTypeMap::const_iterator it; - it = named_type_map.find(name); - - if (it == named_type_map.end()) { - // Find a type named like this in the type registry. - TypeHandle handle = TypeRegistry::ptr()->find_type(name); - if (handle.get_index() > 0) { - RuntimeTypeMap::const_iterator it2; - it2 = runtime_type_map.find(handle.get_index()); - if (it2 != runtime_type_map.end()) { - return it2->second; - } - } - - interrogatedb_cat.error() - << "Attempt to use type " << name << " which has not yet been defined!\n"; - return nullptr; - } else { - return it->second; - } -} - -Dtool_PyTypedObject * -LookupRuntimeTypedClass(TypeHandle handle) { - RuntimeTypeMap::const_iterator it; - it = runtime_type_map.find(handle.get_index()); - - if (it == runtime_type_map.end()) { - interrogatedb_cat.error() - << "Attempt to use type " << handle << " which has not yet been defined!\n"; - return nullptr; - } else { - return it->second; + Dtool_TypeMap *type_map = new Dtool_TypeMap; + capsule = PyCapsule_New((void *)type_map, nullptr, nullptr); + PySys_SetObject("_interrogate_types", capsule); + Py_DECREF(capsule); + return type_map; } } Dtool_PyTypedObject *Dtool_RuntimeTypeDtoolType(int type) { - RuntimeTypeMap::iterator di = runtime_type_map.find(type); - if (di != runtime_type_map.end()) { - return di->second; - } else { - int type2 = get_best_parent_from_Set(type, runtime_type_set); - di = runtime_type_map.find(type2); - if (di != runtime_type_map.end()) { - return di->second; - } - } - return nullptr; + return (Dtool_PyTypedObject *)TypeHandle::from_index(type).get_python_type(); } #if PY_MAJOR_VERSION >= 3 -PyObject *Dtool_PyModuleInitHelper(LibraryDef *defs[], PyModuleDef *module_def) { +PyObject *Dtool_PyModuleInitHelper(const LibraryDef *defs[], PyModuleDef *module_def) { #else -PyObject *Dtool_PyModuleInitHelper(LibraryDef *defs[], const char *modulename) { +PyObject *Dtool_PyModuleInitHelper(const LibraryDef *defs[], const char *modulename) { #endif // Check the version so we can print a helpful error if it doesn't match. string version = Py_GetVersion(); @@ -672,10 +589,40 @@ PyObject *Dtool_PyModuleInitHelper(LibraryDef *defs[], const char *modulename) { Dtool_PyModuleClassInit_DTOOL_SUPER_BASE(nullptr); } + Dtool_TypeMap *type_map = Dtool_GetGlobalTypeMap(); + // the module level function inits.... MethodDefmap functions; - for (int xx = 0; defs[xx] != nullptr; xx++) { - Dtool_Accum_MethDefs(defs[xx]->_methods, functions); + for (size_t i = 0; defs[i] != nullptr; i++) { + const LibraryDef &def = *defs[i]; + Dtool_Accum_MethDefs(def._methods, functions); + + // Define exported types. + const Dtool_TypeDef *types = def._types; + if (types != nullptr) { + while (types->name != nullptr) { + (*type_map)[std::string(types->name)] = types->type; + ++types; + } + } + } + + // Resolve external types, in a second pass. + for (size_t i = 0; defs[i] != nullptr; i++) { + const LibraryDef &def = *defs[i]; + + Dtool_TypeDef *types = def._external_types; + if (types != nullptr) { + while (types->name != nullptr) { + auto it = type_map->find(std::string(types->name)); + if (it != type_map->end()) { + types->type = it->second; + } else { + return PyErr_Format(PyExc_NameError, "name '%s' is not defined", types->name); + } + ++types; + } + } } PyMethodDef *newdef = new PyMethodDef[functions.size() + 1]; diff --git a/dtool/src/interrogatedb/py_panda.h b/dtool/src/interrogatedb/py_panda.h index 7916147e4d..f850f0c859 100644 --- a/dtool/src/interrogatedb/py_panda.h +++ b/dtool/src/interrogatedb/py_panda.h @@ -190,11 +190,9 @@ static void Dtool_FreeInstance_##CLASS_NAME(PyObject *self) {\ // forward declared of typed object. We rely on the fact that typed objects // are uniquly defined by an integer. -EXPCL_INTERROGATEDB void RegisterNamedClass(const std::string &name, Dtool_PyTypedObject &otype); -EXPCL_INTERROGATEDB void RegisterRuntimeTypedClass(Dtool_PyTypedObject &otype); +typedef std::map Dtool_TypeMap; -EXPCL_INTERROGATEDB Dtool_PyTypedObject *LookupNamedClass(const std::string &name); -EXPCL_INTERROGATEDB Dtool_PyTypedObject *LookupRuntimeTypedClass(TypeHandle handle); +EXPCL_INTERROGATEDB Dtool_TypeMap *Dtool_GetGlobalTypeMap(); EXPCL_INTERROGATEDB Dtool_PyTypedObject *Dtool_RuntimeTypeDtoolType(int type); @@ -326,14 +324,22 @@ EXPCL_INTERROGATEDB void Dtool_Accum_MethDefs(PyMethodDef in[], MethodDefmap &th // We need a way to runtime merge compile units into a python "Module" .. this // is done with the fallowing structors and code.. along with the support of // interigate_module + +struct Dtool_TypeDef { + const char *const name; + Dtool_PyTypedObject *type; +}; + struct LibraryDef { - PyMethodDef *_methods; + PyMethodDef *const _methods; + const Dtool_TypeDef *const _types; + Dtool_TypeDef *const _external_types; }; #if PY_MAJOR_VERSION >= 3 -EXPCL_INTERROGATEDB PyObject *Dtool_PyModuleInitHelper(LibraryDef *defs[], PyModuleDef *module_def); +EXPCL_INTERROGATEDB PyObject *Dtool_PyModuleInitHelper(const LibraryDef *defs[], PyModuleDef *module_def); #else -EXPCL_INTERROGATEDB PyObject *Dtool_PyModuleInitHelper(LibraryDef *defs[], const char *modulename); +EXPCL_INTERROGATEDB PyObject *Dtool_PyModuleInitHelper(const LibraryDef *defs[], const char *modulename); #endif // HACK.... Be carefull Dtool_BorrowThisReference This function can be used to