summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRémi Verschelde <remi@verschelde.fr>2024-09-20 21:35:08 +0200
committerGitHub <noreply@github.com>2024-09-20 21:35:08 +0200
commit621cadcf651b93757d5dbf8969023ae62a16f1a4 (patch)
tree79efec5d0c0dbfe1c1e1c9b71f04e9c8c2186d28
parent2be730a05b7ff221b89c967981f7caee6e164ef0 (diff)
parent96382204736cbc131fbc2640ba6ba238c53017c0 (diff)
downloadredot-engine-621cadcf651b93757d5dbf8969023ae62a16f1a4.tar.gz
Merge pull request #97168 from Hilderin/fix-reloading-scripts-already-in-use
Fix reloading scripts already in use
-rw-r--r--core/object/script_language.cpp12
-rw-r--r--core/object/script_language.h5
-rw-r--r--editor/editor_file_system.cpp33
-rw-r--r--editor/editor_file_system.h1
-rw-r--r--editor/editor_node.cpp6
-rw-r--r--editor/plugins/script_editor_plugin.cpp2
6 files changed, 43 insertions, 16 deletions
diff --git a/core/object/script_language.cpp b/core/object/script_language.cpp
index d2fc7392c8..c5856a8a81 100644
--- a/core/object/script_language.cpp
+++ b/core/object/script_language.cpp
@@ -191,7 +191,17 @@ void Script::reload_from_file() {
set_source_code(rel->get_source_code());
set_last_modified_time(rel->get_last_modified_time());
- reload();
+ // Only reload the script when there are no compilation errors to prevent printing the error messages twice.
+ if (rel->is_valid()) {
+ if (Engine::get_singleton()->is_editor_hint() && is_tool()) {
+ get_language()->reload_tool_script(this, true);
+ } else {
+ // It's important to set p_keep_state to true in order to manage reloading scripts
+ // that are currently instantiated.
+ reload(true);
+ }
+ }
+
#else
Resource::reload_from_file();
#endif
diff --git a/core/object/script_language.h b/core/object/script_language.h
index d0023d70e8..3ddfbb3e7d 100644
--- a/core/object/script_language.h
+++ b/core/object/script_language.h
@@ -112,7 +112,10 @@ class Script : public Resource {
OBJ_SAVE_TYPE(Script);
protected:
- virtual bool editor_can_reload_from_file() override { return false; } // this is handled by editor better
+ // Scripts are reloaded via the Script Editor when edited in Godot,
+ // the LSP server when edited in a connected external editor, or
+ // through EditorFileSystem::_update_script_documentation when updated directly on disk.
+ virtual bool editor_can_reload_from_file() override { return false; }
void _notification(int p_what);
static void _bind_methods();
diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp
index adae6599c1..2b51071b15 100644
--- a/editor/editor_file_system.cpp
+++ b/editor/editor_file_system.cpp
@@ -1974,18 +1974,16 @@ void EditorFileSystem::_update_script_documentation() {
for (int i = 0; i < ScriptServer::get_language_count(); i++) {
ScriptLanguage *lang = ScriptServer::get_language(i);
if (lang->supports_documentation() && efd->files[index]->type == lang->get_type()) {
- // Reloading the script from disk if resource already in memory. Otherwise, the
- // ResourceLoader::load will return the last loaded version of the script (without the modifications).
- // The only have the script already loaded here is to edit the script outside the
- // editor without being connected to the LSP server.
- Ref<Resource> res = ResourceCache::get_ref(path);
- if (res.is_valid()) {
- res->reload_from_file();
- }
+ bool should_reload_script = _should_reload_script(path);
Ref<Script> scr = ResourceLoader::load(path);
if (scr.is_null()) {
continue;
}
+ if (should_reload_script) {
+ // Reloading the script from disk. Otherwise, the ResourceLoader::load will
+ // return the last loaded version of the script (without the modifications).
+ scr->reload_from_file();
+ }
Vector<DocData::ClassDoc> docs = scr->get_documentation();
for (int j = 0; j < docs.size(); j++) {
EditorHelp::get_doc_data()->add_doc(docs[j]);
@@ -2007,6 +2005,25 @@ void EditorFileSystem::_update_script_documentation() {
update_script_paths_documentation.clear();
}
+bool EditorFileSystem::_should_reload_script(const String &p_path) {
+ if (first_scan) {
+ return false;
+ }
+
+ Ref<Script> scr = ResourceCache::get_ref(p_path);
+ if (scr.is_null()) {
+ // Not a script or not already loaded.
+ return false;
+ }
+
+ // Scripts are reloaded via the script editor if they are currently opened.
+ if (ScriptEditor::get_singleton()->get_open_scripts().has(scr)) {
+ return false;
+ }
+
+ return true;
+}
+
void EditorFileSystem::_process_update_pending() {
_update_script_classes();
// Parse documentation second, as it requires the class names to be loaded
diff --git a/editor/editor_file_system.h b/editor/editor_file_system.h
index e02127cb13..e53187c1d7 100644
--- a/editor/editor_file_system.h
+++ b/editor/editor_file_system.h
@@ -295,6 +295,7 @@ class EditorFileSystem : public Node {
void _update_script_documentation();
void _process_update_pending();
void _process_removed_files(const HashSet<String> &p_processed_files);
+ bool _should_reload_script(const String &p_path);
Mutex update_scene_mutex;
HashSet<String> update_scene_paths;
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index 2b4b6a5b7e..44292b4185 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -926,11 +926,7 @@ void EditorNode::_resources_changed(const Vector<String> &p_resources) {
}
if (!res->editor_can_reload_from_file()) {
- Ref<Script> scr = res;
- // Scripts are reloaded via the script editor.
- if (scr.is_null() || ScriptEditor::get_singleton()->get_open_scripts().has(scr)) {
- continue;
- }
+ continue;
}
if (!res->get_path().is_resource_file() && !res->get_path().is_absolute_path()) {
continue;
diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp
index 9579388d46..54730ec674 100644
--- a/editor/plugins/script_editor_plugin.cpp
+++ b/editor/plugins/script_editor_plugin.cpp
@@ -1483,7 +1483,7 @@ void ScriptEditor::_menu_option(int p_option) {
current->apply_code();
- Error err = scr->reload(false); // Always hard reload the script before running.
+ Error err = scr->reload(true); // Always hard reload the script before running.
if (err != OK || !scr->is_valid()) {
EditorToaster::get_singleton()->popup_str(TTR("Cannot run the script because it contains errors, check the output log."), EditorToaster::SEVERITY_WARNING);
return;