Implemented proceses priority

This commit is contained in:
Andrea Catania 2018-07-02 07:30:40 +02:00
parent b3627e29f0
commit 51dfa10ac7
4 changed files with 49 additions and 5 deletions

View file

@ -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)
@ -2607,6 +2628,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);
@ -2758,6 +2780,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;

View file

@ -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;

View file

@ -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;
}
@ -915,7 +926,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.

View file

@ -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);