Explorar o código

Merge pull request #63891 from derammo/derammo_tree_cache

Rémi Verschelde %!s(int64=3) %!d(string=hai) anos
pai
achega
9744becc39
Modificáronse 2 ficheiros con 39 adicións e 2 borrados
  1. 32 2
      scene/gui/tree.cpp
  2. 7 0
      scene/gui/tree.h

+ 32 - 2
scene/gui/tree.cpp

@@ -749,6 +749,7 @@ int TreeItem::get_child_count() {
 }
 
 Array TreeItem::get_children() {
+	// Don't need to explicitly create children cache, because get_child_count creates it.
 	int size = get_child_count();
 	Array arr;
 	arr.resize(size);
@@ -770,6 +771,22 @@ int TreeItem::get_index() {
 	return idx - 1;
 }
 
+#ifdef DEV_ENABLED
+void TreeItem::validate_cache() const {
+	if (!parent || parent->children_cache.is_empty()) {
+		return;
+	}
+	TreeItem *scan = parent->first_child;
+	int index = 0;
+	while (scan) {
+		DEV_ASSERT(parent->children_cache[index] == scan);
+		++index;
+		scan = scan->get_next();
+	}
+	DEV_ASSERT(index == parent->children_cache.size());
+}
+#endif
+
 void TreeItem::move_before(TreeItem *p_item) {
 	ERR_FAIL_NULL(p_item);
 	ERR_FAIL_COND(is_root);
@@ -797,7 +814,11 @@ void TreeItem::move_before(TreeItem *p_item) {
 		parent->children_cache.clear();
 	} else {
 		parent->first_child = this;
-		parent->children_cache.insert(0, this);
+		// If the cache is empty, it has not been built but there
+		// are items in the tree (note p_item != nullptr,) so we cannot update it.
+		if (!parent->children_cache.is_empty()) {
+			parent->children_cache.insert(0, this);
+		}
 	}
 
 	prev = item_prev;
@@ -807,6 +828,8 @@ void TreeItem::move_before(TreeItem *p_item) {
 	if (tree && old_tree == tree) {
 		tree->update();
 	}
+
+	validate_cache();
 }
 
 void TreeItem::move_after(TreeItem *p_item) {
@@ -839,12 +862,17 @@ void TreeItem::move_after(TreeItem *p_item) {
 	if (next) {
 		parent->children_cache.clear();
 	} else {
-		parent->children_cache.append(this);
+		// If the cache is empty, it has not been built but there
+		// are items in the tree (note p_item != nullptr,) so we cannot update it.
+		if (!parent->children_cache.is_empty()) {
+			parent->children_cache.append(this);
+		}
 	}
 
 	if (tree && old_tree == tree) {
 		tree->update();
 	}
+	validate_cache();
 }
 
 void TreeItem::remove_child(TreeItem *p_item) {
@@ -859,6 +887,7 @@ void TreeItem::remove_child(TreeItem *p_item) {
 	if (tree) {
 		tree->update();
 	}
+	validate_cache();
 }
 
 void TreeItem::set_selectable(int p_column, bool p_selectable) {
@@ -1396,6 +1425,7 @@ TreeItem::TreeItem(Tree *p_tree) {
 
 TreeItem::~TreeItem() {
 	_unlink_from_tree();
+	validate_cache();
 	prev = nullptr;
 	clear_children();
 	_change_tree(nullptr);

+ 7 - 0
scene/gui/tree.h

@@ -342,6 +342,13 @@ public:
 	Array get_children();
 	int get_index();
 
+#ifdef DEV_ENABLED
+	// This debugging code can be removed once the current refactoring of this class is complete.
+	void validate_cache() const;
+#else
+	void validate_cache() const {}
+#endif
+
 	void move_before(TreeItem *p_item);
 	void move_after(TreeItem *p_item);