summaryrefslogtreecommitdiffstats
path: root/scene/main/canvas_item.cpp
diff options
context:
space:
mode:
authorJuan Linietsky <reduzio@gmail.com>2023-04-05 18:53:32 +0200
committerJuan Linietsky <reduzio@gmail.com>2023-04-06 13:57:13 +0200
commit104392ef4ea7b983b27c44de72adfc627500e814 (patch)
tree2a6cc0938c9254efc1c206527310b0caa25833db /scene/main/canvas_item.cpp
parent44d539465acca7592e0c88748e231fe5f151da37 (diff)
downloadredot-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.cpp37
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());