From 16a86b96049a6ad1965c791be1ae59100b4a1cb2 Mon Sep 17 00:00:00 2001 From: David Snopek Date: Fri, 13 Oct 2023 12:54:21 -0500 Subject: [PATCH] GDExtension: Prevent issues with the editor trying to reload GDExtensions through its usual mechanism --- core/extension/gdextension.cpp | 18 +++++++++++++----- core/extension/gdextension.h | 2 ++ 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/core/extension/gdextension.cpp b/core/extension/gdextension.cpp index 181bf1978f9..8fb1aab6dcf 100644 --- a/core/extension/gdextension.cpp +++ b/core/extension/gdextension.cpp @@ -35,6 +35,7 @@ #include "core/object/method_bind.h" #include "core/os/os.h" #include "core/version.h" +#include "gdextension_manager.h" extern void gdextension_setup_interface(); extern GDExtensionInterfaceFunctionPtr gdextension_get_proc_address(const char *p_name); @@ -949,11 +950,18 @@ Error GDExtensionResourceLoader::load_gdextension_resource(const String &p_path, } Ref GDExtensionResourceLoader::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { - Ref lib; - Error err = load_gdextension_resource(p_path, lib); - if (err != OK && r_error) { - // Errors already logged in load_gdextension_resource(). - *r_error = err; + // We can't have two GDExtension resource object representing the same library, because + // loading (or unloading) a GDExtension affects global data. So, we need reuse the same + // object if one has already been loaded (even if caching is disabled at the resource + // loader level). + GDExtensionManager *manager = GDExtensionManager::get_singleton(); + Ref lib = manager->get_extension(p_path); + if (lib.is_null()) { + Error err = load_gdextension_resource(p_path, lib); + if (err != OK && r_error) { + // Errors already logged in load_gdextension_resource(). + *r_error = err; + } } return lib; } diff --git a/core/extension/gdextension.h b/core/extension/gdextension.h index 2996100c9a8..d71b1f97044 100644 --- a/core/extension/gdextension.h +++ b/core/extension/gdextension.h @@ -112,6 +112,8 @@ protected: public: HashMap class_icon_paths; + virtual bool editor_can_reload_from_file() override { return false; } // Reloading is handled in a special way. + static String get_extension_list_config_file(); static String find_extension_library(const String &p_path, Ref p_config, std::function p_has_feature, PackedStringArray *r_tags = nullptr);