You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-07 12:30:27 +00:00
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.
This commit is contained in:
@@ -1614,34 +1614,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, 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() {
|
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.
|
||||||
|
|
||||||
@@ -1651,27 +1623,41 @@ int EditorNode::_save_external_resources() {
|
|||||||
}
|
}
|
||||||
flg |= ResourceSaver::FLAG_REPLACE_SUBRESOURCE_PATHS;
|
flg |= ResourceSaver::FLAG_REPLACE_SUBRESOURCE_PATHS;
|
||||||
|
|
||||||
HashSet<Ref<Resource>> edited_subresources;
|
HashSet<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 (const Ref<Resource> &res : cached) {
|
|
||||||
if (!res->get_path().is_resource_file()) {
|
for (Ref<Resource> res : cached) {
|
||||||
|
if (!res->is_edited()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// not only check if this resource 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 (const String &E : edited_resources) {
|
||||||
// which will be shared until the next reload.
|
Ref<Resource> res = Ref<Resource>(ResourceCache::get(E));
|
||||||
|
if (!res.is_valid()) {
|
||||||
for (const Ref<Resource> &E : edited_subresources) {
|
continue; // Maybe it was erased in a thread, who knows.
|
||||||
Ref<Resource> res = E;
|
}
|
||||||
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;
|
||||||
|
|||||||
Reference in New Issue
Block a user