Skip to content

Commit

Permalink
Implement manual class deinitialization.
Browse files Browse the repository at this point in the history
  • Loading branch information
korompg committed Sep 30, 2024
1 parent 96565e1 commit c48b485
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 3 deletions.
20 changes: 17 additions & 3 deletions binding_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -708,7 +708,7 @@ def generate_builtin_class_header(builtin_api, size, used_classes, fully_used_cl
result.append("\tfriend class StringName;")

result.append("")
result.append("\tstatic struct _MethodBindings {")
result.append("\tstatic inline struct _MethodBindings {")

result.append("\t\tGDExtensionTypeFromVariantConstructorFunc from_variant_constructor;")

Expand Down Expand Up @@ -808,6 +808,9 @@ def generate_builtin_class_header(builtin_api, size, used_classes, fully_used_cl
else:
result.append(f'\tstatic const {correct_type(constant["type"])} {constant["name"]};')

if builtin_api["has_destructor"]:
result.append("\tstatic void deinitialize();")

if builtin_api["has_destructor"]:
result.append(f"\t~{class_name}();")

Expand Down Expand Up @@ -1091,13 +1094,14 @@ def generate_builtin_class_source(builtin_api, size, used_classes, fully_used_cl
result.append("")

result.append("#include <godot_cpp/core/builtin_ptrcall.hpp>")
if builtin_api["has_destructor"]:
result.append("#include <godot_cpp/core/class_db.hpp>")
result.append("")
result.append("#include <utility>")
result.append("")
result.append("namespace godot {")
result.append("")

result.append(f"{class_name}::_MethodBindings {class_name}::_method_bindings;")
result.append("")

result.append(f"void {class_name}::_init_bindings_constructors_destructor() {{")
Expand All @@ -1117,6 +1121,9 @@ def generate_builtin_class_source(builtin_api, size, used_classes, fully_used_cl
f"\t_method_bindings.destructor = internal::gdextension_interface_variant_get_ptr_destructor({enum_type_name});"
)

if builtin_api["has_destructor"]:
result.append("\tClassDB::register_class_deinitialization_function(deinitialize);")

result.append("}")

result.append(f"void {class_name}::init_bindings() {{")
Expand Down Expand Up @@ -1237,9 +1244,16 @@ def generate_builtin_class_source(builtin_api, size, used_classes, fully_used_cl
result.append("}")
result.append("")

if builtin_api["has_destructor"]:
result.append(f"void {class_name}::deinitialize() {{")
result.append("\tmemset(&_method_bindings, 0, sizeof(_MethodBindings));")
result.append("}")
result.append("")

if builtin_api["has_destructor"]:
result.append(f"{class_name}::~{class_name}() {{")
result.append("\t_method_bindings.destructor(&opaque);")
result.append("\tif (_method_bindings.destructor)")
result.append("\t\t_method_bindings.destructor(&opaque);")
result.append("}")
result.append("")

Expand Down
6 changes: 6 additions & 0 deletions include/godot_cpp/core/class_db.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
// Needs to come after method_bind and object have been included.
#include <godot_cpp/variant/callable_method_pointer.hpp>

#include <functional>
#include <list>
#include <mutex>
#include <set>
Expand Down Expand Up @@ -107,6 +108,7 @@ class ClassDB {
static std::vector<StringName> class_register_order;
static std::unordered_map<StringName, Object *> engine_singletons;
static std::mutex engine_singletons_mutex;
static std::vector<std::function<void(void)>> class_deinitialization_functions;

static MethodBind *bind_methodfi(uint32_t p_flags, MethodBind *p_bind, const MethodDefinition &method_name, const void **p_defs, int p_defcount);
static void initialize_class(const ClassInfo &cl);
Expand Down Expand Up @@ -166,6 +168,10 @@ class ClassDB {
engine_singletons[p_class_name] = p_singleton;
}

static void register_class_deinitialization_function(std::function<void(void)> p_deinit_function) {
class_deinitialization_functions.push_back(p_deinit_function);
}

static void _unregister_engine_singleton(const StringName &p_class_name) {
std::lock_guard<std::mutex> lock(engine_singletons_mutex);
engine_singletons.erase(p_class_name);
Expand Down
4 changes: 4 additions & 0 deletions src/core/class_db.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ std::vector<StringName> ClassDB::class_register_order;
std::unordered_map<StringName, Object *> ClassDB::engine_singletons;
std::mutex ClassDB::engine_singletons_mutex;
GDExtensionInitializationLevel ClassDB::current_level = GDEXTENSION_INITIALIZATION_CORE;
std::vector<std::function<void(void)>> ClassDB::class_deinitialization_functions;

MethodDefinition D_METHOD(StringName p_name) {
return MethodDefinition(p_name);
Expand Down Expand Up @@ -436,6 +437,9 @@ void ClassDB::deinitialize(GDExtensionInitializationLevel p_level) {
for (std::vector<Object *>::iterator i = singleton_objects.begin(); i != singleton_objects.end(); i++) {
internal::gdextension_interface_object_free_instance_binding((*i)->_owner, internal::token);
}
for (std::vector<std::function<void(void)>>::reverse_iterator i = class_deinitialization_functions.rbegin(); i != class_deinitialization_functions.rend(); i++) {
(*i)();
}
}
}

Expand Down

0 comments on commit c48b485

Please sign in to comment.