Skip to content

Commit 0b30ecc

Browse files
committed
Don't mark cached previously pinned AnimationMixers
AnimationPlayerEditor will hold on to pointers to no-longer existing Nodes that were previously pinned. Make sure to not mark them as dirty if they are not already inside the cache. This fixes #102108
1 parent c2732ae commit 0b30ecc

File tree

2 files changed

+23
-3
lines changed

2 files changed

+23
-3
lines changed

editor/gui/scene_tree_editor.cpp

+22-3
Original file line numberDiff line numberDiff line change
@@ -924,12 +924,19 @@ void SceneTreeEditor::_update_tree(bool p_scroll_to_selected) {
924924
// If pinned state changed, update the currently pinned node.
925925
if (AnimationPlayerEditor::get_singleton()->is_pinned() != node_cache.current_has_pin) {
926926
node_cache.current_has_pin = AnimationPlayerEditor::get_singleton()->is_pinned();
927-
node_cache.mark_dirty(pinned_node);
927+
if (node_cache.has(pinned_node)) {
928+
node_cache.mark_dirty(pinned_node);
929+
}
928930
}
929931
// If the current pinned node changed update both the old and new node.
930932
if (node_cache.current_pinned_node != pinned_node) {
931-
node_cache.mark_dirty(pinned_node);
932-
node_cache.mark_dirty(node_cache.current_pinned_node);
933+
// get_editing_node() will return deleted nodes. If the nodes are not in cache don't try to mark them.
934+
if (node_cache.has(pinned_node)) {
935+
node_cache.mark_dirty(pinned_node);
936+
}
937+
if (node_cache.has(node_cache.current_pinned_node)) {
938+
node_cache.mark_dirty(node_cache.current_pinned_node);
939+
}
933940
node_cache.current_pinned_node = pinned_node;
934941
}
935942

@@ -2373,6 +2380,10 @@ HashMap<Node *, SceneTreeEditor::CachedNode>::Iterator SceneTreeEditor::NodeCach
23732380
return I;
23742381
}
23752382

2383+
bool SceneTreeEditor::NodeCache::has(Node *p_node) {
2384+
return get(p_node, false).operator bool();
2385+
}
2386+
23762387
void SceneTreeEditor::NodeCache::remove(Node *p_node, bool p_recursive) {
23772388
if (!p_node) {
23782389
return;
@@ -2382,6 +2393,11 @@ void SceneTreeEditor::NodeCache::remove(Node *p_node, bool p_recursive) {
23822393
editor->selected = nullptr;
23832394
}
23842395

2396+
if (p_node == current_pinned_node) {
2397+
current_pinned_node = nullptr;
2398+
current_has_pin = false;
2399+
}
2400+
23852401
editor->marked.erase(p_node);
23862402

23872403
HashMap<Node *, CachedNode>::Iterator I = cache.find(p_node);
@@ -2419,6 +2435,7 @@ void SceneTreeEditor::NodeCache::mark_dirty(Node *p_node, bool p_parents) {
24192435
if (!p_parents) {
24202436
break;
24212437
}
2438+
24222439
node = node->get_parent();
24232440
}
24242441
}
@@ -2483,4 +2500,6 @@ void SceneTreeEditor::NodeCache::clear() {
24832500
}
24842501
cache.clear();
24852502
to_delete.clear();
2503+
current_pinned_node = nullptr;
2504+
current_has_pin = false;
24862505
}

editor/gui/scene_tree_editor.h

+1
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ class SceneTreeEditor : public Control {
9090

9191
HashMap<Node *, CachedNode>::Iterator add(Node *p_node, TreeItem *p_item);
9292
HashMap<Node *, CachedNode>::Iterator get(Node *p_node, bool p_deleted_ok = true);
93+
bool has(Node *p_node);
9394
void remove(Node *p_node, bool p_recursive = false);
9495
void mark_dirty(Node *p_node, bool p_parents = true);
9596
void mark_children_dirty(Node *p_node, bool p_recursive = false);

0 commit comments

Comments
 (0)