mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-30 08:44:19 -04:00
Remove Python type tables from interrogatedb
This commit is contained in:
parent
da05ef1f5c
commit
e6f870ece6
@ -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
|
||||
*/
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
@ -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
|
||||
|
@ -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<TypeRegistryNode *> 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);
|
||||
|
||||
|
@ -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";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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, ";
|
||||
}
|
||||
|
@ -26,7 +26,7 @@
|
||||
template<class T> 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<class T> 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<class T> 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<class T> 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<class T> 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());
|
||||
}
|
||||
|
@ -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<NamedTypeMap::iterator, bool> 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<RuntimeTypeMap::iterator, bool> 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];
|
||||
|
@ -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<std::string, Dtool_PyTypedObject *> 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
|
||||
|
Loading…
x
Reference in New Issue
Block a user