From 1180110b9ed488c0f8efc6c9f98a55fd6f4aead1 Mon Sep 17 00:00:00 2001 From: Ben Rog-Wilhelm Date: Sat, 8 Dec 2018 10:56:20 -0800 Subject: [PATCH] Implement AnimationPlayer call modes as per #23498. --- doc/classes/AnimationPlayer.xml | 9 ++++++ scene/animation/animation_player.cpp | 44 +++++++++++++++++++++++----- scene/animation/animation_player.h | 10 +++++++ 3 files changed, 55 insertions(+), 8 deletions(-) diff --git a/doc/classes/AnimationPlayer.xml b/doc/classes/AnimationPlayer.xml index 499da4b8a3..4a030c258d 100644 --- a/doc/classes/AnimationPlayer.xml +++ b/doc/classes/AnimationPlayer.xml @@ -237,6 +237,9 @@ The position (in seconds) of the currently playing animation. + + The call mode to use for Call Method tracks. Default value: [code]ANIMATION_METHOD_CALL_DEFERRED[/code]. + If [code]true[/code], updates animations in response to process-related notifications. Default value: [code]true[/code]. @@ -292,5 +295,11 @@ Do not process animation. Use the 'advance' method to process the animation manually. + + Batch method calls during the animation process, then do the calls after events are processed. This avoids bugs involving deleting nodes or modifying the AnimationPlayer while playing. + + + Make method calls immediately when reached in the animation. + diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp index 7f9953ab43..5e3d44eb82 100644 --- a/scene/animation/animation_player.cpp +++ b/scene/animation/animation_player.cpp @@ -545,14 +545,24 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, float #endif if (can_call) { - MessageQueue::get_singleton()->push_call( - nc->node, - method, - s >= 1 ? params[0] : Variant(), - s >= 2 ? params[1] : Variant(), - s >= 3 ? params[2] : Variant(), - s >= 4 ? params[3] : Variant(), - s >= 5 ? params[4] : Variant()); + if (method_call_mode == ANIMATION_METHOD_CALL_DEFERRED) { + MessageQueue::get_singleton()->push_call( + nc->node, + method, + s >= 1 ? params[0] : Variant(), + s >= 2 ? params[1] : Variant(), + s >= 3 ? params[2] : Variant(), + s >= 4 ? params[3] : Variant(), + s >= 5 ? params[4] : Variant()); + } else { + nc->node->call( + method, + s >= 1 ? params[0] : Variant(), + s >= 2 ? params[1] : Variant(), + s >= 3 ? params[2] : Variant(), + s >= 4 ? params[3] : Variant(), + s >= 5 ? params[4] : Variant()); + } } } @@ -1454,6 +1464,16 @@ AnimationPlayer::AnimationProcessMode AnimationPlayer::get_animation_process_mod return animation_process_mode; } +void AnimationPlayer::set_method_call_mode(AnimationMethodCallMode p_mode) { + + method_call_mode = p_mode; +} + +AnimationPlayer::AnimationMethodCallMode AnimationPlayer::get_method_call_mode() const { + + return method_call_mode; +} + void AnimationPlayer::_set_process(bool p_process, bool p_force) { if (processing == p_process && !p_force) @@ -1635,6 +1655,9 @@ void AnimationPlayer::_bind_methods() { 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_method_call_mode", "mode"), &AnimationPlayer::set_method_call_mode); + ClassDB::bind_method(D_METHOD("get_method_call_mode"), &AnimationPlayer::get_method_call_mode); + ClassDB::bind_method(D_METHOD("get_current_animation_position"), &AnimationPlayer::get_current_animation_position); ClassDB::bind_method(D_METHOD("get_current_animation_length"), &AnimationPlayer::get_current_animation_length); @@ -1653,6 +1676,7 @@ void AnimationPlayer::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::REAL, "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::REAL, "playback_speed", PROPERTY_HINT_RANGE, "-64,64,0.01"), "set_speed_scale", "get_speed_scale"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "method_call_mode", PROPERTY_HINT_ENUM, "Deferred,Immediate"), "set_method_call_mode", "get_method_call_mode"); ADD_SIGNAL(MethodInfo("animation_finished", PropertyInfo(Variant::STRING, "anim_name"))); ADD_SIGNAL(MethodInfo("animation_changed", PropertyInfo(Variant::STRING, "old_name"), PropertyInfo(Variant::STRING, "new_name"))); @@ -1662,6 +1686,9 @@ void AnimationPlayer::_bind_methods() { BIND_ENUM_CONSTANT(ANIMATION_PROCESS_PHYSICS); BIND_ENUM_CONSTANT(ANIMATION_PROCESS_IDLE); BIND_ENUM_CONSTANT(ANIMATION_PROCESS_MANUAL); + + BIND_ENUM_CONSTANT(ANIMATION_METHOD_CALL_DEFERRED); + BIND_ENUM_CONSTANT(ANIMATION_METHOD_CALL_IMMEDIATE); } AnimationPlayer::AnimationPlayer() { @@ -1674,6 +1701,7 @@ AnimationPlayer::AnimationPlayer() { end_reached = false; end_notify = false; animation_process_mode = ANIMATION_PROCESS_IDLE; + method_call_mode = ANIMATION_METHOD_CALL_DEFERRED; processing = false; default_blend_time = 0; root = SceneStringNames::get_singleton()->path_pp; diff --git a/scene/animation/animation_player.h b/scene/animation/animation_player.h index b3bf8b1e22..c481efcb5e 100644 --- a/scene/animation/animation_player.h +++ b/scene/animation/animation_player.h @@ -68,6 +68,11 @@ public: ANIMATION_PROCESS_MANUAL, }; + enum AnimationMethodCallMode { + ANIMATION_METHOD_CALL_DEFERRED, + ANIMATION_METHOD_CALL_IMMEDIATE, + }; + private: enum { @@ -243,6 +248,7 @@ private: String autoplay; AnimationProcessMode animation_process_mode; + AnimationMethodCallMode method_call_mode; bool processing; bool active; @@ -335,6 +341,9 @@ public: void set_animation_process_mode(AnimationProcessMode p_mode); AnimationProcessMode get_animation_process_mode() const; + void set_method_call_mode(AnimationMethodCallMode p_mode); + AnimationMethodCallMode get_method_call_mode() const; + void seek(float p_time, bool p_update = false); void seek_delta(float p_time, float p_delta); float get_current_animation_position() const; @@ -360,5 +369,6 @@ public: }; VARIANT_ENUM_CAST(AnimationPlayer::AnimationProcessMode); +VARIANT_ENUM_CAST(AnimationPlayer::AnimationMethodCallMode); #endif