Refactor Process Mode

Implements https://github.com/godotengine/godot-proposals/issues/1835#issuecomment-727186192

* PauseMode is now ProcessMode, containing the following states:
	```
	PROCESS_MODE_INHERIT, // same as parent node
	PROCESS_MODE_NORMAL, // process only if not paused
	PROCESS_MODE_PAUSE_ONLY, // process only if paused
	PROCESS_MODE_ALWAYS, // process always
	PROCESS_MODE_DISABLED, // never process
	```
* NOTIFICATION_PAUSED and NOTIFICATION_UNPAUSED are received effectively when the node is paused and unpaused (not any longer when pause mode is set in SceneTree).
* Renamed some nodes that used ProcessMode/process_mode to specify a callback type to ProcessCallback to avoid clashes.
This commit is contained in:
reduz 2021-02-18 15:52:29 -03:00
parent 247b7e2448
commit 083aa9b95e
17 changed files with 206 additions and 143 deletions

View file

@ -1761,6 +1761,10 @@ void EditorInspector::update_tree() {
continue;
}
if (p.name == "script") {
category_vbox = nullptr; // script should go into its own category
}
if (p.usage & PROPERTY_USAGE_HIGH_END_GFX && RS::get_singleton()->is_low_end()) {
continue; //do not show this property in low end gfx
}

View file

@ -81,7 +81,7 @@ void GPUParticles2DEditorPlugin::_menu_callback(int p_idx) {
cpu_particles->set_name(particles->get_name());
cpu_particles->set_transform(particles->get_transform());
cpu_particles->set_visible(particles->is_visible());
cpu_particles->set_pause_mode(particles->get_pause_mode());
cpu_particles->set_process_mode(particles->get_process_mode());
cpu_particles->set_z_index(particles->get_z_index());
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();

View file

@ -263,7 +263,7 @@ void GPUParticles3DEditor::_menu_option(int p_option) {
cpu_particles->set_name(node->get_name());
cpu_particles->set_transform(node->get_transform());
cpu_particles->set_visible(node->is_visible());
cpu_particles->set_pause_mode(node->get_pause_mode());
cpu_particles->set_process_mode(node->get_process_mode());
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
ur->create_action(TTR("Convert to CPUParticles3D"));

View file

@ -236,6 +236,8 @@ bool SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent, bool p_scroll
item->set_text(0, node_name);
item->set_selectable(0, marked_selectable);
item->set_custom_color(0, get_theme_color("accent_color", "Editor"));
} else if (!p_node->can_process()) {
item->set_custom_color(0, get_theme_color("disabled_font_color", "Editor"));
} else if (!marked_selectable && !marked_children_selectable) {
Node *node = p_node;
while (node) {
@ -585,6 +587,11 @@ void SceneTreeEditor::_test_update_tree() {
tree_dirty = true;
}
void SceneTreeEditor::_tree_process_mode_changed() {
MessageQueue::get_singleton()->push_call(this, "_update_tree");
tree_dirty = true;
}
void SceneTreeEditor::_tree_changed() {
if (EditorNode::get_singleton()->is_exiting()) {
return; //speed up exit
@ -655,6 +662,7 @@ void SceneTreeEditor::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
get_tree()->connect("tree_changed", callable_mp(this, &SceneTreeEditor::_tree_changed));
get_tree()->connect("tree_process_mode_changed", callable_mp(this, &SceneTreeEditor::_tree_process_mode_changed));
get_tree()->connect("node_removed", callable_mp(this, &SceneTreeEditor::_node_removed));
get_tree()->connect("node_renamed", callable_mp(this, &SceneTreeEditor::_node_renamed));
get_tree()->connect("node_configuration_warning_changed", callable_mp(this, &SceneTreeEditor::_warning_changed));
@ -665,6 +673,7 @@ void SceneTreeEditor::_notification(int p_what) {
} break;
case NOTIFICATION_EXIT_TREE: {
get_tree()->disconnect("tree_changed", callable_mp(this, &SceneTreeEditor::_tree_changed));
get_tree()->disconnect("tree_process_mode_changed", callable_mp(this, &SceneTreeEditor::_tree_process_mode_changed));
get_tree()->disconnect("node_removed", callable_mp(this, &SceneTreeEditor::_node_removed));
get_tree()->disconnect("node_renamed", callable_mp(this, &SceneTreeEditor::_node_renamed));
tree->disconnect("item_collapsed", callable_mp(this, &SceneTreeEditor::_cell_collapsed));

View file

@ -75,6 +75,7 @@ class SceneTreeEditor : public Control {
void _test_update_tree();
void _update_tree(bool p_scroll_to_selected = false);
void _tree_changed();
void _tree_process_mode_changed();
void _node_removed(Node *p_node);
void _node_renamed(Node *p_node);

View file

@ -63,11 +63,11 @@ void Camera2D::_update_scroll() {
};
}
void Camera2D::_update_process_mode() {
void Camera2D::_update_process_callback() {
if (Engine::get_singleton()->is_editor_hint()) {
set_process_internal(false);
set_physics_process_internal(false);
} else if (process_mode == CAMERA2D_PROCESS_IDLE) {
} else if (process_callback == CAMERA2D_PROCESS_IDLE) {
set_process_internal(true);
set_physics_process_internal(false);
} else {
@ -157,7 +157,7 @@ Transform2D Camera2D::get_camera_transform() {
}
if (smoothing_enabled && !Engine::get_singleton()->is_editor_hint()) {
float c = smoothing * (process_mode == CAMERA2D_PROCESS_PHYSICS ? get_physics_process_delta_time() : get_process_delta_time());
float c = smoothing * (process_callback == CAMERA2D_PROCESS_PHYSICS ? get_physics_process_delta_time() : get_process_delta_time());
smoothed_camera_pos = ((camera_pos - smoothed_camera_pos) * c) + smoothed_camera_pos;
ret_camera_pos = smoothed_camera_pos;
//camera_pos=camera_pos*(1.0-smoothing)+new_camera_pos*smoothing;
@ -247,7 +247,7 @@ void Camera2D::_notification(int p_what) {
add_to_group(group_name);
add_to_group(canvas_group_name);
_update_process_mode();
_update_process_callback();
_update_scroll();
first = true;
@ -375,17 +375,17 @@ bool Camera2D::is_rotating() const {
return rotating;
}
void Camera2D::set_process_mode(Camera2DProcessMode p_mode) {
if (process_mode == p_mode) {
void Camera2D::set_process_callback(Camera2DProcessCallback p_mode) {
if (process_callback == p_mode) {
return;
}
process_mode = p_mode;
_update_process_mode();
process_callback = p_mode;
_update_process_callback();
}
Camera2D::Camera2DProcessMode Camera2D::get_process_mode() const {
return process_mode;
Camera2D::Camera2DProcessCallback Camera2D::get_process_callback() const {
return process_callback;
}
void Camera2D::_make_current(Object *p_which) {
@ -651,8 +651,8 @@ void Camera2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("_update_scroll"), &Camera2D::_update_scroll);
ClassDB::bind_method(D_METHOD("set_process_mode", "mode"), &Camera2D::set_process_mode);
ClassDB::bind_method(D_METHOD("get_process_mode"), &Camera2D::get_process_mode);
ClassDB::bind_method(D_METHOD("set_process_callback", "mode"), &Camera2D::set_process_callback);
ClassDB::bind_method(D_METHOD("get_process_callback"), &Camera2D::get_process_callback);
ClassDB::bind_method(D_METHOD("_set_current", "current"), &Camera2D::_set_current);
ClassDB::bind_method(D_METHOD("is_current"), &Camera2D::is_current);
@ -714,7 +714,7 @@ void Camera2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "current"), "_set_current", "is_current");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "zoom"), "set_zoom", "get_zoom");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "custom_viewport", PROPERTY_HINT_RESOURCE_TYPE, "Viewport", 0), "set_custom_viewport", "get_custom_viewport");
ADD_PROPERTY(PropertyInfo(Variant::INT, "process_mode", PROPERTY_HINT_ENUM, "Physics,Idle"), "set_process_mode", "get_process_mode");
ADD_PROPERTY(PropertyInfo(Variant::INT, "process_callback", PROPERTY_HINT_ENUM, "Physics,Idle"), "set_process_callback", "get_process_callback");
ADD_GROUP("Limit", "limit_");
ADD_PROPERTYI(PropertyInfo(Variant::INT, "limit_left"), "set_limit", "get_limit", SIDE_LEFT);

View file

@ -43,7 +43,7 @@ public:
ANCHOR_MODE_DRAG_CENTER
};
enum Camera2DProcessMode {
enum Camera2DProcessCallback {
CAMERA2D_PROCESS_PHYSICS,
CAMERA2D_PROCESS_IDLE
};
@ -79,7 +79,7 @@ protected:
bool drag_vertical_offset_changed = false;
Point2 camera_screen_center;
void _update_process_mode();
void _update_process_callback();
void _update_scroll();
void _make_current(Object *p_which);
@ -91,7 +91,7 @@ protected:
bool limit_drawing_enabled = false;
bool margin_drawing_enabled = false;
Camera2DProcessMode process_mode = CAMERA2D_PROCESS_IDLE;
Camera2DProcessCallback process_callback = CAMERA2D_PROCESS_IDLE;
Size2 _get_camera_screen_size() const;
@ -137,8 +137,8 @@ public:
void set_follow_smoothing(float p_speed);
float get_follow_smoothing() const;
void set_process_mode(Camera2DProcessMode p_mode);
Camera2DProcessMode get_process_mode() const;
void set_process_callback(Camera2DProcessCallback p_mode);
Camera2DProcessCallback get_process_callback() const;
void make_current();
void clear_current();
@ -170,6 +170,6 @@ public:
};
VARIANT_ENUM_CAST(Camera2D::AnchorMode);
VARIANT_ENUM_CAST(Camera2D::Camera2DProcessMode);
VARIANT_ENUM_CAST(Camera2D::Camera2DProcessCallback);
#endif // CAMERA_2D_H

View file

@ -673,17 +673,17 @@ float ClippedCamera3D::get_margin() const {
return margin;
}
void ClippedCamera3D::set_process_mode(ProcessMode p_mode) {
if (process_mode == p_mode) {
void ClippedCamera3D::set_process_callback(ClipProcessCallback p_mode) {
if (process_callback == p_mode) {
return;
}
process_mode = p_mode;
set_process_internal(process_mode == CLIP_PROCESS_IDLE);
set_physics_process_internal(process_mode == CLIP_PROCESS_PHYSICS);
process_callback = p_mode;
set_process_internal(process_callback == CLIP_PROCESS_IDLE);
set_physics_process_internal(process_callback == CLIP_PROCESS_PHYSICS);
}
ClippedCamera3D::ProcessMode ClippedCamera3D::get_process_mode() const {
return process_mode;
ClippedCamera3D::ClipProcessCallback ClippedCamera3D::get_process_callback() const {
return process_callback;
}
Transform ClippedCamera3D::get_camera_transform() const {
@ -828,8 +828,8 @@ void ClippedCamera3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_margin", "margin"), &ClippedCamera3D::set_margin);
ClassDB::bind_method(D_METHOD("get_margin"), &ClippedCamera3D::get_margin);
ClassDB::bind_method(D_METHOD("set_process_mode", "process_mode"), &ClippedCamera3D::set_process_mode);
ClassDB::bind_method(D_METHOD("get_process_mode"), &ClippedCamera3D::get_process_mode);
ClassDB::bind_method(D_METHOD("set_process_callback", "process_callback"), &ClippedCamera3D::set_process_callback);
ClassDB::bind_method(D_METHOD("get_process_callback"), &ClippedCamera3D::get_process_callback);
ClassDB::bind_method(D_METHOD("set_collision_mask", "mask"), &ClippedCamera3D::set_collision_mask);
ClassDB::bind_method(D_METHOD("get_collision_mask"), &ClippedCamera3D::get_collision_mask);
@ -854,7 +854,7 @@ void ClippedCamera3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("clear_exceptions"), &ClippedCamera3D::clear_exceptions);
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "margin", PROPERTY_HINT_RANGE, "0,32,0.01"), "set_margin", "get_margin");
ADD_PROPERTY(PropertyInfo(Variant::INT, "process_mode", PROPERTY_HINT_ENUM, "Physics,Idle"), "set_process_mode", "get_process_mode");
ADD_PROPERTY(PropertyInfo(Variant::INT, "process_callback", PROPERTY_HINT_ENUM, "Physics,Idle"), "set_process_callback", "get_process_callback");
ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_mask", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_mask", "get_collision_mask");
ADD_GROUP("Clip To", "clip_to");

View file

@ -186,13 +186,13 @@ class ClippedCamera3D : public Camera3D {
GDCLASS(ClippedCamera3D, Camera3D);
public:
enum ProcessMode {
enum ClipProcessCallback {
CLIP_PROCESS_PHYSICS,
CLIP_PROCESS_IDLE,
};
private:
ProcessMode process_mode = CLIP_PROCESS_PHYSICS;
ClipProcessCallback process_callback = CLIP_PROCESS_PHYSICS;
RID pyramid_shape;
float margin = 0.0;
float clip_offset = 0.0;
@ -219,8 +219,8 @@ public:
void set_margin(float p_margin);
float get_margin() const;
void set_process_mode(ProcessMode p_mode);
ProcessMode get_process_mode() const;
void set_process_callback(ClipProcessCallback p_mode);
ClipProcessCallback get_process_callback() const;
void set_collision_mask(uint32_t p_mask);
uint32_t get_collision_mask() const;
@ -240,5 +240,5 @@ public:
~ClippedCamera3D();
};
VARIANT_ENUM_CAST(ClippedCamera3D::ProcessMode);
VARIANT_ENUM_CAST(ClippedCamera3D::ClipProcessCallback);
#endif

View file

@ -206,7 +206,7 @@ void AnimationPlayer::_notification(int p_what) {
}
} break;
case NOTIFICATION_INTERNAL_PROCESS: {
if (animation_process_mode == ANIMATION_PROCESS_PHYSICS) {
if (process_callback == ANIMATION_PROCESS_PHYSICS) {
break;
}
@ -215,7 +215,7 @@ void AnimationPlayer::_notification(int p_what) {
}
} break;
case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
if (animation_process_mode == ANIMATION_PROCESS_IDLE) {
if (process_callback == ANIMATION_PROCESS_IDLE) {
break;
}
@ -1403,8 +1403,8 @@ bool AnimationPlayer::is_reset_on_save_enabled() const {
return reset_on_save;
}
void AnimationPlayer::set_animation_process_mode(AnimationProcessMode p_mode) {
if (animation_process_mode == p_mode) {
void AnimationPlayer::set_process_callback(AnimationProcessCallback p_mode) {
if (process_callback == p_mode) {
return;
}
@ -1412,14 +1412,14 @@ void AnimationPlayer::set_animation_process_mode(AnimationProcessMode p_mode) {
if (pr) {
_set_process(false);
}
animation_process_mode = p_mode;
process_callback = p_mode;
if (pr) {
_set_process(true);
}
}
AnimationPlayer::AnimationProcessMode AnimationPlayer::get_animation_process_mode() const {
return animation_process_mode;
AnimationPlayer::AnimationProcessCallback AnimationPlayer::get_process_callback() const {
return process_callback;
}
void AnimationPlayer::set_method_call_mode(AnimationMethodCallMode p_mode) {
@ -1435,7 +1435,7 @@ void AnimationPlayer::_set_process(bool p_process, bool p_force) {
return;
}
switch (animation_process_mode) {
switch (process_callback) {
case ANIMATION_PROCESS_PHYSICS:
set_physics_process_internal(p_process && active);
break;
@ -1637,8 +1637,8 @@ void AnimationPlayer::_bind_methods() {
ClassDB::bind_method(D_METHOD("clear_caches"), &AnimationPlayer::clear_caches);
ClassDB::bind_method(D_METHOD("set_animation_process_mode", "mode"), &AnimationPlayer::set_animation_process_mode);
ClassDB::bind_method(D_METHOD("get_animation_process_mode"), &AnimationPlayer::get_animation_process_mode);
ClassDB::bind_method(D_METHOD("set_process_callback", "mode"), &AnimationPlayer::set_process_callback);
ClassDB::bind_method(D_METHOD("get_process_callback"), &AnimationPlayer::get_process_callback);
ClassDB::bind_method(D_METHOD("set_method_call_mode", "mode"), &AnimationPlayer::set_method_call_mode);
ClassDB::bind_method(D_METHOD("get_method_call_mode"), &AnimationPlayer::get_method_call_mode);
@ -1658,7 +1658,7 @@ void AnimationPlayer::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "current_animation_position", PROPERTY_HINT_NONE, "", 0), "", "get_current_animation_position");
ADD_GROUP("Playback Options", "playback_");
ADD_PROPERTY(PropertyInfo(Variant::INT, "playback_process_mode", PROPERTY_HINT_ENUM, "Physics,Idle,Manual"), "set_animation_process_mode", "get_animation_process_mode");
ADD_PROPERTY(PropertyInfo(Variant::INT, "playback_process_mode", PROPERTY_HINT_ENUM, "Physics,Idle,Manual"), "set_process_callback", "get_process_callback");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "playback_default_blend_time", PROPERTY_HINT_RANGE, "0,4096,0.01"), "set_default_blend_time", "get_default_blend_time");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "playback_active", PROPERTY_HINT_NONE, "", 0), "set_active", "is_active");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "playback_speed", PROPERTY_HINT_RANGE, "-64,64,0.01"), "set_speed_scale", "get_speed_scale");

View file

@ -64,7 +64,7 @@ class AnimationPlayer : public Node {
OBJ_CATEGORY("Animation Nodes");
public:
enum AnimationProcessMode {
enum AnimationProcessCallback {
ANIMATION_PROCESS_PHYSICS,
ANIMATION_PROCESS_IDLE,
ANIMATION_PROCESS_MANUAL,
@ -206,7 +206,7 @@ private:
String autoplay;
bool reset_on_save = true;
AnimationProcessMode animation_process_mode = ANIMATION_PROCESS_IDLE;
AnimationProcessCallback process_callback = ANIMATION_PROCESS_IDLE;
AnimationMethodCallMode method_call_mode = ANIMATION_METHOD_CALL_DEFERRED;
bool processing = false;
bool active = true;
@ -298,8 +298,8 @@ public:
void set_reset_on_save_enabled(bool p_enabled);
bool is_reset_on_save_enabled() const;
void set_animation_process_mode(AnimationProcessMode p_mode);
AnimationProcessMode get_animation_process_mode() const;
void set_process_callback(AnimationProcessCallback p_mode);
AnimationProcessCallback get_process_callback() const;
void set_method_call_mode(AnimationMethodCallMode p_mode);
AnimationMethodCallMode get_method_call_mode() const;
@ -328,7 +328,7 @@ public:
~AnimationPlayer();
};
VARIANT_ENUM_CAST(AnimationPlayer::AnimationProcessMode);
VARIANT_ENUM_CAST(AnimationPlayer::AnimationProcessCallback);
VARIANT_ENUM_CAST(AnimationPlayer::AnimationMethodCallMode);
#endif

View file

@ -473,7 +473,7 @@ void AnimationTree::set_active(bool p_active) {
active = p_active;
started = active;
if (process_mode == ANIMATION_PROCESS_IDLE) {
if (process_callback == ANIMATION_PROCESS_IDLE) {
set_process_internal(active);
} else {
set_physics_process_internal(active);
@ -494,8 +494,8 @@ bool AnimationTree::is_active() const {
return active;
}
void AnimationTree::set_process_mode(AnimationProcessMode p_mode) {
if (process_mode == p_mode) {
void AnimationTree::set_process_callback(AnimationProcessCallback p_mode) {
if (process_callback == p_mode) {
return;
}
@ -504,15 +504,15 @@ void AnimationTree::set_process_mode(AnimationProcessMode p_mode) {
set_active(false);
}
process_mode = p_mode;
process_callback = p_mode;
if (was_active) {
set_active(true);
}
}
AnimationTree::AnimationProcessMode AnimationTree::get_process_mode() const {
return process_mode;
AnimationTree::AnimationProcessCallback AnimationTree::get_process_callback() const {
return process_callback;
}
void AnimationTree::_node_removed(Node *p_node) {
@ -1234,11 +1234,11 @@ void AnimationTree::advance(float p_time) {
}
void AnimationTree::_notification(int p_what) {
if (active && p_what == NOTIFICATION_INTERNAL_PHYSICS_PROCESS && process_mode == ANIMATION_PROCESS_PHYSICS) {
if (active && p_what == NOTIFICATION_INTERNAL_PHYSICS_PROCESS && process_callback == ANIMATION_PROCESS_PHYSICS) {
_process_graph(get_physics_process_delta_time());
}
if (active && p_what == NOTIFICATION_INTERNAL_PROCESS && process_mode == ANIMATION_PROCESS_IDLE) {
if (active && p_what == NOTIFICATION_INTERNAL_PROCESS && process_callback == ANIMATION_PROCESS_IDLE) {
_process_graph(get_process_delta_time());
}
@ -1471,8 +1471,8 @@ void AnimationTree::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_tree_root", "root"), &AnimationTree::set_tree_root);
ClassDB::bind_method(D_METHOD("get_tree_root"), &AnimationTree::get_tree_root);
ClassDB::bind_method(D_METHOD("set_process_mode", "mode"), &AnimationTree::set_process_mode);
ClassDB::bind_method(D_METHOD("get_process_mode"), &AnimationTree::get_process_mode);
ClassDB::bind_method(D_METHOD("set_process_callback", "mode"), &AnimationTree::set_process_callback);
ClassDB::bind_method(D_METHOD("get_process_callback"), &AnimationTree::get_process_callback);
ClassDB::bind_method(D_METHOD("set_animation_player", "root"), &AnimationTree::set_animation_player);
ClassDB::bind_method(D_METHOD("get_animation_player"), &AnimationTree::get_animation_player);
@ -1491,7 +1491,7 @@ void AnimationTree::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "tree_root", PROPERTY_HINT_RESOURCE_TYPE, "AnimationRootNode"), "set_tree_root", "get_tree_root");
ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "anim_player", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "AnimationPlayer"), "set_animation_player", "get_animation_player");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "active"), "set_active", "is_active");
ADD_PROPERTY(PropertyInfo(Variant::INT, "process_mode", PROPERTY_HINT_ENUM, "Physics,Idle,Manual"), "set_process_mode", "get_process_mode");
ADD_PROPERTY(PropertyInfo(Variant::INT, "process_callback", PROPERTY_HINT_ENUM, "Physics,Idle,Manual"), "set_process_callback", "get_process_callback");
ADD_GROUP("Root Motion", "root_motion_");
ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "root_motion_track"), "set_root_motion_track", "get_root_motion_track");

View file

@ -163,7 +163,7 @@ class AnimationTree : public Node {
GDCLASS(AnimationTree, Node);
public:
enum AnimationProcessMode {
enum AnimationProcessCallback {
ANIMATION_PROCESS_PHYSICS,
ANIMATION_PROCESS_IDLE,
ANIMATION_PROCESS_MANUAL,
@ -238,7 +238,7 @@ private:
Ref<AnimationNode> root;
AnimationProcessMode process_mode = ANIMATION_PROCESS_IDLE;
AnimationProcessCallback process_callback = ANIMATION_PROCESS_IDLE;
bool active = false;
NodePath animation_player;
@ -294,8 +294,8 @@ public:
void set_active(bool p_active);
bool is_active() const;
void set_process_mode(AnimationProcessMode p_mode);
AnimationProcessMode get_process_mode() const;
void set_process_callback(AnimationProcessCallback p_mode);
AnimationProcessCallback get_process_callback() const;
void set_animation_player(const NodePath &p_player);
NodePath get_animation_player() const;
@ -320,6 +320,6 @@ public:
~AnimationTree();
};
VARIANT_ENUM_CAST(AnimationTree::AnimationProcessMode)
VARIANT_ENUM_CAST(AnimationTree::AnimationProcessCallback)
#endif // ANIMATION_GRAPH_PLAYER_H

View file

@ -89,12 +89,12 @@ void RootMotionView::_notification(int p_what) {
AnimationTree *tree = Object::cast_to<AnimationTree>(node);
if (tree && tree->is_active() && tree->get_root_motion_track() != NodePath()) {
if (is_processing_internal() && tree->get_process_mode() == AnimationTree::ANIMATION_PROCESS_PHYSICS) {
if (is_processing_internal() && tree->get_process_callback() == AnimationTree::ANIMATION_PROCESS_PHYSICS) {
set_process_internal(false);
set_physics_process_internal(true);
}
if (is_physics_processing_internal() && tree->get_process_mode() == AnimationTree::ANIMATION_PROCESS_IDLE) {
if (is_physics_processing_internal() && tree->get_process_callback() == AnimationTree::ANIMATION_PROCESS_IDLE) {
set_process_internal(true);
set_physics_process_internal(false);
}

View file

@ -46,7 +46,7 @@
#include <stdint.h>
VARIANT_ENUM_CAST(Node::PauseMode);
VARIANT_ENUM_CAST(Node::ProcessMode);
int Node::orphan_node_count = 0;
@ -69,14 +69,14 @@ void Node::_notification(int p_notification) {
ERR_FAIL_COND(!get_viewport());
ERR_FAIL_COND(!get_tree());
if (data.pause_mode == PAUSE_MODE_INHERIT) {
if (data.process_mode == PROCESS_MODE_INHERIT) {
if (data.parent) {
data.pause_owner = data.parent->data.pause_owner;
data.process_owner = data.parent->data.process_owner;
} else {
data.pause_owner = nullptr;
data.process_owner = nullptr;
}
} else {
data.pause_owner = this;
data.process_owner = this;
}
if (data.input) {
@ -110,7 +110,7 @@ void Node::_notification(int p_notification) {
remove_from_group("_vp_unhandled_key_input" + itos(get_viewport()->get_instance_id()));
}
data.pause_owner = nullptr;
data.process_owner = nullptr;
if (data.path_cache) {
memdelete(data.path_cache);
data.path_cache = nullptr;
@ -391,44 +391,81 @@ bool Node::is_physics_processing_internal() const {
return data.physics_process_internal;
}
void Node::set_pause_mode(PauseMode p_mode) {
if (data.pause_mode == p_mode) {
void Node::set_process_mode(ProcessMode p_mode) {
if (data.process_mode == p_mode) {
return;
}
bool prev_inherits = data.pause_mode == PAUSE_MODE_INHERIT;
data.pause_mode = p_mode;
if (!is_inside_tree()) {
return; //pointless
}
if ((data.pause_mode == PAUSE_MODE_INHERIT) == prev_inherits) {
return; ///nothing changed
data.process_mode = p_mode;
return;
}
Node *owner = nullptr;
bool prev_can_process = can_process();
if (data.pause_mode == PAUSE_MODE_INHERIT) {
data.process_mode = p_mode;
if (data.process_mode == PROCESS_MODE_INHERIT) {
if (data.parent) {
owner = data.parent->data.pause_owner;
data.process_owner = data.parent->data.owner;
} else {
data.process_owner = nullptr;
}
} else {
owner = this;
data.process_owner = this;
}
_propagate_pause_owner(owner);
}
bool next_can_process = can_process();
Node::PauseMode Node::get_pause_mode() const {
return data.pause_mode;
}
int pause_notification = 0;
void Node::_propagate_pause_owner(Node *p_owner) {
if (this != p_owner && data.pause_mode != PAUSE_MODE_INHERIT) {
return;
if (prev_can_process && !next_can_process) {
pause_notification = NOTIFICATION_PAUSED;
} else if (!prev_can_process && next_can_process) {
pause_notification = NOTIFICATION_UNPAUSED;
}
data.pause_owner = p_owner;
_propagate_process_owner(data.process_owner, pause_notification);
#ifdef TOOLS_ENABLED
// This is required for the editor to update the visibility of disabled nodes
// Its very expensive during runtime to change, so editor-only
if (Engine::get_singleton()->is_editor_hint()) {
get_tree()->emit_signal("tree_process_mode_changed");
}
#endif
}
void Node::_propagate_pause_notification(bool p_enable) {
bool prev_can_process = _can_process(!p_enable);
bool next_can_process = _can_process(p_enable);
if (prev_can_process && !next_can_process) {
notification(NOTIFICATION_PAUSED);
} else if (!prev_can_process && next_can_process) {
notification(NOTIFICATION_UNPAUSED);
}
for (int i = 0; i < data.children.size(); i++) {
data.children[i]->_propagate_pause_owner(p_owner);
data.children[i]->_propagate_pause_notification(p_enable);
}
}
Node::ProcessMode Node::get_process_mode() const {
return data.process_mode;
}
void Node::_propagate_process_owner(Node *p_owner, int p_notification) {
data.process_owner = p_owner;
if (p_notification != 0) {
notification(p_notification);
}
for (int i = 0; i < data.children.size(); i++) {
Node *c = data.children[i];
if (c->data.process_mode == PROCESS_MODE_INHERIT) {
c->_propagate_process_owner(p_owner, p_notification);
}
}
}
@ -805,30 +842,33 @@ bool Node::can_process_notification(int p_what) const {
bool Node::can_process() const {
ERR_FAIL_COND_V(!is_inside_tree(), false);
return _can_process(get_tree()->is_paused());
}
if (get_tree()->is_paused()) {
if (data.pause_mode == PAUSE_MODE_STOP) {
return false;
}
if (data.pause_mode == PAUSE_MODE_PROCESS) {
return true;
}
if (data.pause_mode == PAUSE_MODE_INHERIT) {
if (!data.pause_owner) {
return false; //clearly no pause owner by default
}
bool Node::_can_process(bool p_paused) const {
ProcessMode process_mode;
if (data.pause_owner->data.pause_mode == PAUSE_MODE_PROCESS) {
return true;
}
if (data.pause_owner->data.pause_mode == PAUSE_MODE_STOP) {
return false;
}
if (data.process_mode == PROCESS_MODE_INHERIT) {
if (!data.process_owner) {
process_mode = PROCESS_MODE_PAUSABLE;
} else {
process_mode = data.process_owner->data.process_mode;
}
} else {
process_mode = data.process_mode;
}
return true;
if (process_mode == PROCESS_MODE_DISABLED) {
return false;
} else if (process_mode == PROCESS_MODE_ALWAYS) {
return true;
}
if (p_paused) {
return process_mode == PROCESS_MODE_WHEN_PAUSED;
} else {
return process_mode == PROCESS_MODE_PAUSABLE;
}
}
float Node::get_physics_process_delta_time() const {
@ -1898,15 +1938,11 @@ String Node::get_filename() const {
}
void Node::set_editor_description(const String &p_editor_description) {
set_meta("_editor_description_", p_editor_description);
data.editor_description = p_editor_description;
}
String Node::get_editor_description() const {
if (has_meta("_editor_description_")) {
return get_meta("_editor_description_");
} else {
return "";
}
return data.editor_description;
}
void Node::set_editable_instance(Node *p_node, bool p_editable) {
@ -2783,8 +2819,8 @@ void Node::_bind_methods() {
ClassDB::bind_method(D_METHOD("is_processing_unhandled_input"), &Node::is_processing_unhandled_input);
ClassDB::bind_method(D_METHOD("set_process_unhandled_key_input", "enable"), &Node::set_process_unhandled_key_input);
ClassDB::bind_method(D_METHOD("is_processing_unhandled_key_input"), &Node::is_processing_unhandled_key_input);
ClassDB::bind_method(D_METHOD("set_pause_mode", "mode"), &Node::set_pause_mode);
ClassDB::bind_method(D_METHOD("get_pause_mode"), &Node::get_pause_mode);
ClassDB::bind_method(D_METHOD("set_process_mode", "mode"), &Node::set_process_mode);
ClassDB::bind_method(D_METHOD("get_process_mode"), &Node::get_process_mode);
ClassDB::bind_method(D_METHOD("can_process"), &Node::can_process);
ClassDB::bind_method(D_METHOD("print_stray_nodes"), &Node::_print_stray_nodes);
@ -2822,12 +2858,12 @@ void Node::_bind_methods() {
ClassDB::bind_method(D_METHOD("rpc_config", "method", "mode"), &Node::rpc_config);
ClassDB::bind_method(D_METHOD("rset_config", "property", "mode"), &Node::rset_config);
ClassDB::bind_method(D_METHOD("_set_editor_description", "editor_description"), &Node::set_editor_description);
ClassDB::bind_method(D_METHOD("_get_editor_description"), &Node::get_editor_description);
ADD_PROPERTY(PropertyInfo(Variant::STRING, "editor_description", PROPERTY_HINT_MULTILINE_TEXT, "", PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_editor_description", "_get_editor_description");
ClassDB::bind_method(D_METHOD("set_editor_description", "editor_description"), &Node::set_editor_description);
ClassDB::bind_method(D_METHOD("get_editor_description"), &Node::get_editor_description);
ClassDB::bind_method(D_METHOD("_set_import_path", "import_path"), &Node::set_import_path);
ClassDB::bind_method(D_METHOD("_get_import_path"), &Node::get_import_path);
ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "_import_path", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_import_path", "_get_import_path");
{
@ -2891,9 +2927,11 @@ void Node::_bind_methods() {
BIND_CONSTANT(NOTIFICATION_APPLICATION_FOCUS_OUT);
BIND_CONSTANT(NOTIFICATION_TEXT_SERVER_CHANGED);
BIND_ENUM_CONSTANT(PAUSE_MODE_INHERIT);
BIND_ENUM_CONSTANT(PAUSE_MODE_STOP);
BIND_ENUM_CONSTANT(PAUSE_MODE_PROCESS);
BIND_ENUM_CONSTANT(PROCESS_MODE_INHERIT);
BIND_ENUM_CONSTANT(PROCESS_MODE_PAUSABLE);
BIND_ENUM_CONSTANT(PROCESS_MODE_WHEN_PAUSED);
BIND_ENUM_CONSTANT(PROCESS_MODE_ALWAYS);
BIND_ENUM_CONSTANT(PROCESS_MODE_DISABLED);
BIND_ENUM_CONSTANT(DUPLICATE_SIGNALS);
BIND_ENUM_CONSTANT(DUPLICATE_GROUPS);
@ -2906,15 +2944,19 @@ void Node::_bind_methods() {
ADD_SIGNAL(MethodInfo("tree_exiting"));
ADD_SIGNAL(MethodInfo("tree_exited"));
ADD_PROPERTY(PropertyInfo(Variant::INT, "pause_mode", PROPERTY_HINT_ENUM, "Inherit,Stop,Process"), "set_pause_mode", "get_pause_mode");
ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "name", PROPERTY_HINT_NONE, "", 0), "set_name", "get_name");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "filename", PROPERTY_HINT_NONE, "", 0), "set_filename", "get_filename");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "owner", PROPERTY_HINT_RESOURCE_TYPE, "Node", 0), "set_owner", "get_owner");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "multiplayer", PROPERTY_HINT_RESOURCE_TYPE, "MultiplayerAPI", 0), "", "get_multiplayer");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "custom_multiplayer", PROPERTY_HINT_RESOURCE_TYPE, "MultiplayerAPI", 0), "set_custom_multiplayer", "get_custom_multiplayer");
ADD_GROUP("Process", "process_");
ADD_PROPERTY(PropertyInfo(Variant::INT, "process_mode", PROPERTY_HINT_ENUM, "Inherit,Pausable,WhenPaused,Always,Disabled"), "set_process_mode", "get_process_mode");
ADD_PROPERTY(PropertyInfo(Variant::INT, "process_priority"), "set_process_priority", "get_process_priority");
ADD_GROUP("Editor Description", "editor_");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "editor_description", PROPERTY_HINT_MULTILINE_TEXT, "", PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_INTERNAL), "set_editor_description", "get_editor_description");
BIND_VMETHOD(MethodInfo("_process", PropertyInfo(Variant::FLOAT, "delta")));
BIND_VMETHOD(MethodInfo("_physics_process", PropertyInfo(Variant::FLOAT, "delta")));
BIND_VMETHOD(MethodInfo("_enter_tree"));

View file

@ -46,10 +46,12 @@ class Node : public Object {
OBJ_CATEGORY("Nodes");
public:
enum PauseMode {
PAUSE_MODE_INHERIT,
PAUSE_MODE_STOP,
PAUSE_MODE_PROCESS
enum ProcessMode {
PROCESS_MODE_INHERIT, // same as parent node
PROCESS_MODE_PAUSABLE, // process only if not paused
PROCESS_MODE_WHEN_PAUSED, // process only if paused
PROCESS_MODE_ALWAYS, // process always
PROCESS_MODE_DISABLED, // never process
};
enum DuplicateFlags {
@ -102,6 +104,7 @@ private:
#ifdef TOOLS_ENABLED
NodePath import_path; // Path used when imported, used by scene editors to keep tracking.
#endif
String editor_description;
Viewport *viewport = nullptr;
@ -109,8 +112,8 @@ private:
List<Node *>::Element *OW = nullptr; // Owned element.
List<Node *> owned;
PauseMode pause_mode = PAUSE_MODE_INHERIT;
Node *pause_owner = nullptr;
ProcessMode process_mode = PROCESS_MODE_INHERIT;
Node *process_owner = nullptr;
int network_master = 1; // Server by default.
Vector<NetData> rpc_methods;
@ -166,7 +169,7 @@ private:
void _propagate_after_exit_tree();
void _propagate_validate_owner();
void _print_stray_nodes();
void _propagate_pause_owner(Node *p_owner);
void _propagate_process_owner(Node *p_owner, int p_notification);
Array _get_node_and_resource(const NodePath &p_path);
void _duplicate_signals(const Node *p_original, Node *p_copy) const;
@ -184,6 +187,9 @@ private:
friend class SceneTree;
void _set_tree(SceneTree *p_tree);
void _propagate_pause_notification(bool p_enable);
_FORCE_INLINE_ bool _can_process(bool p_paused) const;
#ifdef TOOLS_ENABLED
friend class SceneTreeEditor;
@ -381,8 +387,8 @@ public:
void replace_by(Node *p_node, bool p_keep_data = false);
void set_pause_mode(PauseMode p_mode);
PauseMode get_pause_mode() const;
void set_process_mode(ProcessMode p_mode);
ProcessMode get_process_mode() const;
bool can_process() const;
bool can_process_notification(int p_what) const;

View file

@ -767,7 +767,7 @@ void SceneTree::set_pause(bool p_enabled) {
PhysicsServer3D::get_singleton()->set_active(!p_enabled);
PhysicsServer2D::get_singleton()->set_active(!p_enabled);
if (get_root()) {
get_root()->propagate_notification(p_enabled ? Node::NOTIFICATION_PAUSED : Node::NOTIFICATION_UNPAUSED);
get_root()->_propagate_pause_notification(p_enabled);
}
}
@ -1254,6 +1254,7 @@ void SceneTree::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "multiplayer_poll"), "set_multiplayer_poll_enabled", "is_multiplayer_poll_enabled");
ADD_SIGNAL(MethodInfo("tree_changed"));
ADD_SIGNAL(MethodInfo("tree_process_mode_changed")); //editor only signal, but due to API hash it cant be removed in run-time
ADD_SIGNAL(MethodInfo("node_added", PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_RESOURCE_TYPE, "Node")));
ADD_SIGNAL(MethodInfo("node_removed", PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_RESOURCE_TYPE, "Node")));
ADD_SIGNAL(MethodInfo("node_renamed", PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_RESOURCE_TYPE, "Node")));