From 390f7def39a6ff9a34a3a85f6b180d341b52d869 Mon Sep 17 00:00:00 2001 From: Karroffel Date: Sat, 19 Aug 2017 15:17:06 +0200 Subject: [PATCH] add "propagate_call" method to Node It is possible to propagate a notification down the Node tree by using `propagate_notification`, but there was no such method for doing the same but with method calls. This commit adds the `propagate_call` method, which calls a method on a node and all child nodes. An optional paramter `parent_first` determines whether the parent node gets called before or after the children have been visited. It defaults to false, so the parent gets called last. --- doc/base/classes.xml | 11 +++++++++++ scene/main/node.cpp | 18 ++++++++++++++++++ scene/main/node.h | 2 ++ 3 files changed, 31 insertions(+) diff --git a/doc/base/classes.xml b/doc/base/classes.xml index f21fa2c7c060..fd3e428c8b1a 100644 --- a/doc/base/classes.xml +++ b/doc/base/classes.xml @@ -26549,6 +26549,17 @@ Notify the current node and all its children recursively by calling notification() in all of them. + + + + + + + + + Calls the method (if present) with the arguments given in "args" on this Node and recursively on all children. If the parent_first argument is true then the method will be called on the current [Node] first, then on all children. If it is false then the children will get called first. + + diff --git a/scene/main/node.cpp b/scene/main/node.cpp index 0474c6fd26d5..8a31b1ef01dc 100755 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -1954,6 +1954,23 @@ void Node::propagate_notification(int p_notification) { data.blocked--; } +void Node::propagate_call(const StringName &p_method, const Array &p_args, const bool p_parent_first) { + + data.blocked++; + + if (p_parent_first && has_method(p_method)) + callv(p_method, p_args); + + for (int i = 0; i < data.children.size(); i++) { + data.children[i]->propagate_call(p_method, p_args, p_parent_first); + } + + if (!p_parent_first && has_method(p_method)) + callv(p_method, p_args); + + data.blocked--; +} + void Node::_propagate_replace_owner(Node *p_owner, Node *p_by_owner) { if (get_owner() == p_owner) set_owner(p_by_owner); @@ -2761,6 +2778,7 @@ void Node::_bind_methods() { ClassDB::bind_method(D_METHOD("set_filename", "filename"), &Node::set_filename); ClassDB::bind_method(D_METHOD("get_filename"), &Node::get_filename); ClassDB::bind_method(D_METHOD("propagate_notification", "what"), &Node::propagate_notification); + ClassDB::bind_method(D_METHOD("propagate_call", "method", "args", "parent_first"), &Node::propagate_call, DEFVAL(Array()), DEFVAL(false)); ClassDB::bind_method(D_METHOD("set_fixed_process", "enable"), &Node::set_fixed_process); ClassDB::bind_method(D_METHOD("get_fixed_process_delta_time"), &Node::get_fixed_process_delta_time); ClassDB::bind_method(D_METHOD("is_fixed_processing"), &Node::is_fixed_processing); diff --git a/scene/main/node.h b/scene/main/node.h index bb8d80a0c869..180ec0577330 100644 --- a/scene/main/node.h +++ b/scene/main/node.h @@ -298,6 +298,8 @@ public: void propagate_notification(int p_notification); + void propagate_call(const StringName &p_method, const Array &p_args = Array(), const bool p_parent_first = false); + /* PROCESSING */ void set_fixed_process(bool p_process); float get_fixed_process_delta_time() const;