diff options
Diffstat (limited to 'core/extension/gdextension.cpp')
-rw-r--r-- | core/extension/gdextension.cpp | 29 |
1 files changed, 23 insertions, 6 deletions
diff --git a/core/extension/gdextension.cpp b/core/extension/gdextension.cpp index 181bf1978f..6c3d0a6148 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); @@ -663,7 +664,7 @@ void GDExtension::_get_library_path(GDExtensionClassLibraryPtr p_library, GDExte memnew_placement(r_path, String(self->library_path)); } -HashMap<StringName, GDExtensionInterfaceFunctionPtr> gdextension_interface_functions; +HashMap<StringName, GDExtensionInterfaceFunctionPtr> GDExtension::gdextension_interface_functions; void GDExtension::register_interface_function(StringName p_function_name, GDExtensionInterfaceFunctionPtr p_function_pointer) { ERR_FAIL_COND_MSG(gdextension_interface_functions.has(p_function_name), "Attempt to register interface function '" + p_function_name + "', which appears to be already registered."); @@ -835,6 +836,10 @@ void GDExtension::initialize_gdextensions() { register_interface_function("get_library_path", (GDExtensionInterfaceFunctionPtr)&GDExtension::_get_library_path); } +void GDExtension::finalize_gdextensions() { + gdextension_interface_functions.clear(); +} + Error GDExtensionResourceLoader::load_gdextension_resource(const String &p_path, Ref<GDExtension> &p_extension) { ERR_FAIL_COND_V_MSG(p_extension.is_valid() && p_extension->is_library_open(), ERR_ALREADY_IN_USE, "Cannot load GDExtension resource into already opened library."); @@ -910,9 +915,9 @@ Error GDExtensionResourceLoader::load_gdextension_resource(const String &p_path, #ifdef TOOLS_ENABLED p_extension->set_reloadable(config->get_value("configuration", "reloadable", false) && Engine::get_singleton()->is_extension_reloading_enabled()); - p_extension->update_last_modified_time(MAX( - FileAccess::get_modified_time(library_path), - FileAccess::get_modified_time(p_path))); + p_extension->update_last_modified_time( + FileAccess::get_modified_time(p_path), + FileAccess::get_modified_time(library_path)); #endif err = p_extension->open_library(library_path, entry_symbol); @@ -949,6 +954,15 @@ Error GDExtensionResourceLoader::load_gdextension_resource(const String &p_path, } Ref<Resource> 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) { + // 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(); + if (manager->is_extension_loaded(p_path)) { + return manager->get_extension(p_path); + } + Ref<GDExtension> lib; Error err = load_gdextension_resource(p_path, lib); if (err != OK && r_error) { @@ -976,10 +990,13 @@ String GDExtensionResourceLoader::get_resource_type(const String &p_path) const #ifdef TOOLS_ENABLED bool GDExtension::has_library_changed() const { - if (FileAccess::get_modified_time(get_path()) > last_modified_time) { + // Check only that the last modified time is different (rather than checking + // that it's newer) since some OS's (namely Windows) will preserve the modified + // time by default when copying files. + if (FileAccess::get_modified_time(get_path()) != resource_last_modified_time) { return true; } - if (FileAccess::get_modified_time(library_path) > last_modified_time) { + if (FileAccess::get_modified_time(library_path) != library_last_modified_time) { return true; } return false; |