Browse Source

Merge pull request #19888 from AndreaCatania/pry

Implemented proceses priority
Juan Linietsky 7 years ago
parent
commit
172f652dc0
4 changed files with 49 additions and 5 deletions
  1. 23 0
      scene/main/node.cpp
  2. 9 0
      scene/main/node.h
  3. 15 4
      scene/main/scene_tree.cpp
  4. 2 1
      scene/main/scene_tree.h

+ 23 - 0
scene/main/node.cpp

@@ -809,6 +809,22 @@ bool Node::is_processing_internal() const {
 	return data.idle_process_internal;
 }
 
+void Node::set_process_priority(int p_priority) {
+	data.process_priority = p_priority;
+
+	if (is_processing())
+		data.tree->make_group_changed("idle_process");
+
+	if (is_processing_internal())
+		data.tree->make_group_changed("idle_process_internal");
+
+	if (is_physics_processing())
+		data.tree->make_group_changed("physics_process");
+
+	if (is_physics_processing_internal())
+		data.tree->make_group_changed("physics_process_internal");
+}
+
 void Node::set_process_input(bool p_enable) {
 
 	if (p_enable == data.input)
@@ -1388,6 +1404,11 @@ bool Node::is_greater_than(const Node *p_node) const {
 	return res;
 }
 
+bool Node::has_priority_higher_than(const Node *p_node) const {
+	ERR_FAIL_NULL_V(p_node, false);
+	return data.process_priority > p_node->data.process_priority;
+}
+
 void Node::get_owned_by(Node *p_by, List<Node *> *p_owned) {
 
 	if (data.owner == p_by)
@@ -2608,6 +2629,7 @@ void Node::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("is_physics_processing"), &Node::is_physics_processing);
 	ClassDB::bind_method(D_METHOD("get_process_delta_time"), &Node::get_process_delta_time);
 	ClassDB::bind_method(D_METHOD("set_process", "enable"), &Node::set_process);
+	ClassDB::bind_method(D_METHOD("set_process_priority", "priority"), &Node::set_process_priority);
 	ClassDB::bind_method(D_METHOD("is_processing"), &Node::is_processing);
 	ClassDB::bind_method(D_METHOD("set_process_input", "enable"), &Node::set_process_input);
 	ClassDB::bind_method(D_METHOD("is_processing_input"), &Node::is_processing_input);
@@ -2759,6 +2781,7 @@ Node::Node() {
 	data.tree = NULL;
 	data.physics_process = false;
 	data.idle_process = false;
+	data.process_priority = 0;
 	data.physics_process_internal = false;
 	data.idle_process_internal = false;
 	data.inside_tree = false;

+ 9 - 0
scene/main/node.h

@@ -70,6 +70,11 @@ public:
 		bool operator()(const Node *p_a, const Node *p_b) const { return p_b->is_greater_than(p_a); }
 	};
 
+	struct ComparatorWithPriority {
+
+		bool operator()(const Node *p_a, const Node *p_b) const { return p_b->has_priority_higher_than(p_a) || p_b->is_greater_than(p_a); }
+	};
+
 private:
 	struct GroupData {
 
@@ -118,6 +123,7 @@ private:
 		//should move all the stuff below to bits
 		bool physics_process;
 		bool idle_process;
+		int process_priority;
 
 		bool physics_process_internal;
 		bool idle_process_internal;
@@ -259,6 +265,7 @@ public:
 
 	bool is_a_parent_of(const Node *p_node) const;
 	bool is_greater_than(const Node *p_node) const;
+	bool has_priority_higher_than(const Node *p_node) const;
 
 	NodePath get_path() const;
 	NodePath get_path_to(const Node *p_node) const;
@@ -319,6 +326,8 @@ public:
 	void set_process_internal(bool p_idle_process_internal);
 	bool is_processing_internal() const;
 
+	void set_process_priority(int p_priority);
+
 	void set_process_input(bool p_enable);
 	bool is_processing_input() const;
 

+ 15 - 4
scene/main/scene_tree.cpp

@@ -132,6 +132,12 @@ void SceneTree::remove_from_group(const StringName &p_group, Node *p_node) {
 		group_map.erase(E);
 }
 
+void SceneTree::make_group_changed(const StringName &p_group) {
+	Map<StringName, Group>::Element *E = group_map.find(p_group);
+	if (E)
+		E->get().changed = true;
+}
+
 void SceneTree::flush_transform_notifications() {
 
 	SelfList<Node> *n = xform_change_list.first();
@@ -165,7 +171,7 @@ void SceneTree::_flush_ugc() {
 	ugc_locked = false;
 }
 
-void SceneTree::_update_group_order(Group &g) {
+void SceneTree::_update_group_order(Group &g, bool p_use_priority) {
 
 	if (!g.changed)
 		return;
@@ -175,8 +181,13 @@ void SceneTree::_update_group_order(Group &g) {
 	Node **nodes = &g.nodes[0];
 	int node_count = g.nodes.size();
 
-	SortArray<Node *, Node::Comparator> node_sort;
-	node_sort.sort(nodes, node_count);
+	if (p_use_priority) {
+		SortArray<Node *, Node::ComparatorWithPriority> node_sort;
+		node_sort.sort(nodes, node_count);
+	} else {
+		SortArray<Node *, Node::Comparator> node_sort;
+		node_sort.sort(nodes, node_count);
+	}
 	g.changed = false;
 }
 
@@ -921,7 +932,7 @@ void SceneTree::_notify_group_pause(const StringName &p_group, int p_notificatio
 	if (g.nodes.empty())
 		return;
 
-	_update_group_order(g);
+	_update_group_order(g, p_notification == Node::NOTIFICATION_PROCESS || p_notification == Node::NOTIFICATION_INTERNAL_PROCESS || p_notification == Node::NOTIFICATION_PHYSICS_PROCESS || p_notification == Node::NOTIFICATION_INTERNAL_PHYSICS_PROCESS);
 
 	//copy, so copy on write happens in case something is removed from process while being called
 	//performance is not lost because only if something is added/removed the vector is copied.

+ 2 - 1
scene/main/scene_tree.h

@@ -161,7 +161,7 @@ private:
 	bool ugc_locked;
 	void _flush_ugc();
 
-	_FORCE_INLINE_ void _update_group_order(Group &g);
+	_FORCE_INLINE_ void _update_group_order(Group &g, bool p_use_priority = false);
 	void _update_listener();
 
 	Array _get_nodes_in_group(const StringName &p_group);
@@ -204,6 +204,7 @@ private:
 
 	Group *add_to_group(const StringName &p_group, Node *p_node);
 	void remove_from_group(const StringName &p_group, Node *p_node);
+	void make_group_changed(const StringName &p_group);
 
 	void _notify_group_pause(const StringName &p_group, int p_notification);
 	void _call_input_pause(const StringName &p_group, const StringName &p_method, const Ref<InputEvent> &p_input);