Skip to content

Commit

Permalink
Simplify Subresource Saving
Browse files Browse the repository at this point in the history
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 godotengine#55885.

I am not 100% entirely convinced that this approach works, but I think it should so please test.
  • Loading branch information
reduz committed Jun 23, 2022
1 parent 3ccff61 commit 9eb5f2a
Showing 1 changed file with 27 additions and 41 deletions.
68 changes: 27 additions & 41 deletions editor/editor_node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1614,34 +1614,6 @@ bool EditorNode::_validate_scene_recursive(const String &p_filename, Node *p_nod
return false;
}

static bool _find_edited_resources(const Ref<Resource> &p_resource, HashSet<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 (const PropertyInfo &E : plist) {
if (E.type == Variant::OBJECT && E.usage & PROPERTY_USAGE_STORAGE && !(E.usage & PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT)) {
Ref<Resource> res = p_resource->get(E.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.

Expand All @@ -1651,29 +1623,43 @@ int EditorNode::_save_external_resources() {
}
flg |= ResourceSaver::FLAG_REPLACE_SUBRESOURCE_PATHS;

HashSet<Ref<Resource>> edited_subresources;
HashSet<String> edited_resources;
int saved = 0;
List<Ref<Resource>> cached;
ResourceCache::get_cached_resources(&cached);
for (const Ref<Resource> &res : cached) {
if (!res->get_path().is_resource_file()) {

for (Ref<Resource> res : cached) {
if (!res->is_edited()) {
continue;
}
// not only check if this resource is edited, check contained subresources too
if (_find_edited_resources(res, edited_subresources)) {
ResourceSaver::save(res->get_path(), res, flg);
saved++;
}
}

// Clear later, because user may have put the same subresource in two different resources,
// which will be shared until the next reload.
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));
}
}

for (const Ref<Resource> &E : edited_subresources) {
Ref<Resource> res = E;
res->set_edited(false);
}

for (const String &E : edited_resources) {
Ref<Resource> res = Ref<Resource>(ResourceCache::get(E));
if (!res.is_valid()) {
continue; // Maybe it was erased in a thread, who knows.
}
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;
}

Expand Down

0 comments on commit 9eb5f2a

Please sign in to comment.