From dc1a6dc07fbe111e034d89f10841a185e812c583 Mon Sep 17 00:00:00 2001 From: kobewi Date: Fri, 24 Apr 2026 20:25:18 +0200 Subject: [PATCH] Avoid repeats in resource gather --- editor/editor_node.cpp | 30 ++++++++++++++------- editor/editor_node.h | 2 +- editor/inspector/editor_resource_picker.cpp | 3 ++- 3 files changed, 23 insertions(+), 12 deletions(-) diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index c0eb3efd44..a4d6c866f0 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -1891,7 +1891,7 @@ bool EditorNode::is_resource_internal_to_scene(Ref p_resource) { return inside_scene || p_resource->get_path().is_empty(); } -void EditorNode::gather_resources(const Variant &p_variant, List> &r_list, bool p_subresources, bool p_allow_external) { +void EditorNode::gather_resources(const Variant &p_variant, List> &r_list, HashSet &r_scanned_objects, bool p_subresources, bool p_allow_external) { Variant::Type type = p_variant.get_type(); if (type == Variant::OBJECT && p_variant.get_validated_object() == nullptr) { return; @@ -1913,7 +1913,7 @@ void EditorNode::gather_resources(const Variant &p_variant, List> } } if (Object::cast_to(v) == nullptr) { - gather_resources(v, r_list, p_subresources, p_allow_external); + gather_resources(v, r_list, r_scanned_objects, p_subresources, p_allow_external); } } return; @@ -1939,27 +1939,35 @@ void EditorNode::gather_resources(const Variant &p_variant, List> } } if (Object::cast_to(kv.key) == nullptr) { - gather_resources(kv.key, r_list, p_subresources, p_allow_external); + gather_resources(kv.key, r_list, r_scanned_objects, p_subresources, p_allow_external); } if (Object::cast_to(kv.value) == nullptr) { - gather_resources(kv.value, r_list, p_subresources, p_allow_external); + gather_resources(kv.value, r_list, r_scanned_objects, p_subresources, p_allow_external); } } return; } + // Variant::Object + + Object *object = p_variant; + if (r_scanned_objects.has(object)) { + return; + } + r_scanned_objects.insert(object); + List pinfo; - p_variant.get_property_list(&pinfo); + object->get_property_list(&pinfo); for (const PropertyInfo &E : pinfo) { if (!(E.usage & PROPERTY_USAGE_EDITOR)) { continue; } - Variant property_value = p_variant.get(E.name); + Variant property_value = object->get(E.name); Variant::Type property_type = property_value.get_type(); if (property_type == Variant::ARRAY || property_type == Variant::DICTIONARY) { - gather_resources(property_value, r_list, p_subresources, p_allow_external); + gather_resources(property_value, r_list, r_scanned_objects, p_subresources, p_allow_external); continue; } Ref res = property_value; @@ -1975,7 +1983,7 @@ void EditorNode::gather_resources(const Variant &p_variant, List> } r_list.push_back(res); if (p_subresources) { - gather_resources(res, r_list, p_subresources, p_allow_external); + gather_resources(res, r_list, r_scanned_objects, p_subresources, p_allow_external); } } } @@ -1986,7 +1994,8 @@ void EditorNode::update_resource_count(Node *p_node, bool p_remove) { } List> res_list; - gather_resources(p_node, res_list, true); + HashSet scanned_objects; + gather_resources(p_node, res_list, scanned_objects, true); for (Ref &R : res_list) { List::Element *E = resource_count[R].find(p_node); @@ -2015,7 +2024,8 @@ List EditorNode::get_resource_node_list(Ref p_res) { void EditorNode::update_node_reference(const Variant &p_value, Node *p_node, bool p_remove) { List> list; Ref res = p_value; - gather_resources(p_value, list, true); //Gather all Resources and their SubResources to remove p_node from their lists. + HashSet scanned_objects; + gather_resources(p_value, list, scanned_objects, true); //Gather all Resources and their SubResources to remove p_node from their lists. if (res.is_valid() && is_resource_internal_to_scene(res)) { // Avoid external Resources from being added in. diff --git a/editor/editor_node.h b/editor/editor_node.h index 337c7484a5..dcd50a5499 100644 --- a/editor/editor_node.h +++ b/editor/editor_node.h @@ -826,7 +826,7 @@ public: void save_resource(const Ref &p_resource); void save_resource_as(const Ref &p_resource, const String &p_at_path = String()); bool is_resource_internal_to_scene(Ref p_resource); - void gather_resources(const Variant &p_variant, List> &r_list, bool p_subresources = false, bool p_allow_external = false); + void gather_resources(const Variant &p_variant, List> &r_list, HashSet &r_scanned_objects, bool p_subresources = false, bool p_allow_external = false); void update_resource_count(Node *p_node, bool p_remove = false); void update_node_reference(const Variant &p_value, Node *p_node, bool p_remove = false); void clear_node_reference(Ref p_res); diff --git a/editor/inspector/editor_resource_picker.cpp b/editor/inspector/editor_resource_picker.cpp index f94dee315b..93fe657407 100644 --- a/editor/inspector/editor_resource_picker.cpp +++ b/editor/inspector/editor_resource_picker.cpp @@ -1433,7 +1433,8 @@ bool EditorResourcePicker::_is_uniqueness_enabled(bool p_check_recursive) { if (p_check_recursive && parent_counter <= 1) { List> nested_resources; - en->gather_resources(edited_resource, nested_resources, true, true); + HashSet scanned_objects; + en->gather_resources(edited_resource, nested_resources, scanned_objects, true, true); for (Ref R : nested_resources) { // Take into account Nested External Resources.