@@ -239,6 +239,8 @@ void Node::_notification(int p_notification) {
239
239
memdelete (data.path_cache );
240
240
data.path_cache = nullptr ;
241
241
}
242
+ // reset the cached_hierarchy_path
243
+ data.cached_hierarchy_path .clear ();
242
244
} break ;
243
245
244
246
case NOTIFICATION_PAUSED: {
@@ -577,6 +579,9 @@ void Node::_move_child(Node *p_child, int p_index, bool p_ignore_end) {
577
579
data.children_cache [i]->data .index = i;
578
580
}
579
581
}
582
+
583
+ data.cached_hierarchy_path .clear ();
584
+
580
585
// notification second
581
586
move_child_notify (p_child);
582
587
notification (NOTIFICATION_CHILD_ORDER_CHANGED);
@@ -2049,6 +2054,61 @@ bool Node::is_ancestor_of(const Node *p_node) const {
2049
2054
return false ;
2050
2055
}
2051
2056
2057
+ void Node::precompute_hierarchy_path () const {
2058
+ if (data.cached_hierarchy_path .size () == data.depth ) {
2059
+ // Skip if already cached and valid
2060
+ return ;
2061
+ }
2062
+
2063
+ // Resize to avoid reallocation
2064
+ data.cached_hierarchy_path .resize (data.depth );
2065
+
2066
+ // Fill the path from the node to the root
2067
+ const Node *n = this ;
2068
+ for (int i = data.depth - 1 ; i >= 0 ; --i) {
2069
+ data.cached_hierarchy_path .write [i] = n->get_index ();
2070
+ n = n->data .parent ;
2071
+ }
2072
+ }
2073
+
2074
+ bool Node::is_greater_than_cached (const Node *p_node) const {
2075
+ // Ensure paths are precomputed
2076
+ precompute_hierarchy_path ();
2077
+ p_node->precompute_hierarchy_path ();
2078
+
2079
+ const Vector<int > &this_path = data.cached_hierarchy_path ;
2080
+ const Vector<int > &that_path = p_node->data .cached_hierarchy_path ;
2081
+
2082
+ const int this_size = this_path.size ();
2083
+ const int that_size = that_path.size ();
2084
+ const int min_size = MIN (this_size, that_size);
2085
+
2086
+ const int *this_data = this_path.ptr ();
2087
+ const int *that_data = that_path.ptr ();
2088
+
2089
+ int cmp_result = memcmp (this_data, that_data, min_size * sizeof (int ));
2090
+ if (cmp_result != 0 ) {
2091
+ // cmp_result > 0 means the first mismatching byte in this_data is bigger
2092
+ // cmp_result < 0 means the first mismatching byte in this_data is smaller
2093
+ return cmp_result > 0 ;
2094
+ }
2095
+
2096
+ return this_size > that_size;
2097
+ //
2098
+ // // Compare paths lexicographically
2099
+ // int min_size = MIN(this_path.size(), that_path.size());
2100
+ // for (int i = 0; i < min_size; ++i) {
2101
+ // if (this_path[i] != that_path[i]) {
2102
+ // return this_path[i] > that_path[i];
2103
+ // }
2104
+ // }
2105
+
2106
+ // If paths are equal up to the shortest length, the deeper node is greater
2107
+ // return this_path.size() > that_path.size();
2108
+ }
2109
+
2110
+
2111
+
2052
2112
bool Node::is_greater_than (const Node *p_node) const {
2053
2113
ERR_FAIL_NULL_V (p_node, false );
2054
2114
ERR_FAIL_COND_V (!data.inside_tree , false );
0 commit comments