From 7dcefa7c1b66c8b16d8a7ef8fb07a7c5eabdcda1 Mon Sep 17 00:00:00 2001 From: Hugo Locurcio Date: Sat, 9 Oct 2021 11:36:03 +0200 Subject: [PATCH] Add a warning for Timer nodes with very low wait times Very low wait times behave in unpredictable ways depending on the rendered frame rate. This is because the timeout signal is only emitted once per rendered frame (or physics frame, depending on the timer's process mode). --- doc/classes/Timer.xml | 3 ++- scene/main/timer.cpp | 14 ++++++++++++++ scene/main/timer.h | 2 ++ 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/doc/classes/Timer.xml b/doc/classes/Timer.xml index bc5970bf148..ac7fe9daebc 100644 --- a/doc/classes/Timer.xml +++ b/doc/classes/Timer.xml @@ -51,7 +51,8 @@ [b]Note:[/b] You cannot set this value. To change the timer's remaining time, use [method start]. - Wait time in seconds. + The wait time in seconds. + [b]Note:[/b] Timers can only emit once per rendered frame at most (or once per physics frame if [member process_mode] is [constant TIMER_PROCESS_PHYSICS]). This means very low wait times (lower than 0.05 seconds) will behave in significantly different ways depending on the rendered framerate. For very low wait times, it is recommended to use a process loop in a script instead of using a Timer node. diff --git a/scene/main/timer.cpp b/scene/main/timer.cpp index 010c692df58..2be6fe6ea45 100644 --- a/scene/main/timer.cpp +++ b/scene/main/timer.cpp @@ -84,6 +84,7 @@ void Timer::_notification(int p_what) { void Timer::set_wait_time(float p_time) { ERR_FAIL_COND_MSG(p_time <= 0, "Time should be greater than zero."); wait_time = p_time; + update_configuration_warning(); } float Timer::get_wait_time() const { return wait_time; @@ -178,6 +179,19 @@ void Timer::_set_process(bool p_process, bool p_force) { processing = p_process; } +String Timer::get_configuration_warning() const { + String warning = Node::get_configuration_warning(); + + if (wait_time < 0.05 - CMP_EPSILON) { + if (warning != String()) { + warning += "\n\n"; + } + warning += TTR("Very low timer wait times (< 0.05 seconds) may behave in significantly different ways depending on the rendered or physics frame rate.\nConsider using a script's process loop instead of relying on a Timer for very low wait times."); + } + + return warning; +} + void Timer::_bind_methods() { ClassDB::bind_method(D_METHOD("set_wait_time", "time_sec"), &Timer::set_wait_time); ClassDB::bind_method(D_METHOD("get_wait_time"), &Timer::get_wait_time); diff --git a/scene/main/timer.h b/scene/main/timer.h index 0604a2d9906..84ada10a776 100644 --- a/scene/main/timer.h +++ b/scene/main/timer.h @@ -73,6 +73,8 @@ public: float get_time_left() const; + String get_configuration_warning() const; + void set_timer_process_mode(TimerProcessMode p_mode); TimerProcessMode get_timer_process_mode() const; Timer();