summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/extension/gdextension.cpp41
-rw-r--r--core/extension/gdextension.h7
-rw-r--r--main/main.cpp7
3 files changed, 54 insertions, 1 deletions
diff --git a/core/extension/gdextension.cpp b/core/extension/gdextension.cpp
index 9a735f5aa6..1e4cd81034 100644
--- a/core/extension/gdextension.cpp
+++ b/core/extension/gdextension.cpp
@@ -485,6 +485,13 @@ void GDExtension::close_library() {
ERR_FAIL_COND(library == nullptr);
OS::get_singleton()->close_dynamic_library(library);
+#if defined(TOOLS_ENABLED) && defined(WINDOWS_ENABLED)
+ // Delete temporary copy of library if it exists.
+ if (!temp_lib_path.is_empty() && Engine::get_singleton()->is_editor_hint()) {
+ DirAccess::remove_absolute(temp_lib_path);
+ }
+#endif
+
library = nullptr;
}
@@ -641,6 +648,40 @@ Ref<Resource> GDExtensionResourceLoader::load(const String &p_path, const String
Ref<GDExtension> lib;
lib.instantiate();
String abs_path = ProjectSettings::get_singleton()->globalize_path(library_path);
+
+#if defined(WINDOWS_ENABLED) && defined(TOOLS_ENABLED)
+ // If running on the editor on Windows, we copy the library and open the copy.
+ // This is so the original file isn't locked and can be updated by a compiler.
+ if (Engine::get_singleton()->is_editor_hint()) {
+ if (!FileAccess::exists(abs_path)) {
+ if (r_error) {
+ *r_error = ERR_FILE_NOT_FOUND;
+ }
+ ERR_PRINT("GDExtension library not found: " + library_path);
+ return Ref<Resource>();
+ }
+
+ // Copy the file to the same directory as the original with a prefix in the name.
+ // This is so relative path to dependencies are satisfied.
+ String copy_path = abs_path.get_base_dir().path_join("~" + abs_path.get_file());
+
+ Error copy_err = DirAccess::copy_absolute(abs_path, copy_path);
+ if (copy_err) {
+ if (r_error) {
+ *r_error = ERR_CANT_CREATE;
+ }
+ ERR_PRINT("Error copying GDExtension library: " + library_path);
+ return Ref<Resource>();
+ }
+ FileAccess::set_hidden_attribute(copy_path, true);
+
+ // Save the copied path so it can be deleted later.
+ lib->set_temp_library_path(copy_path);
+
+ // Use the copy to open the library.
+ abs_path = copy_path;
+ }
+#endif
err = lib->open_library(abs_path, entry_symbol);
if (r_error) {
diff --git a/core/extension/gdextension.h b/core/extension/gdextension.h
index b935f8706f..5a4dd3d5f5 100644
--- a/core/extension/gdextension.h
+++ b/core/extension/gdextension.h
@@ -43,6 +43,9 @@ class GDExtension : public Resource {
void *library = nullptr; // pointer if valid,
String library_path;
+#if defined(WINDOWS_ENABLED) && defined(TOOLS_ENABLED)
+ String temp_lib_path;
+#endif
struct Extension {
ObjectGDExtension gdextension;
@@ -76,6 +79,10 @@ public:
Error open_library(const String &p_path, const String &p_entry_symbol);
void close_library();
+#if defined(WINDOWS_ENABLED) && defined(TOOLS_ENABLED)
+ void set_temp_library_path(const String &p_path) { temp_lib_path = p_path; }
+#endif
+
enum InitializationLevel {
INITIALIZATION_LEVEL_CORE = GDEXTENSION_INITIALIZATION_CORE,
INITIALIZATION_LEVEL_SERVERS = GDEXTENSION_INITIALIZATION_SERVERS,
diff --git a/main/main.cpp b/main/main.cpp
index f79a71474d..e6dd576b8a 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -1543,6 +1543,12 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
}
}
+#ifdef TOOLS_ENABLED
+ if (editor) {
+ Engine::get_singleton()->set_editor_hint(true);
+ }
+#endif
+
// Initialize user data dir.
OS::get_singleton()->ensure_user_data_dir();
@@ -1570,7 +1576,6 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
#ifdef TOOLS_ENABLED
if (editor) {
packed_data->set_disabled(true);
- Engine::get_singleton()->set_editor_hint(true);
main_args.push_back("--editor");
if (!init_windowed) {
init_maximized = true;