fixed Tree UI control bug corrupting child cache

This commit is contained in:
derammo 2022-08-03 18:08:16 -04:00
parent ea4b8de2b4
commit 4e6c8e00fc
2 changed files with 39 additions and 2 deletions

View File

@ -749,6 +749,7 @@ int TreeItem::get_child_count() {
} }
Array TreeItem::get_children() { Array TreeItem::get_children() {
// Don't need to explicitly create children cache, because get_child_count creates it.
int size = get_child_count(); int size = get_child_count();
Array arr; Array arr;
arr.resize(size); arr.resize(size);
@ -770,6 +771,22 @@ int TreeItem::get_index() {
return idx - 1; 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) { void TreeItem::move_before(TreeItem *p_item) {
ERR_FAIL_NULL(p_item); ERR_FAIL_NULL(p_item);
ERR_FAIL_COND(is_root); ERR_FAIL_COND(is_root);
@ -797,7 +814,11 @@ void TreeItem::move_before(TreeItem *p_item) {
parent->children_cache.clear(); parent->children_cache.clear();
} else { } else {
parent->first_child = this; 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; prev = item_prev;
@ -807,6 +828,8 @@ void TreeItem::move_before(TreeItem *p_item) {
if (tree && old_tree == tree) { if (tree && old_tree == tree) {
tree->update(); tree->update();
} }
validate_cache();
} }
void TreeItem::move_after(TreeItem *p_item) { void TreeItem::move_after(TreeItem *p_item) {
@ -839,12 +862,17 @@ void TreeItem::move_after(TreeItem *p_item) {
if (next) { if (next) {
parent->children_cache.clear(); parent->children_cache.clear();
} else { } 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) { if (tree && old_tree == tree) {
tree->update(); tree->update();
} }
validate_cache();
} }
void TreeItem::remove_child(TreeItem *p_item) { void TreeItem::remove_child(TreeItem *p_item) {
@ -859,6 +887,7 @@ void TreeItem::remove_child(TreeItem *p_item) {
if (tree) { if (tree) {
tree->update(); tree->update();
} }
validate_cache();
} }
void TreeItem::set_selectable(int p_column, bool p_selectable) { void TreeItem::set_selectable(int p_column, bool p_selectable) {
@ -1396,6 +1425,7 @@ TreeItem::TreeItem(Tree *p_tree) {
TreeItem::~TreeItem() { TreeItem::~TreeItem() {
_unlink_from_tree(); _unlink_from_tree();
validate_cache();
prev = nullptr; prev = nullptr;
clear_children(); clear_children();
_change_tree(nullptr); _change_tree(nullptr);

View File

@ -342,6 +342,13 @@ public:
Array get_children(); Array get_children();
int get_index(); 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_before(TreeItem *p_item);
void move_after(TreeItem *p_item); void move_after(TreeItem *p_item);