|
|
@@ -17,6 +17,8 @@
|
|
|
|
|
|
#include "pythonLoaderFileType.h"
|
|
|
|
|
|
+extern struct Dtool_PyTypedObject Dtool_LoaderFileType;
|
|
|
+
|
|
|
/**
|
|
|
* Registers a loader file type that is implemented in Python.
|
|
|
*/
|
|
|
@@ -64,4 +66,50 @@ register_deferred_type(PyObject *entry_point) {
|
|
|
_this->register_type(loader);
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * If the given loader type is registered, unregisters it.
|
|
|
+ */
|
|
|
+void Extension<LoaderFileTypeRegistry>::
|
|
|
+unregister_type(PyObject *type) {
|
|
|
+ // Are we passing in a C++ file type object?
|
|
|
+ LoaderFileType *extracted_type;
|
|
|
+ if (DtoolInstance_GetPointer(type, extracted_type, Dtool_LoaderFileType)) {
|
|
|
+ _this->unregister_type(extracted_type);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // If not, we may be passing in a Python file type.
|
|
|
+ PyObject *load_func = PyObject_GetAttrString(type, "load_file");
|
|
|
+ PyObject *save_func = PyObject_GetAttrString(type, "save_file");
|
|
|
+ PyErr_Clear();
|
|
|
+
|
|
|
+ if (load_func == nullptr && save_func == nullptr) {
|
|
|
+ Dtool_Raise_TypeError("expected loader type");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Keep looping until we've removed all instances of it.
|
|
|
+ bool found_any;
|
|
|
+ do {
|
|
|
+ found_any = false;
|
|
|
+ size_t num_types = _this->get_num_types();
|
|
|
+ for (size_t i = 0; i < num_types; ++i) {
|
|
|
+ LoaderFileType *type = _this->get_type(i);
|
|
|
+ if (type->is_of_type(PythonLoaderFileType::get_class_type())) {
|
|
|
+ PythonLoaderFileType *python_type = (PythonLoaderFileType *)type;
|
|
|
+ if (python_type->_load_func == load_func &&
|
|
|
+ python_type->_save_func == save_func) {
|
|
|
+ _this->unregister_type(python_type);
|
|
|
+ delete python_type;
|
|
|
+ found_any = true;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } while (found_any);
|
|
|
+
|
|
|
+ Py_XDECREF(load_func);
|
|
|
+ Py_XDECREF(save_func);
|
|
|
+}
|
|
|
+
|
|
|
#endif
|