1
0
mirror of https://github.com/godotengine/godot.git synced 2025-12-01 16:38:31 +00:00

Merge pull request #113187 from TokageItLab/anim-map-revert

Revert: Fix AHashMap realloc cause AnimationPlayer crash
This commit is contained in:
Rémi Verschelde
2025-11-26 23:44:27 +01:00
2 changed files with 38 additions and 44 deletions

View File

@@ -164,11 +164,10 @@ void AnimationPlayer::_process_playback_data(PlaybackData &cd, double p_delta, f
double start = cd.get_start_time();
double end = cd.get_end_time();
AnimationData *p_from = &animation_set[cd.animation_name];
Animation::LoopedFlag looped_flag = Animation::LOOPED_FLAG_NONE;
switch (p_from->animation->get_loop_mode()) {
switch (cd.from->animation->get_loop_mode()) {
case Animation::LOOP_NONE: {
if (Animation::is_less_approx(next_pos, start)) {
next_pos = start;
@@ -208,7 +207,7 @@ void AnimationPlayer::_process_playback_data(PlaybackData &cd, double p_delta, f
// End detection.
if (p_is_current) {
if (p_from->animation->get_loop_mode() == Animation::LOOP_NONE) {
if (cd.from->animation->get_loop_mode() == Animation::LOOP_NONE) {
if (!backwards && Animation::is_less_or_equal_approx(prev_pos, end) && Math::is_equal_approx(next_pos, end)) {
// Playback finished.
next_pos = end; // Snap to the edge.
@@ -249,7 +248,7 @@ void AnimationPlayer::_process_playback_data(PlaybackData &cd, double p_delta, f
pi.is_external_seeking = !p_internal_seeked && !p_started;
pi.looped_flag = looped_flag;
pi.weight = p_blend;
make_animation_instance(cd.animation_name, pi);
make_animation_instance(cd.from->name, pi);
}
float AnimationPlayer::get_current_blend_amount() {
@@ -301,13 +300,12 @@ void AnimationPlayer::_blend_playback_data(double p_delta, bool p_started) {
}
bool AnimationPlayer::_blend_pre_process(double p_delta, int p_track_count, const AHashMap<NodePath, int> &p_track_map) {
if (playback.current.animation_name.is_empty()) {
if (!playback.current.from) {
_set_process(false);
return false;
}
AnimationData *p_from = &animation_set[playback.current.animation_name];
tmp_from = p_from->animation->get_instance_id();
tmp_from = playback.current.from->animation->get_instance_id();
end_reached = false;
end_notify = false;
@@ -318,10 +316,10 @@ bool AnimationPlayer::_blend_pre_process(double p_delta, int p_track_count, cons
playback.started = false;
}
String prev_animation_name = playback.current.animation_name;
AnimationData *prev_from = playback.current.from;
_blend_playback_data(p_delta, started);
if (prev_animation_name != playback.current.animation_name) {
if (prev_from != playback.current.from) {
return false; // Animation has been changed in the process (may be caused by method track), abort process.
}
@@ -335,7 +333,7 @@ void AnimationPlayer::_blend_capture(double p_delta) {
void AnimationPlayer::_blend_post_process() {
if (end_reached) {
// If the method track changes current animation, the animation is not finished.
if (tmp_from == animation_set[playback.current.animation_name].animation->get_instance_id()) {
if (tmp_from == playback.current.from->animation->get_instance_id()) {
if (playback_queue.size()) {
if (!finished_anim.is_empty()) {
emit_signal(SceneStringName(animation_finished), finished_anim);
@@ -435,10 +433,10 @@ void AnimationPlayer::play_section_with_markers(const StringName &p_name, const
ERR_FAIL_COND_MSG(p_start_marker && p_end_marker && Animation::is_greater_approx(start_time, end_time), vformat("End marker %s is placed earlier than start marker %s in animation: %s.", p_end_marker, p_start_marker, name));
if (p_start_marker && Animation::is_less_approx(start_time, 0)) {
WARN_PRINT_ED(vformat("Negative time start marker: %s is invalid in the section, so the start of the animation: %s is used instead.", p_start_marker, playback.current.animation_name));
WARN_PRINT_ED(vformat("Negative time start marker: %s is invalid in the section, so the start of the animation: %s is used instead.", p_start_marker, playback.current.from->animation->get_name()));
}
if (p_end_marker && Animation::is_less_approx(end_time, 0)) {
WARN_PRINT_ED(vformat("Negative time end marker: %s is invalid in the section, so the end of the animation: %s is used instead.", p_end_marker, playback.current.animation_name));
WARN_PRINT_ED(vformat("Negative time end marker: %s is invalid in the section, so the end of the animation: %s is used instead.", p_end_marker, playback.current.from->animation->get_name()));
}
play_section(name, start_time, end_time, p_custom_blend, p_custom_scale, p_from_end);
@@ -457,11 +455,11 @@ void AnimationPlayer::play_section(const StringName &p_name, double p_start_time
Playback &c = playback;
if (!c.current.animation_name.is_empty()) {
if (c.current.from) {
double blend_time = 0.0;
// Find if it can blend.
BlendKey bk;
bk.from = c.current.animation_name;
bk.from = c.current.from->name;
bk.to = name;
if (Animation::is_greater_or_equal_approx(p_custom_blend, 0)) {
@@ -473,7 +471,7 @@ void AnimationPlayer::play_section(const StringName &p_name, double p_start_time
if (blend_times.has(bk)) {
blend_time = blend_times[bk];
} else {
bk.from = c.current.animation_name;
bk.from = c.current.from->name;
bk.to = "*";
if (blend_times.has(bk)) {
@@ -500,8 +498,7 @@ void AnimationPlayer::play_section(const StringName &p_name, double p_start_time
_clear_playing_caches();
}
c.current.animation_name = name;
c.current.animation_length = animation_set[name].animation->get_length();
c.current.from = &animation_set[name];
c.current.speed_scale = p_custom_scale;
c.current.start_time = p_start_time;
c.current.end_time = p_end_time;
@@ -616,8 +613,7 @@ void AnimationPlayer::set_assigned_animation(const StringName &p_animation) {
} else {
ERR_FAIL_COND_MSG(!animation_set.has(p_animation), vformat("Animation not found: %s.", p_animation.operator String()));
playback.current.pos = 0;
playback.current.animation_name = p_animation;
playback.current.animation_length = animation_set[p_animation].animation->get_length();
playback.current.from = &animation_set[p_animation];
playback.current.start_time = -1;
playback.current.end_time = -1;
playback.assigned = p_animation;
@@ -662,13 +658,12 @@ void AnimationPlayer::seek_internal(double p_time, bool p_update, bool p_update_
_check_immediately_after_start();
playback.current.pos = p_time;
if (!playback.current.animation_name.is_empty()) {
if (!playback.current.from) {
if (playback.assigned) {
ERR_FAIL_COND_MSG(!animation_set.has(playback.assigned), vformat("Animation not found: %s.", playback.assigned));
playback.current.animation_name = playback.assigned;
playback.current.animation_length = animation_set[playback.assigned].animation->get_length();
playback.current.from = &animation_set[playback.assigned];
}
if (!playback.current.animation_name.is_empty()) {
if (!playback.current.from) {
return; // There is no animation.
}
}
@@ -704,37 +699,37 @@ void AnimationPlayer::_check_immediately_after_start() {
}
bool AnimationPlayer::is_valid() const {
return (!playback.current.animation_name.is_empty());
return (playback.current.from);
}
double AnimationPlayer::get_current_animation_position() const {
ERR_FAIL_COND_V_MSG(!playback.current.animation_name.is_empty(), 0, "AnimationPlayer has no current animation.");
ERR_FAIL_NULL_V_MSG(playback.current.from, 0, "AnimationPlayer has no current animation.");
return playback.current.pos;
}
double AnimationPlayer::get_current_animation_length() const {
ERR_FAIL_COND_V_MSG(!playback.current.animation_name.is_empty(), 0, "AnimationPlayer has no current animation.");
return playback.current.animation_length;
ERR_FAIL_NULL_V_MSG(playback.current.from, 0, "AnimationPlayer has no current animation.");
return playback.current.from->animation->get_length();
}
void AnimationPlayer::set_section_with_markers(const StringName &p_start_marker, const StringName &p_end_marker) {
ERR_FAIL_COND_MSG(!playback.current.animation_name.is_empty(), "AnimationPlayer has no current animation.");
ERR_FAIL_NULL_MSG(playback.current.from, "AnimationPlayer has no current animation.");
ERR_FAIL_COND_MSG(p_start_marker == p_end_marker && p_start_marker, vformat("Start marker and end marker cannot be the same marker: %s.", p_start_marker));
ERR_FAIL_COND_MSG(p_start_marker && !animation_set[playback.current.animation_name].animation->has_marker(p_start_marker), vformat("Marker %s not found in animation: %s.", p_start_marker, playback.current.animation_name));
ERR_FAIL_COND_MSG(p_end_marker && !animation_set[playback.current.animation_name].animation->has_marker(p_end_marker), vformat("Marker %s not found in animation: %s.", p_end_marker, playback.current.animation_name));
double start_time = p_start_marker ? animation_set[playback.current.animation_name].animation->get_marker_time(p_start_marker) : -1;
double end_time = p_end_marker ? animation_set[playback.current.animation_name].animation->get_marker_time(p_end_marker) : -1;
ERR_FAIL_COND_MSG(p_start_marker && !playback.current.from->animation->has_marker(p_start_marker), vformat("Marker %s not found in animation: %s.", p_start_marker, playback.current.from->animation->get_name()));
ERR_FAIL_COND_MSG(p_end_marker && !playback.current.from->animation->has_marker(p_end_marker), vformat("Marker %s not found in animation: %s.", p_end_marker, playback.current.from->animation->get_name()));
double start_time = p_start_marker ? playback.current.from->animation->get_marker_time(p_start_marker) : -1;
double end_time = p_end_marker ? playback.current.from->animation->get_marker_time(p_end_marker) : -1;
if (p_start_marker && Animation::is_less_approx(start_time, 0)) {
WARN_PRINT_ONCE_ED(vformat("Marker %s time must be positive in animation: %s.", p_start_marker, playback.current.animation_name));
WARN_PRINT_ONCE_ED(vformat("Marker %s time must be positive in animation: %s.", p_start_marker, playback.current.from->animation->get_name()));
}
if (p_end_marker && Animation::is_less_approx(end_time, 0)) {
WARN_PRINT_ONCE_ED(vformat("Marker %s time must be positive in animation: %s.", p_end_marker, playback.current.animation_name));
WARN_PRINT_ONCE_ED(vformat("Marker %s time must be positive in animation: %s.", p_end_marker, playback.current.from->animation->get_name()));
}
set_section(start_time, end_time);
}
void AnimationPlayer::set_section(double p_start_time, double p_end_time) {
ERR_FAIL_COND_MSG(!playback.current.animation_name.is_empty(), "AnimationPlayer has no current animation.");
ERR_FAIL_NULL_MSG(playback.current.from, "AnimationPlayer has no current animation.");
ERR_FAIL_COND_MSG(Animation::is_greater_or_equal_approx(p_start_time, 0) && Animation::is_greater_or_equal_approx(p_end_time, 0) && Animation::is_greater_or_equal_approx(p_start_time, p_end_time), vformat("Start time %f is greater than end time %f.", p_start_time, p_end_time));
playback.current.start_time = p_start_time;
playback.current.end_time = p_end_time;
@@ -747,12 +742,12 @@ void AnimationPlayer::reset_section() {
}
double AnimationPlayer::get_section_start_time() const {
ERR_FAIL_COND_V_MSG(!playback.current.animation_name.is_empty(), playback.current.start_time, "AnimationPlayer has no current animation.");
ERR_FAIL_NULL_V_MSG(playback.current.from, playback.current.start_time, "AnimationPlayer has no current animation.");
return playback.current.get_start_time();
}
double AnimationPlayer::get_section_end_time() const {
ERR_FAIL_COND_V_MSG(!playback.current.animation_name.is_empty(), playback.current.end_time, "AnimationPlayer has no current animation.");
ERR_FAIL_NULL_V_MSG(playback.current.from, playback.current.end_time, "AnimationPlayer has no current animation.");
return playback.current.get_end_time();
}
@@ -784,7 +779,7 @@ void AnimationPlayer::_stop_internal(bool p_reset, bool p_keep_state) {
_clear_caches();
Playback &c = playback;
// c.blend.clear();
double start = (!c.current.animation_name.is_empty()) ? playback.current.get_start_time() : 0;
double start = c.current.from ? playback.current.get_start_time() : 0;
if (p_reset) {
c.blend.clear();
if (p_keep_state) {
@@ -794,7 +789,7 @@ void AnimationPlayer::_stop_internal(bool p_reset, bool p_keep_state) {
seek_internal(start, true, true, true);
is_stopping = false;
}
c.current.animation_name = String();
c.current.from = nullptr;
c.current.speed_scale = 1;
emit_signal(SNAME("current_animation_changed"), "");
}

View File

@@ -65,21 +65,20 @@ private:
bool is_stopping = false;
struct PlaybackData {
String animation_name;
int animation_length = 0;
AnimationData *from = nullptr;
double pos = 0.0;
float speed_scale = 1.0;
double start_time = 0.0;
double end_time = 0.0;
double get_start_time() const {
if ((!animation_name.is_empty()) && (Animation::is_less_approx(start_time, 0) || Animation::is_greater_approx(start_time, animation_length))) {
if (from && (Animation::is_less_approx(start_time, 0) || Animation::is_greater_approx(start_time, from->animation->get_length()))) {
return 0;
}
return start_time;
}
double get_end_time() const {
if ((!animation_name.is_empty()) && (Animation::is_less_approx(end_time, 0) || Animation::is_greater_approx(end_time, animation_length))) {
return animation_length;
if (from && (Animation::is_less_approx(end_time, 0) || Animation::is_greater_approx(end_time, from->animation->get_length()))) {
return from->animation->get_length();
}
return end_time;
}