Repository: godotengine/godot
File: scene/animation/animation_player.cpp (C++)

Code before:
			max_dur = MAX(max_dur, p_from_end ? current_pos - anim->track_get_key_time(i, anim->track_get_key_count(i) - 1) : anim->track_get_key_time(i, 0) - current_pos);
		}
		p_duration = max_dur;
	}
	if (Math::is_zero_approx(p_duration)) {
		return;
	}
	capture(name, p_duration, p_trans_type, p_ease_type);
}

void AnimationPlayer::play_with_capture(const StringName &p_name, double p_duration, double p_custom_blend, float p_custom_scale, bool p_from_end, Tween::TransitionType p_trans_type, Tween::EaseType p_ease_type) {
	_capture(p_name, p_from_end, p_duration, p_trans_type, p_ease_type);
	_play(p_name, p_custom_blend, p_custom_scale, p_from_end);
}

bool AnimationPlayer::is_playing() const {
	return playing;
}

void AnimationPlayer::set_current_animation(const StringName &p_animation) {
	if (p_animation == SNAME("[stop]") || p_animation.is_empty()) {
		// It should be call deferred and handled only when is_playing() == true to prevent infinite loops caused by seeking within stop().
		// Especially when the key current_animation = "[stop]" is placed at the beginning of an animation,
		// this line is called when the animation changes, so is_playing() == true must be checked.
		if (is_playing()) {
			callable_mp(this, &AnimationPlayer::stop).bind(false).call_deferred();
		}
	} else if (!is_playing()) {
		play(p_animation);
	} else if (playback.assigned != p_animation) {
		float speed = playback.current.speed_scale;
		play(p_animation, -1.0, speed, std::signbit(speed));
	} else {
		// Same animation, do not replay from start.
	}
}

StringName AnimationPlayer::get_current_animation() const {
	return (is_playing() ? playback.assigned : StringName());
}

void AnimationPlayer::set_assigned_animation(const StringName &p_animation) {
	if (is_playing()) {
		float speed = playback.current.speed_scale;
		play(p_animation, -1.0, speed, std::signbit(speed));
	} 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.is_enabled = true;
		playback.current.animation_name = p_animation;
		playback.current.animation_length = animation_set[p_animation].animation->get_length();

Review comment (suggestion):
```suggestion
			callable_mp(this, &AnimationPlayer::stop).call_deferred(false);
```

Code after:
			max_dur = MAX(max_dur, p_from_end ? current_pos - anim->track_get_key_time(i, anim->track_get_key_count(i) - 1) : anim->track_get_key_time(i, 0) - current_pos);
		}
		p_duration = max_dur;
	}
	if (Math::is_zero_approx(p_duration)) {
		return;
	}
	capture(name, p_duration, p_trans_type, p_ease_type);
}

void AnimationPlayer::play_with_capture(const StringName &p_name, double p_duration, double p_custom_blend, float p_custom_scale, bool p_from_end, Tween::TransitionType p_trans_type, Tween::EaseType p_ease_type) {
	_capture(p_name, p_from_end, p_duration, p_trans_type, p_ease_type);
	_play(p_name, p_custom_blend, p_custom_scale, p_from_end);
}

bool AnimationPlayer::is_playing() const {
	return playing;
}

void AnimationPlayer::set_current_animation(const StringName &p_animation) {
	if (p_animation == SNAME("[stop]") || p_animation.is_empty()) {
		// It should be call deferred and handled only when is_playing() == true to prevent infinite loops caused by seeking within stop().
		// Especially when the key current_animation = "[stop]" is placed at the beginning of an animation,
		// this line is called when the animation changes, so is_playing() == true must be checked.
		if (is_playing()) {
			callable_mp(this, &AnimationPlayer::stop).call_deferred(false);
		}
	} else if (!is_playing()) {
		play(p_animation);
	} else if (playback.assigned != p_animation) {
		float speed = playback.current.speed_scale;
		play(p_animation, -1.0, speed, std::signbit(speed));
	} else {
		// Same animation, do not replay from start.
	}
}

StringName AnimationPlayer::get_current_animation() const {
	return (is_playing() ? playback.assigned : StringName());
}

void AnimationPlayer::set_assigned_animation(const StringName &p_animation) {
	if (is_playing()) {
		float speed = playback.current.speed_scale;
		play(p_animation, -1.0, speed, std::signbit(speed));
	} 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.is_enabled = true;
		playback.current.animation_name = p_animation;
		playback.current.animation_length = animation_set[p_animation].animation->get_length();