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)
This commit is contained in:
reduz 2022-06-22 19:03:43 +02:00 committed by Relintai
parent 059d393d42
commit 95f8c781e1

View File

@ -1435,34 +1435,6 @@ bool EditorNode::_validate_scene_recursive(const String &p_filename, Node *p_nod
return false; return false;
} }
static bool _find_edited_resources(const Ref<Resource> &p_resource, Set<Ref<Resource>> &edited_resources) {
if (p_resource->is_edited()) {
edited_resources.insert(p_resource);
return true;
}
List<PropertyInfo> plist;
p_resource->get_property_list(&plist);
for (List<PropertyInfo>::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() { int EditorNode::_save_external_resources() {
//save external resources and its subresources if any was modified //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; flg |= ResourceSaver::FLAG_REPLACE_SUBRESOURCE_PATHS;
Set<Ref<Resource>> edited_subresources; Set<String> edited_resources;
int saved = 0; int saved = 0;
List<Ref<Resource>> cached; List<Ref<Resource>> cached;
ResourceCache::get_cached_resources(&cached); ResourceCache::get_cached_resources(&cached);
for (List<Ref<Resource>>::Element *E = cached.front(); E; E = E->next()) { for (List<Ref<Resource>>::Element *E = cached.front(); E; E = E->next()) {
Ref<Resource> res = E->get(); Ref<Resource> res = E->get();
if (!res->get_path().is_resource_file()) { if (!res->is_edited()) {
continue; continue;
} }
//not only check if this resourec is edited, check contained subresources too
if (_find_edited_resources(res, edited_subresources)) { String path = res->get_path();
ResourceSaver::save(res->get_path(), res, flg); if (path.begins_with("res://")) {
saved++; 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, for (Set<String>::Element *E = edited_resources.front(); E; E = E->next()) {
// which will be shared until the next reload Ref<Resource> res = Ref<Resource>(ResourceCache::get(E->get()));
if (!res.is_valid()) {
for (Set<Ref<Resource>>::Element *E = edited_subresources.front(); E; E = E->next()) { continue; // Maybe it was erased in a thread, who knows.
Ref<Resource> res = E->get(); }
res->set_edited(false); Ref<PackedScene> 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; return saved;