GDExtension: Always run shutdown callback before deinitializing any levels

This commit is contained in:
David Snopek
2025-06-16 08:20:48 -05:00
parent 6f2ab528ca
commit 3b7e34556c
2 changed files with 11 additions and 7 deletions

View File

@@ -815,8 +815,12 @@ typedef void (*GDExtensionMainLoopShutdownCallback)();
typedef void (*GDExtensionMainLoopFrameCallback)(); typedef void (*GDExtensionMainLoopFrameCallback)();
typedef struct { typedef struct {
// Will be called after Godot is started and is fully initialized.
GDExtensionMainLoopStartupCallback startup_func; GDExtensionMainLoopStartupCallback startup_func;
// Will be called before Godot is shutdown when it is still fully initialized.
GDExtensionMainLoopShutdownCallback shutdown_func; GDExtensionMainLoopShutdownCallback shutdown_func;
// Will be called for each process frame. This will run after all `_process()` methods on Node, and before `ScriptServer::frame()`.
// This is intended to be the equivalent of `ScriptLanguage::frame()` for GDExtension language bindings that don't use the script API.
GDExtensionMainLoopFrameCallback frame_func; GDExtensionMainLoopFrameCallback frame_func;
} GDExtensionMainLoopCallbacks; } GDExtensionMainLoopCallbacks;

View File

@@ -77,13 +77,6 @@ GDExtensionManager::LoadStatus GDExtensionManager::_unload_extension_internal(co
emit_signal("extension_unloading", p_extension); emit_signal("extension_unloading", p_extension);
#endif #endif
if (level >= 0) { // Already initialized up to some level.
// Deinitialize down from current level.
for (int32_t i = level; i >= GDExtension::INITIALIZATION_LEVEL_CORE; i--) {
p_extension->deinitialize_library(GDExtension::InitializationLevel(i));
}
}
if (!shutdown_callback_called) { if (!shutdown_callback_called) {
// Extension is unloading before the shutdown callback has been called, // Extension is unloading before the shutdown callback has been called,
// which means the engine hasn't shutdown yet but we want to make sure // which means the engine hasn't shutdown yet but we want to make sure
@@ -93,6 +86,13 @@ GDExtensionManager::LoadStatus GDExtensionManager::_unload_extension_internal(co
} }
} }
if (level >= 0) { // Already initialized up to some level.
// Deinitialize down from current level.
for (int32_t i = level; i >= GDExtension::INITIALIZATION_LEVEL_CORE; i--) {
p_extension->deinitialize_library(GDExtension::InitializationLevel(i));
}
}
for (const KeyValue<String, String> &kv : p_extension->class_icon_paths) { for (const KeyValue<String, String> &kv : p_extension->class_icon_paths) {
gdextension_class_icon_paths.erase(kv.key); gdextension_class_icon_paths.erase(kv.key);
} }