diff options
author | Juan Linietsky <reduzio@gmail.com> | 2023-04-05 18:53:32 +0200 |
---|---|---|
committer | Juan Linietsky <reduzio@gmail.com> | 2023-04-06 13:57:13 +0200 |
commit | 104392ef4ea7b983b27c44de72adfc627500e814 (patch) | |
tree | 2a6cc0938c9254efc1c206527310b0caa25833db /scene/main/canvas_item.cpp | |
parent | 44d539465acca7592e0c88748e231fe5f151da37 (diff) | |
download | redot-engine-104392ef4ea7b983b27c44de72adfc627500e814.tar.gz |
Remove NOTIFICATION_MOVED_IN_PARENT
* This notification makes node children management very inefficient.
* Replaced by a NOTIFICATION_CHILDREN_CHANGED (and children_changed signal).
* Changed Canvas code (and similar) to use the above signal, to perform more efficiently.
This PR breaks compatibility (although this notification was very rarely used, even within the engine), but provides an alternate way to do the same.
It is required for the changes in #75627 to be entirely effective.
Diffstat (limited to 'scene/main/canvas_item.cpp')
-rw-r--r-- | scene/main/canvas_item.cpp | 37 |
1 files changed, 23 insertions, 14 deletions
diff --git a/scene/main/canvas_item.cpp b/scene/main/canvas_item.cpp index 72fb838732..4eabc4916c 100644 --- a/scene/main/canvas_item.cpp +++ b/scene/main/canvas_item.cpp @@ -188,10 +188,13 @@ void CanvasItem::_enter_canvas() { // Resolves to nullptr if the node is top_level. CanvasItem *parent_item = get_parent_item(); + if (get_parent()) { + get_viewport()->canvas_parent_mark_dirty(get_parent()); + } + if (parent_item) { canvas_layer = parent_item->canvas_layer; RenderingServer::get_singleton()->canvas_item_set_parent(canvas_item, parent_item->get_canvas_item()); - RenderingServer::get_singleton()->canvas_item_set_draw_index(canvas_item, get_index()); RenderingServer::get_singleton()->canvas_item_set_visibility_layer(canvas_item, visibility_layer); } else { Node *n = this; @@ -227,8 +230,6 @@ void CanvasItem::_enter_canvas() { } else { get_viewport()->gui_reset_canvas_sort_index(); } - - get_tree()->call_group_flags(SceneTree::GROUP_CALL_UNIQUE | SceneTree::GROUP_CALL_DEFERRED, canvas_group, SNAME("_top_level_raise_self")); } pending_update = false; @@ -302,21 +303,12 @@ void CanvasItem::_notification(int p_what) { if (!block_transform_notify && !xform_change.in_list()) { get_tree()->xform_change_list.add(&xform_change); } - } break; - case NOTIFICATION_MOVED_IN_PARENT: { - if (!is_inside_tree()) { - break; + if (get_viewport()) { + get_parent()->connect(SNAME("child_order_changed"), callable_mp(get_viewport(), &Viewport::canvas_parent_mark_dirty).bind(get_parent()), CONNECT_REFERENCE_COUNTED); } - if (canvas_group != StringName()) { - get_tree()->call_group_flags(SceneTree::GROUP_CALL_UNIQUE | SceneTree::GROUP_CALL_DEFERRED, canvas_group, "_top_level_raise_self"); - } else { - ERR_FAIL_COND_MSG(!get_parent_item(), "Moved child is in incorrect state (no canvas group, no canvas item parent)."); - RenderingServer::get_singleton()->canvas_item_set_draw_index(canvas_item, get_index()); - } } break; - case NOTIFICATION_EXIT_TREE: { if (xform_change.in_list()) { get_tree()->xform_change_list.remove(&xform_change); @@ -332,6 +324,10 @@ void CanvasItem::_notification(int p_what) { } global_invalid = true; parent_visible_in_tree = false; + + if (get_viewport()) { + get_parent()->disconnect(SNAME("child_order_changed"), callable_mp(get_viewport(), &Viewport::canvas_parent_mark_dirty).bind(get_parent())); + } } break; case NOTIFICATION_VISIBILITY_CHANGED: { @@ -340,6 +336,19 @@ void CanvasItem::_notification(int p_what) { } } +void CanvasItem::update_draw_order() { + if (!is_inside_tree()) { + return; + } + + if (canvas_group != StringName()) { + get_tree()->call_group_flags(SceneTree::GROUP_CALL_UNIQUE | SceneTree::GROUP_CALL_DEFERRED, canvas_group, "_top_level_raise_self"); + } else { + ERR_FAIL_COND_MSG(!get_parent_item(), "Moved child is in incorrect state (no canvas group, no canvas item parent)."); + RenderingServer::get_singleton()->canvas_item_set_draw_index(canvas_item, get_index()); + } +} + void CanvasItem::_window_visibility_changed() { if (visible) { _propagate_visibility_changed(window->is_visible()); |