From da0ec37aa9c6fd80becc9d8ffa8fd064445d8023 Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Tue, 20 Nov 2018 21:47:48 -0300 Subject: [PATCH] Reworked how non-imported resources are reloaded on change, fixes #19852 --- editor/editor_file_system.cpp | 33 +++++++++++++++- editor/editor_file_system.h | 3 +- editor/editor_node.cpp | 72 ++++++++++++++++++----------------- editor/editor_node.h | 2 + 4 files changed, 72 insertions(+), 38 deletions(-) diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp index a99c9656ba7..94eb1a33992 100644 --- a/editor/editor_file_system.cpp +++ b/editor/editor_file_system.cpp @@ -466,6 +466,7 @@ bool EditorFileSystem::_update_scan_actions() { bool fs_changed = false; Vector reimports; + Vector reloads; for (List::Element *E = scan_actions.front(); E; E = E->next()) { @@ -545,12 +546,25 @@ bool EditorFileSystem::_update_scan_actions() { fs_changed = true; } break; + case ItemAction::ACTION_FILE_RELOAD: { + + int idx = ia.dir->find_file_index(ia.file); + ERR_CONTINUE(idx == -1); + String full_path = ia.dir->get_file_path(idx); + + reloads.push_back(full_path); + + } break; } } if (reimports.size()) { reimport_files(reimports); } + + if (reloads.size()) { + emit_signal("resources_reload", reloads); + } scan_actions.clear(); return fs_changed; @@ -905,11 +919,11 @@ void EditorFileSystem::_scan_fs_changes(EditorFileSystemDirectory *p_dir, const continue; } + String path = cd.plus_file(p_dir->files[i]->file); + if (import_extensions.has(p_dir->files[i]->file.get_extension().to_lower())) { //check here if file must be imported or not - String path = cd.plus_file(p_dir->files[i]->file); - uint64_t mt = FileAccess::get_modified_time(path); bool reimport = false; @@ -936,6 +950,20 @@ void EditorFileSystem::_scan_fs_changes(EditorFileSystemDirectory *p_dir, const ia.file = p_dir->files[i]->file; scan_actions.push_back(ia); } + } else if (ResourceCache::has(path)) { //test for potential reload + + uint64_t mt = FileAccess::get_modified_time(path); + + if (mt != p_dir->files[i]->modified_time) { + + p_dir->files[i]->modified_time = mt; //save new time, but test for reload + + ItemAction ia; + ia.action = ItemAction::ACTION_FILE_RELOAD; + ia.dir = p_dir; + ia.file = p_dir->files[i]->file; + scan_actions.push_back(ia); + } } } @@ -1726,6 +1754,7 @@ void EditorFileSystem::_bind_methods() { ADD_SIGNAL(MethodInfo("filesystem_changed")); ADD_SIGNAL(MethodInfo("sources_changed", PropertyInfo(Variant::BOOL, "exist"))); ADD_SIGNAL(MethodInfo("resources_reimported", PropertyInfo(Variant::POOL_STRING_ARRAY, "resources"))); + ADD_SIGNAL(MethodInfo("resources_reload", PropertyInfo(Variant::POOL_STRING_ARRAY, "resources"))); } void EditorFileSystem::_update_extensions() { diff --git a/editor/editor_file_system.h b/editor/editor_file_system.h index f6eef2a1527..51b3fd38f07 100644 --- a/editor/editor_file_system.h +++ b/editor/editor_file_system.h @@ -116,7 +116,8 @@ class EditorFileSystem : public Node { ACTION_DIR_REMOVE, ACTION_FILE_ADD, ACTION_FILE_REMOVE, - ACTION_FILE_TEST_REIMPORT + ACTION_FILE_TEST_REIMPORT, + ACTION_FILE_RELOAD }; Action action; diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index b8d5ba5acb5..1b77b04a059 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -410,6 +410,40 @@ void EditorNode::_on_plugin_ready(Object *p_script, const String &p_activate_nam push_item(script.operator->()); } +void EditorNode::_resources_changed(const PoolVector &p_resources) { + + List > changed; + + int rc = p_resources.size(); + for (int i = 0; i < rc; i++) { + + Ref res(ResourceCache::get(p_resources.get(i))); + if (res.is_null()) { + continue; + } + + if (!res->editor_can_reload_from_file()) + continue; + if (!res->get_path().is_resource_file() && !res->get_path().is_abs_path()) + continue; + if (!FileAccess::exists(res->get_path())) + continue; + + if (res->get_import_path() != String()) { + //this is an imported resource, will be reloaded if reimported via the _resources_reimported() callback + continue; + } + + changed.push_back(res); + } + + if (changed.size()) { + for (List >::Element *E = changed.front(); E; E = E->next()) { + E->get()->reload_from_file(); + } + } +} + void EditorNode::_fs_changed() { for (Set::Element *E = file_dialogs.front(); E; E = E->next()) { @@ -422,41 +456,6 @@ void EditorNode::_fs_changed() { E->get()->invalidate(); } - { - //reload changed resources - List > changed; - - List > cached; - ResourceCache::get_cached_resources(&cached); - // FIXME: This should be done in a thread. - for (List >::Element *E = cached.front(); E; E = E->next()) { - - if (!E->get()->editor_can_reload_from_file()) - continue; - if (!E->get()->get_path().is_resource_file() && !E->get()->get_path().is_abs_path()) - continue; - if (!FileAccess::exists(E->get()->get_path())) - continue; - - if (E->get()->get_import_path() != String()) { - //this is an imported resource, will be reloaded if reimported via the _resources_reimported() callback - continue; - } - - uint64_t mt = FileAccess::get_modified_time(E->get()->get_path()); - - if (mt != E->get()->get_last_modified_time()) { - changed.push_back(E->get()); - } - } - - if (changed.size()) { - for (List >::Element *E = changed.front(); E; E = E->next()) { - E->get()->reload_from_file(); - } - } - } - _mark_unsaved_scenes(); if (export_defer.preset != "" && !EditorFileSystem::get_singleton()->is_scanning()) { @@ -4650,6 +4649,8 @@ void EditorNode::_bind_methods() { ClassDB::bind_method(D_METHOD("_video_driver_selected"), &EditorNode::_video_driver_selected); + ClassDB::bind_method(D_METHOD("_resources_changed"), &EditorNode::_resources_changed); + ADD_SIGNAL(MethodInfo("play_pressed")); ADD_SIGNAL(MethodInfo("pause_pressed")); ADD_SIGNAL(MethodInfo("stop_pressed")); @@ -5819,6 +5820,7 @@ EditorNode::EditorNode() { EditorFileSystem::get_singleton()->connect("sources_changed", this, "_sources_changed"); EditorFileSystem::get_singleton()->connect("filesystem_changed", this, "_fs_changed"); EditorFileSystem::get_singleton()->connect("resources_reimported", this, "_resources_reimported"); + EditorFileSystem::get_singleton()->connect("resources_reload", this, "_resources_changed"); _build_icon_type_cache(); diff --git a/editor/editor_node.h b/editor/editor_node.h index be6bacd0d1e..eda7ebcf53f 100644 --- a/editor/editor_node.h +++ b/editor/editor_node.h @@ -606,6 +606,8 @@ private: static void _resource_saved(RES p_resource, const String &p_path); static void _resource_loaded(RES p_resource, const String &p_path); + void _resources_changed(const PoolVector &p_resources); + protected: void _notification(int p_what); static void _bind_methods();