Skip to content

Commit

Permalink
Improve Scene Tree editor performance
Browse files Browse the repository at this point in the history
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 godotengine#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.
  • Loading branch information
hpvb committed Dec 11, 2024
1 parent 44dfa7e commit 84d64bc
Show file tree
Hide file tree
Showing 14 changed files with 803 additions and 173 deletions.
1 change: 1 addition & 0 deletions core/object/object.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ enum PropertyHint {
PROPERTY_HINT_DICTIONARY_TYPE,
PROPERTY_HINT_TOOL_BUTTON,
PROPERTY_HINT_ONESHOT, ///< the property will be changed by self after setting, such as AudioStreamPlayer.playing, Particles.emitting.
PROPERTY_HINT_NO_NODEPATH, /// < this property will not contain a NodePath, regardless of type (Array, Dictionary, List, etc.). Needed for SceneTreeDock.
PROPERTY_HINT_MAX,
};

Expand Down
2 changes: 1 addition & 1 deletion doc/classes/@GlobalScope.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2943,7 +2943,7 @@
<constant name="PROPERTY_HINT_ONESHOT" value="40" enum="PropertyHint">
Hints that a property will be changed on its own after setting, such as [member AudioStreamPlayer.playing] or [member GPUParticles3D.emitting].
</constant>
<constant name="PROPERTY_HINT_MAX" value="41" enum="PropertyHint">
<constant name="PROPERTY_HINT_MAX" value="42" enum="PropertyHint">
Represents the size of the [enum PropertyHint] enum.
</constant>
<constant name="PROPERTY_USAGE_NONE" value="0" enum="PropertyUsageFlags" is_bitfield="true">
Expand Down
5 changes: 5 additions & 0 deletions doc/classes/Node.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1068,6 +1068,11 @@
Emitted when the node's editor description field changed.
</description>
</signal>
<signal name="editor_state_changed">
<description>
Emitted when an attribute of the node that is relevant to the editor is changed. Only emitted in the editor.
</description>
</signal>
<signal name="ready">
<description>
Emitted when the node is considered ready, after [method _ready] is called.
Expand Down
1 change: 1 addition & 0 deletions editor/connections_dialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -735,6 +735,7 @@ ConnectDialog::ConnectDialog() {
from_signal->set_editable(false);

tree = memnew(SceneTreeEditor(false));
tree->set_update_when_invisible(false);
tree->set_connecting_signal(true);
tree->set_show_enabled_subscene(true);
tree->set_v_size_flags(Control::SIZE_FILL | Control::SIZE_EXPAND);
Expand Down
Loading

0 comments on commit 84d64bc

Please sign in to comment.