Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix reloading scripts already in use #97168

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion core/object/script_language.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 4 additions & 1 deletion core/object/script_language.h
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down
33 changes: 25 additions & 8 deletions editor/editor_file_system.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1973,18 +1973,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]);
Expand All @@ -2006,6 +2004,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
Expand Down
1 change: 1 addition & 0 deletions editor/editor_file_system.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
6 changes: 1 addition & 5 deletions editor/editor_node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion editor/plugins/script_editor_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Loading