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
The performance improvement on the SceneTreeEditor caused the previous
state of the SceneTreeEditor::marked HashSet to matter, when it
previously was always just overwritten when markings changed. The old
code thus had no reason to ever clear the marking list.
We now make sure that whether the SceneTreeEditor is hidden or not that
when the edited scene changes we always reset the entire state of the
editor, including the marked HashSet.
When a node was previously selected and the test "selected == p_node"
was true the code would use set_selected() to change the selection to
nullptr. However, if the tree is dirty, which is always true in this
codepath, this would lead to a recursive call to _update_tree()
ultimately leading to a crash due to us running out of stack.
This fixes#100666
We now cache the Node*<>TreeItem* mapping in the SceneTreeEditor. This
allows us to make targeted updates to the Tree used to display the scene
tree in the editor.
Previously on almost all changes to the scene tree the editor would
rebuild the entire widget, causing a large number of deallocations an
allocations. We now carefully manipulate the Tree widget in-situ saving
a large number of these allocations.
In order to know what Nodes need to be updated we add a
editor_state_changed signal to Node, this is a TOOLS_ENABLED,
editor-only signal fired when changes to Node happen that are relevant
to editor state.
We also now make sure that when nodes are moved/renamed we don't check
expensive properties that cannot contain NodePaths. This saves a lot of
time when SceneTreeDock renames a node in a scene with a lot of
MeshInstances. This makes renaming nodes go from ~27 seconds to ~2
seconds on large scenes.
SceneTreeEditor instances will now also not do all of the potentially
expensive update work if they are invisible. This behavior is turned off
by default so it won't affect existing users. This change allows the
editor to only update SceneTreeEditors that actually in view. In
practice this means that for most changes instead of updating 6
SceneTreeEditors we only update 1 instantly, and the others only when
they become visible.
There is definitely more that could be done, but this is already a
massive improvement. In complex scenes we see an improvement of 10x,
things that used to take ~30 seconds now only take 2.
This fixes#83460
I want to thank KoBeWi, TokisanGames, a-johnston, aniel080400 for
their tireless testing. And AeioMuch for their testing and providing a
fix for the hover issue.
- Controls
- `LineEdit`, `TextEdit`: Always disabled since it's dragging user input.
- `TabBar`: Use the same auto translate mode as the node.
- `RichTextLabel`: Always disable since auto translation is done
differently from other controls (selection text you get
programmatically is always after auto translation).
- Editor
- Disable drag preview auto translation if the text is user input,
filename, or class name.
- Also disabled unexpected auto translation for audio bus effect names.
- Instead of checking for Key::UP, Key::DOWN, Key::PAGEUP, Key::PAGEDOWN etc., we rather check for the action like 'ui_up' or 'ui_down'.
- Also use AcceptDialog's 'register_text_enter' functionality to consistently close a dialog when ENTER is pressed while the LineEdit has focus (instead of redirecting ENTER keys to e.g. the underlying Tree).
- Unify the LineEdit filter behavior for the SceneTreeDialog and corresponding usages
- Improve OK Button disablement (something should be selected)
This broke when the `node_selected` connection was removed in #91435.
Here it's returned, but the emit is removed from `_node_removed`. That
preserves the earlier fix while allowing nodes to be reselected.
- Create AudioStreamPlayer if dropped in between nodes in the Scene dock
- Create AudioStreamPlayer2D if dropped into 2D editor
- Create AudioStreamPlayer3D if dropped into 3D editor
Random-access access to `List` when iterating is `O(n^2)` (`O(n)` when
accessing a single element)
* Removed subscript operator, in favor of a more explicit `get`
* Added conversion from `Iterator` to `ConstIterator`
* Remade existing operations into other solutions when applicable