2023-01-05 20:25:55 +08:00
/**************************************************************************/
/* timer.cpp */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
2018-01-05 07:50:27 +08:00
2014-02-10 09:10:30 +08:00
# include "timer.h"
void Timer : : _notification ( int p_what ) {
2017-03-05 23:44:50 +08:00
switch ( p_what ) {
2014-02-10 09:10:30 +08:00
case NOTIFICATION_READY : {
2014-10-12 13:13:22 +08:00
if ( autostart ) {
2014-10-14 12:01:25 +08:00
# ifdef TOOLS_ENABLED
2023-03-17 08:58:30 +08:00
if ( is_part_of_edited_scene ( ) ) {
2014-10-12 13:13:22 +08:00
break ;
2020-05-14 22:41:43 +08:00
}
2014-12-07 13:04:20 +08:00
# endif
start ( ) ;
2017-03-05 23:44:50 +08:00
autostart = false ;
2014-10-12 13:13:22 +08:00
}
2014-02-10 09:10:30 +08:00
} break ;
2022-02-16 01:06:48 +08:00
2017-01-11 05:02:19 +08:00
case NOTIFICATION_INTERNAL_PROCESS : {
2021-02-19 20:35:31 +08:00
if ( ! processing | | timer_process_callback = = TIMER_PROCESS_PHYSICS | | ! is_processing_internal ( ) ) {
2015-05-01 22:44:02 +08:00
return ;
2020-05-14 22:41:43 +08:00
}
2014-02-10 09:10:30 +08:00
time_left - = get_process_delta_time ( ) ;
2017-03-05 23:44:50 +08:00
if ( time_left < 0 ) {
2020-05-14 22:41:43 +08:00
if ( ! one_shot ) {
2017-04-05 14:22:41 +08:00
time_left + = wait_time ;
2020-05-14 22:41:43 +08:00
} else {
2014-02-10 09:10:30 +08:00
stop ( ) ;
2020-05-14 22:41:43 +08:00
}
2014-02-10 09:10:30 +08:00
2021-07-18 05:22:52 +08:00
emit_signal ( SNAME ( " timeout " ) ) ;
2014-02-10 09:10:30 +08:00
}
} break ;
2022-02-16 01:06:48 +08:00
2017-09-30 22:19:07 +08:00
case NOTIFICATION_INTERNAL_PHYSICS_PROCESS : {
2021-02-19 20:35:31 +08:00
if ( ! processing | | timer_process_callback = = TIMER_PROCESS_IDLE | | ! is_physics_processing_internal ( ) ) {
2015-05-10 22:00:26 +08:00
return ;
2020-05-14 22:41:43 +08:00
}
2017-09-30 22:19:07 +08:00
time_left - = get_physics_process_delta_time ( ) ;
2015-05-10 22:00:26 +08:00
2017-03-05 23:44:50 +08:00
if ( time_left < 0 ) {
2020-05-14 22:41:43 +08:00
if ( ! one_shot ) {
2017-04-05 14:22:41 +08:00
time_left + = wait_time ;
2020-05-14 22:41:43 +08:00
} else {
2015-05-10 22:00:26 +08:00
stop ( ) ;
2020-05-14 22:41:43 +08:00
}
2021-07-18 05:22:52 +08:00
emit_signal ( SNAME ( " timeout " ) ) ;
2015-05-10 22:00:26 +08:00
}
} break ;
2014-02-10 09:10:30 +08:00
}
}
2021-05-21 13:23:35 +08:00
void Timer : : set_wait_time ( double p_time ) {
2019-08-09 04:11:48 +08:00
ERR_FAIL_COND_MSG ( p_time < = 0 , " Time should be greater than zero. " ) ;
2017-03-05 23:44:50 +08:00
wait_time = p_time ;
2021-10-09 14:57:48 +08:00
update_configuration_warnings ( ) ;
2014-02-10 09:10:30 +08:00
}
2020-05-14 20:29:06 +08:00
2021-05-21 13:23:35 +08:00
double Timer : : get_wait_time ( ) const {
2014-02-10 09:10:30 +08:00
return wait_time ;
}
void Timer : : set_one_shot ( bool p_one_shot ) {
2017-03-05 23:44:50 +08:00
one_shot = p_one_shot ;
2014-02-10 09:10:30 +08:00
}
2020-05-14 20:29:06 +08:00
2014-02-10 09:10:30 +08:00
bool Timer : : is_one_shot ( ) const {
return one_shot ;
}
void Timer : : set_autostart ( bool p_start ) {
2017-03-05 23:44:50 +08:00
autostart = p_start ;
2014-02-10 09:10:30 +08:00
}
2020-05-14 20:29:06 +08:00
2014-02-10 09:10:30 +08:00
bool Timer : : has_autostart ( ) const {
return autostart ;
}
2021-05-21 13:23:35 +08:00
void Timer : : start ( double p_time ) {
2019-11-27 23:34:54 +08:00
ERR_FAIL_COND_MSG ( ! is_inside_tree ( ) , " Timer was not added to the SceneTree. Either add it or set autostart to true. " ) ;
2019-09-01 07:25:22 +08:00
2018-04-27 03:42:50 +08:00
if ( p_time > 0 ) {
set_wait_time ( p_time ) ;
}
2017-03-05 23:44:50 +08:00
time_left = wait_time ;
2015-05-10 22:00:26 +08:00
_set_process ( true ) ;
2014-02-10 09:10:30 +08:00
}
void Timer : : stop ( ) {
2017-03-05 23:44:50 +08:00
time_left = - 1 ;
2015-05-10 22:00:26 +08:00
_set_process ( false ) ;
2017-03-05 23:44:50 +08:00
autostart = false ;
2014-02-10 09:10:30 +08:00
}
2017-03-12 01:10:01 +08:00
void Timer : : set_paused ( bool p_paused ) {
2020-05-14 22:41:43 +08:00
if ( paused = = p_paused ) {
2016-04-01 05:23:16 +08:00
return ;
2020-05-14 22:41:43 +08:00
}
2016-04-01 05:23:16 +08:00
2017-03-12 01:10:01 +08:00
paused = p_paused ;
2016-04-01 05:23:16 +08:00
_set_process ( processing ) ;
}
2017-03-12 01:10:01 +08:00
bool Timer : : is_paused ( ) const {
return paused ;
}
bool Timer : : is_stopped ( ) const {
return get_time_left ( ) < = 0 ;
2016-04-01 05:23:16 +08:00
}
2021-05-21 13:23:35 +08:00
double Timer : : get_time_left ( ) const {
2017-03-05 23:44:50 +08:00
return time_left > 0 ? time_left : 0 ;
2014-02-10 09:10:30 +08:00
}
2021-02-19 20:35:31 +08:00
void Timer : : set_timer_process_callback ( TimerProcessCallback p_callback ) {
if ( timer_process_callback = = p_callback ) {
2015-05-10 22:00:26 +08:00
return ;
2020-05-14 22:41:43 +08:00
}
2015-05-10 22:00:26 +08:00
2021-02-19 20:35:31 +08:00
switch ( timer_process_callback ) {
2017-09-30 22:19:07 +08:00
case TIMER_PROCESS_PHYSICS :
if ( is_physics_processing_internal ( ) ) {
set_physics_process_internal ( false ) ;
2017-01-11 05:02:19 +08:00
set_process_internal ( true ) ;
2015-05-10 22:00:26 +08:00
}
2017-03-05 23:44:50 +08:00
break ;
2015-05-10 22:00:26 +08:00
case TIMER_PROCESS_IDLE :
2017-01-11 05:02:19 +08:00
if ( is_processing_internal ( ) ) {
set_process_internal ( false ) ;
2017-09-30 22:19:07 +08:00
set_physics_process_internal ( true ) ;
2015-05-10 22:00:26 +08:00
}
2017-03-05 23:44:50 +08:00
break ;
2015-05-10 22:00:26 +08:00
}
2021-02-19 20:35:31 +08:00
timer_process_callback = p_callback ;
2015-05-10 22:00:26 +08:00
}
2021-02-19 20:35:31 +08:00
Timer : : TimerProcessCallback Timer : : get_timer_process_callback ( ) const {
return timer_process_callback ;
2015-05-10 22:00:26 +08:00
}
2017-03-05 23:44:50 +08:00
void Timer : : _set_process ( bool p_process , bool p_force ) {
2021-02-19 20:35:31 +08:00
switch ( timer_process_callback ) {
2020-05-10 19:00:47 +08:00
case TIMER_PROCESS_PHYSICS :
set_physics_process_internal ( p_process & & ! paused ) ;
break ;
case TIMER_PROCESS_IDLE :
set_process_internal ( p_process & & ! paused ) ;
break ;
2015-05-10 22:00:26 +08:00
}
2016-04-01 05:23:16 +08:00
processing = p_process ;
2015-05-10 22:00:26 +08:00
}
2014-02-10 09:10:30 +08:00
2024-02-18 02:03:21 +08:00
PackedStringArray Timer : : get_configuration_warnings ( ) const {
PackedStringArray warnings = Node : : get_configuration_warnings ( ) ;
2021-10-09 14:57:48 +08:00
if ( wait_time < 0.05 - CMP_EPSILON ) {
2022-03-28 21:24:14 +08:00
warnings . push_back ( RTR ( " Very low timer wait times (< 0.05 seconds) may behave in significantly different ways depending on the rendered or physics frame rate. \n Consider using a script's process loop instead of relying on a Timer for very low wait times. " ) ) ;
2021-10-09 14:57:48 +08:00
}
return warnings ;
}
2014-02-10 09:10:30 +08:00
void Timer : : _bind_methods ( ) {
2017-03-05 23:44:50 +08:00
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 ) ;
2014-02-10 09:10:30 +08:00
2017-03-05 23:44:50 +08:00
ClassDB : : bind_method ( D_METHOD ( " set_one_shot " , " enable " ) , & Timer : : set_one_shot ) ;
ClassDB : : bind_method ( D_METHOD ( " is_one_shot " ) , & Timer : : is_one_shot ) ;
2014-02-10 09:10:30 +08:00
2017-03-05 23:44:50 +08:00
ClassDB : : bind_method ( D_METHOD ( " set_autostart " , " enable " ) , & Timer : : set_autostart ) ;
ClassDB : : bind_method ( D_METHOD ( " has_autostart " ) , & Timer : : has_autostart ) ;
2014-02-10 09:10:30 +08:00
2018-04-27 03:42:50 +08:00
ClassDB : : bind_method ( D_METHOD ( " start " , " time_sec " ) , & Timer : : start , DEFVAL ( - 1 ) ) ;
2017-03-05 23:44:50 +08:00
ClassDB : : bind_method ( D_METHOD ( " stop " ) , & Timer : : stop ) ;
2014-02-10 09:10:30 +08:00
2017-03-12 01:10:01 +08:00
ClassDB : : bind_method ( D_METHOD ( " set_paused " , " paused " ) , & Timer : : set_paused ) ;
ClassDB : : bind_method ( D_METHOD ( " is_paused " ) , & Timer : : is_paused ) ;
ClassDB : : bind_method ( D_METHOD ( " is_stopped " ) , & Timer : : is_stopped ) ;
2016-04-01 05:23:16 +08:00
2017-03-05 23:44:50 +08:00
ClassDB : : bind_method ( D_METHOD ( " get_time_left " ) , & Timer : : get_time_left ) ;
2014-02-10 09:10:30 +08:00
2021-02-19 20:35:31 +08:00
ClassDB : : bind_method ( D_METHOD ( " set_timer_process_callback " , " callback " ) , & Timer : : set_timer_process_callback ) ;
ClassDB : : bind_method ( D_METHOD ( " get_timer_process_callback " ) , & Timer : : get_timer_process_callback ) ;
2015-05-10 22:00:26 +08:00
2017-03-05 23:44:50 +08:00
ADD_SIGNAL ( MethodInfo ( " timeout " ) ) ;
2014-02-10 09:10:30 +08:00
2021-02-19 20:35:31 +08:00
ADD_PROPERTY ( PropertyInfo ( Variant : : INT , " process_callback " , PROPERTY_HINT_ENUM , " Physics,Idle " ) , " set_timer_process_callback " , " get_timer_process_callback " ) ;
2021-12-03 08:09:19 +08:00
ADD_PROPERTY ( PropertyInfo ( Variant : : FLOAT , " wait_time " , PROPERTY_HINT_RANGE , " 0.001,4096,0.001,or_greater,exp,suffix:s " ) , " set_wait_time " , " get_wait_time " ) ;
2017-03-05 23:44:50 +08:00
ADD_PROPERTY ( PropertyInfo ( Variant : : BOOL , " one_shot " ) , " set_one_shot " , " is_one_shot " ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : BOOL , " autostart " ) , " set_autostart " , " has_autostart " ) ;
2021-06-18 07:10:18 +08:00
ADD_PROPERTY ( PropertyInfo ( Variant : : BOOL , " paused " , PROPERTY_HINT_NONE , " " , PROPERTY_USAGE_NONE ) , " set_paused " , " is_paused " ) ;
2021-12-03 08:09:19 +08:00
ADD_PROPERTY ( PropertyInfo ( Variant : : FLOAT , " time_left " , PROPERTY_HINT_NONE , " suffix:s " , PROPERTY_USAGE_NONE ) , " " , " get_time_left " ) ;
2015-09-26 02:45:00 +08:00
2017-09-30 22:19:07 +08:00
BIND_ENUM_CONSTANT ( TIMER_PROCESS_PHYSICS ) ;
2017-08-20 23:45:01 +08:00
BIND_ENUM_CONSTANT ( TIMER_PROCESS_IDLE ) ;
2014-02-10 09:10:30 +08:00
}
2021-02-10 01:24:36 +08:00
Timer : : Timer ( ) { }