Merge pull request #60671 from KoBeWi/infiniten't

Improve Tween infinite loop detection
This commit is contained in:
Rémi Verschelde 2022-05-01 01:21:59 +02:00 committed by GitHub
commit 4a9e8b560a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 18 additions and 10 deletions

View File

@ -278,14 +278,15 @@ bool Tween::step(float p_delta) {
bool step_active = false; bool step_active = false;
total_time += rem_delta; total_time += rem_delta;
#ifdef DEBUG_ENABLED
float initial_delta = rem_delta;
bool potential_infinite = false;
#endif
while (rem_delta > 0 && running) { while (rem_delta > 0 && running) {
float step_delta = rem_delta; float step_delta = rem_delta;
step_active = false; step_active = false;
#ifdef DEBUG_ENABLED
float prev_delta = rem_delta;
#endif
for (Ref<Tweener> &tweener : tweeners.write[current_step]) { for (Ref<Tweener> &tweener : tweeners.write[current_step]) {
// Modified inside Tweener.step(). // Modified inside Tweener.step().
float temp_delta = rem_delta; float temp_delta = rem_delta;
@ -310,17 +311,21 @@ bool Tween::step(float p_delta) {
emit_signal(SNAME("loop_finished"), loops_done); emit_signal(SNAME("loop_finished"), loops_done);
current_step = 0; current_step = 0;
start_tweeners(); start_tweeners();
#ifdef DEBUG_ENABLED
if (loops <= 0 && Math::is_equal_approx(rem_delta, initial_delta)) {
if (!potential_infinite) {
potential_infinite = true;
} else {
// Looped twice without using any time, this is 100% certain infinite loop.
ERR_FAIL_V_MSG(false, "Infinite loop detected. Check set_loops() description for more info.");
}
}
#endif
} }
} else { } else {
start_tweeners(); start_tweeners();
} }
} }
#ifdef DEBUG_ENABLED
if (Math::is_equal_approx(rem_delta, prev_delta) && running && loops <= 0) {
ERR_FAIL_V_MSG(false, "Infinite loop detected. Check set_loops() description for more info.");
}
#endif
} }
return true; return true;

View File

@ -116,6 +116,9 @@ private:
bool valid = false; bool valid = false;
bool default_parallel = false; bool default_parallel = false;
bool parallel_enabled = false; bool parallel_enabled = false;
#ifdef DEBUG_ENABLED
bool is_infinite = false;
#endif
typedef real_t (*interpolater)(real_t t, real_t b, real_t c, real_t d); typedef real_t (*interpolater)(real_t t, real_t b, real_t c, real_t d);
static interpolater interpolaters[TRANS_MAX][EASE_MAX]; static interpolater interpolaters[TRANS_MAX][EASE_MAX];