From 95f8c781e1b837f9319cbb5f56a5d8974767b4b9 Mon Sep 17 00:00:00 2001 From: reduz Date: Wed, 22 Jun 2022 19:03:43 +0200 Subject: [PATCH] Simplify Subresource Saving Redo edited subresource (and resource) saving in a much more simplified way. I think this should work (unless I am missing something) and be faster than what is there. It should also supersede #55885. I am not 100% entirely convinced that this approach works, but I think it should so please test. (cherry picked from commit 9eb5f2a0d79fb761235e77d369ee2f38fceb094a) --- editor/editor_node.cpp | 65 ++++++++++++++++-------------------------- 1 file changed, 25 insertions(+), 40 deletions(-) diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 40b45e8f9..65b2741b1 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -1435,34 +1435,6 @@ bool EditorNode::_validate_scene_recursive(const String &p_filename, Node *p_nod return false; } -static bool _find_edited_resources(const Ref &p_resource, Set> &edited_resources) { - if (p_resource->is_edited()) { - edited_resources.insert(p_resource); - return true; - } - - List plist; - - p_resource->get_property_list(&plist); - - for (List::Element *E = plist.front(); E; E = E->next()) { - if (E->get().type == Variant::OBJECT && E->get().usage & PROPERTY_USAGE_STORAGE && !(E->get().usage & PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT)) { - RES res = p_resource->get(E->get().name); - if (res.is_null()) { - continue; - } - if (res->get_path().is_resource_file()) { //not a subresource, continue - continue; - } - if (_find_edited_resources(res, edited_resources)) { - return true; - } - } - } - - return false; -} - int EditorNode::_save_external_resources() { //save external resources and its subresources if any was modified @@ -1472,28 +1444,41 @@ int EditorNode::_save_external_resources() { } flg |= ResourceSaver::FLAG_REPLACE_SUBRESOURCE_PATHS; - Set> edited_subresources; + Set edited_resources; int saved = 0; List> cached; ResourceCache::get_cached_resources(&cached); for (List>::Element *E = cached.front(); E; E = E->next()) { Ref res = E->get(); - if (!res->get_path().is_resource_file()) { + if (!res->is_edited()) { continue; } - //not only check if this resourec is edited, check contained subresources too - if (_find_edited_resources(res, edited_subresources)) { - ResourceSaver::save(res->get_path(), res, flg); - saved++; + + String path = res->get_path(); + if (path.begins_with("res://")) { + int subres_pos = path.find("::"); + if (subres_pos == -1) { + // Actual resource. + edited_resources.insert(path); + } else { + edited_resources.insert(path.substr(0, subres_pos)); + } } + + res->set_edited(false); } - // clear later, because user may have put the same subresource in two different resources, - // which will be shared until the next reload - - for (Set>::Element *E = edited_subresources.front(); E; E = E->next()) { - Ref res = E->get(); - res->set_edited(false); + for (Set::Element *E = edited_resources.front(); E; E = E->next()) { + Ref res = Ref(ResourceCache::get(E->get())); + if (!res.is_valid()) { + continue; // Maybe it was erased in a thread, who knows. + } + Ref ps = res; + if (ps.is_valid()) { + continue; // Do not save PackedScenes, this will mess up the editor. + } + ResourceSaver::save(res->get_path(), res, flg); + saved++; } return saved;