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.

(cherry picked from commit 9eb5f2a)
  • Loading branch information
reduz authored and Riordan-DC committed Jan 23, 2023
1 parent 1e31703 commit d39abc3
Showing 1 changed file with 25 additions and 40 deletions.
65 changes: 25 additions & 40 deletions editor/editor_node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1439,34 +1439,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, 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() {
//save external resources and its subresources if any was modified

Expand All @@ -1476,30 +1448,43 @@ int EditorNode::_save_external_resources() {
}
flg |= ResourceSaver::FLAG_REPLACE_SUBRESOURCE_PATHS;

Set<Ref<Resource>> edited_subresources;
Set<String> edited_resources;
int saved = 0;
List<Ref<Resource>> cached;
ResourceCache::get_cached_resources(&cached);
for (List<Ref<Resource>>::Element *E = cached.front(); E; E = E->next()) {
Ref<Resource> 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++;
}
}

// 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 (Set<Ref<Resource>>::Element *E = edited_subresources.front(); E; E = E->next()) {
Ref<Resource> res = E->get();
res->set_edited(false);
}

for (Set<String>::Element *E = edited_resources.front(); E; E = E->next()) {
Ref<Resource> res = Ref<Resource>(ResourceCache::get(E->get()));
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 d39abc3

Please sign in to comment.