summaryrefslogtreecommitdiffstats
path: root/editor/filesystem_dock.cpp
diff options
context:
space:
mode:
authorMarius Hanl <mariushanl@web.de>2024-04-04 00:14:49 +0200
committerMarius Hanl <mariushanl@web.de>2024-04-05 18:52:15 +0200
commitdda06a82099b056058379d2423e0d5b16375b52d (patch)
tree826476bb855fdab40a4300afe2ffdf6162d4f72d /editor/filesystem_dock.cpp
parent29b3d9e9e538f0aa8effc8ad8bf19a2915292a89 (diff)
downloadredot-engine-dda06a82099b056058379d2423e0d5b16375b52d.tar.gz
Fix errors when renaming/moving/deleting global scripts
When renaming or moving global scripts, the following errors can appear: - Attempt to open script 'xxx' resulted in error 'File not found'. - Failed loading resource: xxx. Make sure resources have been imported by opening the project in the editor at least once. - Parser Error: Class 'xxx' hides a global script class. When deleting scripts, errors appear when opening the 'Create Node Dialog' as the script cache still contains the removed global scripts. The following errors can appear: - Attempt to open script 'xxx' resulted in error 'File not found'. - Failed loading resource: xxx. Make sure resources have been imported by opening the project in the editor at least once. editor/create_dialog.cpp:241 - Condition "scr.is_null()" is true. All this errors can be fixed by correctly handling the cases. They involves removing the old path and adding the new one (if not deleted) to the ScriptServer. This is somewhat similar if the file is moved or deleted outside Godot and detected by the file watcher, but more specialized for this particular usecase, since we know the old and the new path / correctly know what the user just did.
Diffstat (limited to 'editor/filesystem_dock.cpp')
-rw-r--r--editor/filesystem_dock.cpp54
1 files changed, 48 insertions, 6 deletions
diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp
index 4521f4d3ff..bb92cfb0b4 100644
--- a/editor/filesystem_dock.cpp
+++ b/editor/filesystem_dock.cpp
@@ -1561,10 +1561,42 @@ void FileSystemDock::_try_duplicate_item(const FileOrFolder &p_item, const Strin
}
void FileSystemDock::_update_resource_paths_after_move(const HashMap<String, String> &p_renames, const HashMap<String, ResourceUID::ID> &p_uids) const {
- // Update the paths in ResourceUID, so that UIDs remain valid.
- for (const KeyValue<String, ResourceUID::ID> &pair : p_uids) {
- if (p_renames.has(pair.key)) {
- ResourceUID::get_singleton()->set_id(pair.value, p_renames[pair.key]);
+ for (const KeyValue<String, String> &pair : p_renames) {
+ // Update UID path.
+ const String &old_path = pair.key;
+ const String &new_path = pair.value;
+
+ const HashMap<String, ResourceUID::ID>::ConstIterator I = p_uids.find(old_path);
+ if (I) {
+ ResourceUID::get_singleton()->set_id(I->value, new_path);
+ }
+
+ ScriptServer::remove_global_class_by_path(old_path);
+
+ int index = -1;
+ EditorFileSystemDirectory *efd = EditorFileSystem::get_singleton()->find_file(old_path, &index);
+
+ if (!efd || index < 0) {
+ // The file was removed.
+ continue;
+ }
+
+ // Update paths for global classes.
+ if (!efd->get_file_script_class_name(index).is_empty()) {
+ String lang;
+ for (int i = 0; i < ScriptServer::get_language_count(); i++) {
+ if (ScriptServer::get_language(i)->handles_global_class_type(efd->get_file_type(index))) {
+ lang = ScriptServer::get_language(i)->get_name();
+ break;
+ }
+ }
+ if (lang.is_empty()) {
+ continue; // No language found that can handle this global class.
+ }
+
+ ScriptServer::add_global_class(efd->get_file_script_class_name(index), efd->get_file_script_class_extends(index), lang, new_path);
+ EditorNode::get_editor_data().script_class_set_icon_path(efd->get_file_script_class_name(index), efd->get_file_script_class_icon_path(index));
+ EditorNode::get_editor_data().script_class_set_name(new_path, efd->get_file_script_class_name(index));
}
}
@@ -1583,10 +1615,13 @@ void FileSystemDock::_update_resource_paths_after_move(const HashMap<String, Str
if (p_renames.has(base_path)) {
base_path = p_renames[base_path];
+ r->set_path(base_path + extra_path);
}
-
- r->set_path(base_path + extra_path);
}
+
+ ScriptServer::save_global_classes();
+ EditorNode::get_editor_data().script_class_save_icon_paths();
+ EditorFileSystem::get_singleton()->emit_signal(SNAME("script_classes_updated"));
}
void FileSystemDock::_update_dependencies_after_move(const HashMap<String, String> &p_renames, const HashSet<String> &p_file_owners) const {
@@ -1710,6 +1745,13 @@ void FileSystemDock::_make_scene_confirm() {
}
void FileSystemDock::_resource_removed(const Ref<Resource> &p_resource) {
+ const Ref<Script> &scr = p_resource;
+ if (scr.is_valid()) {
+ ScriptServer::remove_global_class_by_path(scr->get_path());
+ ScriptServer::save_global_classes();
+ EditorNode::get_editor_data().script_class_save_icon_paths();
+ EditorFileSystem::get_singleton()->emit_signal(SNAME("script_classes_updated"));
+ }
emit_signal(SNAME("resource_removed"), p_resource);
}