diff --git a/binding_generator.py b/binding_generator.py index db7525810..5c613df65 100644 --- a/binding_generator.py +++ b/binding_generator.py @@ -1192,6 +1192,8 @@ def generate_engine_class_header(class_api, used_classes, fully_used_classes, us if is_singleton: result.append(f"\tstatic {class_name} *get_singleton();") result.append("") + result.append(f"\t~{class_name}();") + result.append("") if "methods" in class_api: for method in class_api["methods"]: @@ -1314,6 +1316,8 @@ def generate_engine_class_source(class_api, used_classes, fully_used_classes, us result.append("") if is_singleton: + result.append(f"static bool {class_name}_singleton_destroyed = false;") + result.append("") result.append(f"{class_name} *{class_name}::get_singleton() {{") result.append(f"\tconst StringName __class_name = {class_name}::get_class_static();") result.append( @@ -1325,9 +1329,20 @@ def generate_engine_class_source(class_api, used_classes, fully_used_classes, us result.append( f"\tstatic {class_name} *singleton = reinterpret_cast<{class_name} *>(internal::gde_interface->object_get_instance_binding(singleton_obj, internal::token, &{class_name}::___binding_callbacks));" ) + result.append(f"\tstatic struct {class_name}_BindingCleanup {{") + result.append(f"\t\t~{class_name}_BindingCleanup() {{") + result.append(f"\t\t\tif (!{class_name}_singleton_destroyed) {{") + result.append("\t\t\t\tinternal::gde_interface->object_clear_instance_binding(singleton_obj, internal::token);") + result.append("\t\t\t}") + result.append("\t\t}") + result.append("\t} binding_cleanup;") result.append("\treturn singleton;") result.append("}") result.append("") + result.append(f"{class_name}::~{class_name}() {{") + result.append(f"\t{class_name}_singleton_destroyed = true;") + result.append("}") + result.append("") if "methods" in class_api: for method in class_api["methods"]: diff --git a/godot-headers/godot/gdextension_interface.h b/godot-headers/godot/gdextension_interface.h index b59a6b5ca..109d87fa3 100644 --- a/godot-headers/godot/gdextension_interface.h +++ b/godot-headers/godot/gdextension_interface.h @@ -544,6 +544,7 @@ typedef struct { void *(*object_get_instance_binding)(GDExtensionObjectPtr p_o, void *p_token, const GDExtensionInstanceBindingCallbacks *p_callbacks); void (*object_set_instance_binding)(GDExtensionObjectPtr p_o, void *p_token, void *p_binding, const GDExtensionInstanceBindingCallbacks *p_callbacks); + void (*object_clear_instance_binding)(GDExtensionObjectPtr p_o, void *p_token); void (*object_set_instance)(GDExtensionObjectPtr p_o, GDExtensionConstStringNamePtr p_classname, GDExtensionClassInstancePtr p_instance); /* p_classname should be a registered extension class and should extend the p_o object's class. */