Переглянути джерело

Merge pull request #10443 from karroffel/propagate_call

add "propagate_call" method to Node
Rémi Verschelde 8 роки тому
батько
коміт
d37bd15cb9
3 змінених файлів з 31 додано та 0 видалено
  1. 11 0
      doc/base/classes.xml
  2. 18 0
      scene/main/node.cpp
  3. 2 0
      scene/main/node.h

+ 11 - 0
doc/base/classes.xml

@@ -26542,6 +26542,17 @@
 				Notify the current node and all its children recursively by calling notification() in all of them.
 			</description>
 		</method>
+		<method name="propagate_call">
+			<argument index="0" name="method" type="String">
+			</argument>
+			<argument index="1" name="args" type="Array" default="[]">
+			</argument>
+			<argument index="2" name="parent_first" type="bool" default="false">
+			</argument>
+			<description>
+				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.
+			</description>
+		</method>
 		<method name="queue_free">
 			<description>
 			</description>

+ 18 - 0
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);

+ 2 - 0
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;