2014-02-10 02:10:30 +01:00
/*************************************************************************/
/* timer.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
2017-08-27 14:16:55 +02:00
/* https://godotengine.org */
2014-02-10 02:10:30 +01:00
/*************************************************************************/
2022-01-03 21:27:34 +01:00
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
2014-02-10 02:10:30 +01:00
/* */
/* 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 00:50:27 +01:00
2014-02-10 02:10:30 +01:00
# include "timer.h"
void Timer : : _notification ( int p_what ) {
2017-03-05 16:44:50 +01:00
switch ( p_what ) {
2014-02-10 02:10:30 +01:00
case NOTIFICATION_READY : {
2014-10-12 07:13:22 +02:00
if ( autostart ) {
2014-10-14 06:01:25 +02:00
# ifdef TOOLS_ENABLED
2021-06-19 00:02:50 +02:00
if ( Engine : : get_singleton ( ) - > is_editor_hint ( ) & & get_tree ( ) - > get_edited_scene_root ( ) & & ( get_tree ( ) - > get_edited_scene_root ( ) = = this | | get_tree ( ) - > get_edited_scene_root ( ) - > is_ancestor_of ( this ) ) ) {
2014-10-12 07:13:22 +02:00
break ;
2020-05-14 16:41:43 +02:00
}
2014-12-07 06:04:20 +01:00
# endif
start ( ) ;
2017-03-05 16:44:50 +01:00
autostart = false ;
2014-10-12 07:13:22 +02:00
}
2014-02-10 02:10:30 +01:00
} break ;
2022-02-15 18:06:48 +01:00
2017-01-10 22:02:19 +01:00
case NOTIFICATION_INTERNAL_PROCESS : {
2021-02-19 13:35:31 +01:00
if ( ! processing | | timer_process_callback = = TIMER_PROCESS_PHYSICS | | ! is_processing_internal ( ) ) {
2015-05-01 16:44:02 +02:00
return ;
2020-05-14 16:41:43 +02:00
}
2014-02-10 02:10:30 +01:00
time_left - = get_process_delta_time ( ) ;
2017-03-05 16:44:50 +01:00
if ( time_left < 0 ) {
2020-05-14 16:41:43 +02:00
if ( ! one_shot ) {
2017-04-05 08:22:41 +02:00
time_left + = wait_time ;
2020-05-14 16:41:43 +02:00
} else {
2014-02-10 02:10:30 +01:00
stop ( ) ;
2020-05-14 16:41:43 +02:00
}
2014-02-10 02:10:30 +01:00
2021-07-17 23:22:52 +02:00
emit_signal ( SNAME ( " timeout " ) ) ;
2014-02-10 02:10:30 +01:00
}
} break ;
2022-02-15 18:06:48 +01:00
2017-09-30 16:19:07 +02:00
case NOTIFICATION_INTERNAL_PHYSICS_PROCESS : {
2021-02-19 13:35:31 +01:00
if ( ! processing | | timer_process_callback = = TIMER_PROCESS_IDLE | | ! is_physics_processing_internal ( ) ) {
2015-05-10 16:00:26 +02:00
return ;
2020-05-14 16:41:43 +02:00
}
2017-09-30 16:19:07 +02:00
time_left - = get_physics_process_delta_time ( ) ;
2015-05-10 16:00:26 +02:00
2017-03-05 16:44:50 +01:00
if ( time_left < 0 ) {
2020-05-14 16:41:43 +02:00
if ( ! one_shot ) {
2017-04-05 08:22:41 +02:00
time_left + = wait_time ;
2020-05-14 16:41:43 +02:00
} else {
2015-05-10 16:00:26 +02:00
stop ( ) ;
2020-05-14 16:41:43 +02:00
}
2021-07-17 23:22:52 +02:00
emit_signal ( SNAME ( " timeout " ) ) ;
2015-05-10 16:00:26 +02:00
}
} break ;
2014-02-10 02:10:30 +01:00
}
}
2021-05-21 07:23:35 +02:00
void Timer : : set_wait_time ( double p_time ) {
2019-08-08 22:11:48 +02:00
ERR_FAIL_COND_MSG ( p_time < = 0 , " Time should be greater than zero. " ) ;
2017-03-05 16:44:50 +01:00
wait_time = p_time ;
2021-10-09 08:57:48 +02:00
update_configuration_warnings ( ) ;
2014-02-10 02:10:30 +01:00
}
2020-05-14 14:29:06 +02:00
2021-05-21 07:23:35 +02:00
double Timer : : get_wait_time ( ) const {
2014-02-10 02:10:30 +01:00
return wait_time ;
}
void Timer : : set_one_shot ( bool p_one_shot ) {
2017-03-05 16:44:50 +01:00
one_shot = p_one_shot ;
2014-02-10 02:10:30 +01:00
}
2020-05-14 14:29:06 +02:00
2014-02-10 02:10:30 +01:00
bool Timer : : is_one_shot ( ) const {
return one_shot ;
}
void Timer : : set_autostart ( bool p_start ) {
2017-03-05 16:44:50 +01:00
autostart = p_start ;
2014-02-10 02:10:30 +01:00
}
2020-05-14 14:29:06 +02:00
2014-02-10 02:10:30 +01:00
bool Timer : : has_autostart ( ) const {
return autostart ;
}
2021-05-21 07:23:35 +02:00
void Timer : : start ( double p_time ) {
2019-11-27 16:34:54 +01: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 01:25:22 +02:00
2018-04-26 21:42:50 +02:00
if ( p_time > 0 ) {
set_wait_time ( p_time ) ;
}
2017-03-05 16:44:50 +01:00
time_left = wait_time ;
2015-05-10 16:00:26 +02:00
_set_process ( true ) ;
2014-02-10 02:10:30 +01:00
}
void Timer : : stop ( ) {
2017-03-05 16:44:50 +01:00
time_left = - 1 ;
2015-05-10 16:00:26 +02:00
_set_process ( false ) ;
2017-03-05 16:44:50 +01:00
autostart = false ;
2014-02-10 02:10:30 +01:00
}
2017-03-11 18:10:01 +01:00
void Timer : : set_paused ( bool p_paused ) {
2020-05-14 16:41:43 +02:00
if ( paused = = p_paused ) {
2016-03-31 23:23:16 +02:00
return ;
2020-05-14 16:41:43 +02:00
}
2016-03-31 23:23:16 +02:00
2017-03-11 18:10:01 +01:00
paused = p_paused ;
2016-03-31 23:23:16 +02:00
_set_process ( processing ) ;
}
2017-03-11 18:10:01 +01:00
bool Timer : : is_paused ( ) const {
return paused ;
}
bool Timer : : is_stopped ( ) const {
return get_time_left ( ) < = 0 ;
2016-03-31 23:23:16 +02:00
}
2021-05-21 07:23:35 +02:00
double Timer : : get_time_left ( ) const {
2017-03-05 16:44:50 +01:00
return time_left > 0 ? time_left : 0 ;
2014-02-10 02:10:30 +01:00
}
2021-02-19 13:35:31 +01:00
void Timer : : set_timer_process_callback ( TimerProcessCallback p_callback ) {
if ( timer_process_callback = = p_callback ) {
2015-05-10 16:00:26 +02:00
return ;
2020-05-14 16:41:43 +02:00
}
2015-05-10 16:00:26 +02:00
2021-02-19 13:35:31 +01:00
switch ( timer_process_callback ) {
2017-09-30 16:19:07 +02:00
case TIMER_PROCESS_PHYSICS :
if ( is_physics_processing_internal ( ) ) {
set_physics_process_internal ( false ) ;
2017-01-10 22:02:19 +01:00
set_process_internal ( true ) ;
2015-05-10 16:00:26 +02:00
}
2017-03-05 16:44:50 +01:00
break ;
2015-05-10 16:00:26 +02:00
case TIMER_PROCESS_IDLE :
2017-01-10 22:02:19 +01:00
if ( is_processing_internal ( ) ) {
set_process_internal ( false ) ;
2017-09-30 16:19:07 +02:00
set_physics_process_internal ( true ) ;
2015-05-10 16:00:26 +02:00
}
2017-03-05 16:44:50 +01:00
break ;
2015-05-10 16:00:26 +02:00
}
2021-02-19 13:35:31 +01:00
timer_process_callback = p_callback ;
2015-05-10 16:00:26 +02:00
}
2021-02-19 13:35:31 +01:00
Timer : : TimerProcessCallback Timer : : get_timer_process_callback ( ) const {
return timer_process_callback ;
2015-05-10 16:00:26 +02:00
}
2017-03-05 16:44:50 +01:00
void Timer : : _set_process ( bool p_process , bool p_force ) {
2021-02-19 13:35:31 +01:00
switch ( timer_process_callback ) {
2020-05-10 13:00:47 +02: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 16:00:26 +02:00
}
2016-03-31 23:23:16 +02:00
processing = p_process ;
2015-05-10 16:00:26 +02:00
}
2014-02-10 02:10:30 +01:00
2021-10-09 08:57:48 +02:00
TypedArray < String > Timer : : get_configuration_warnings ( ) const {
TypedArray < String > warnings = Node : : get_configuration_warnings ( ) ;
if ( wait_time < 0.05 - CMP_EPSILON ) {
2022-03-28 15:24:14 +02: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 08:57:48 +02:00
}
return warnings ;
}
2014-02-10 02:10:30 +01:00
void Timer : : _bind_methods ( ) {
2017-03-05 16:44:50 +01: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 02:10:30 +01:00
2017-03-05 16:44:50 +01: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 02:10:30 +01:00
2017-03-05 16:44:50 +01: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 02:10:30 +01:00
2018-04-26 21:42:50 +02:00
ClassDB : : bind_method ( D_METHOD ( " start " , " time_sec " ) , & Timer : : start , DEFVAL ( - 1 ) ) ;
2017-03-05 16:44:50 +01:00
ClassDB : : bind_method ( D_METHOD ( " stop " ) , & Timer : : stop ) ;
2014-02-10 02:10:30 +01:00
2017-03-11 18:10:01 +01: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-03-31 23:23:16 +02:00
2017-03-05 16:44:50 +01:00
ClassDB : : bind_method ( D_METHOD ( " get_time_left " ) , & Timer : : get_time_left ) ;
2014-02-10 02:10:30 +01:00
2021-02-19 13:35:31 +01: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 16:00:26 +02:00
2017-03-05 16:44:50 +01:00
ADD_SIGNAL ( MethodInfo ( " timeout " ) ) ;
2014-02-10 02:10:30 +01:00
2021-02-19 13:35:31 +01:00
ADD_PROPERTY ( PropertyInfo ( Variant : : INT , " process_callback " , PROPERTY_HINT_ENUM , " Physics,Idle " ) , " set_timer_process_callback " , " get_timer_process_callback " ) ;
2021-12-03 01:09:19 +01: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 16:44:50 +01: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 01:10:18 +02:00
ADD_PROPERTY ( PropertyInfo ( Variant : : BOOL , " paused " , PROPERTY_HINT_NONE , " " , PROPERTY_USAGE_NONE ) , " set_paused " , " is_paused " ) ;
2021-12-03 01:09:19 +01:00
ADD_PROPERTY ( PropertyInfo ( Variant : : FLOAT , " time_left " , PROPERTY_HINT_NONE , " suffix:s " , PROPERTY_USAGE_NONE ) , " " , " get_time_left " ) ;
2015-09-25 20:45:00 +02:00
2017-09-30 16:19:07 +02:00
BIND_ENUM_CONSTANT ( TIMER_PROCESS_PHYSICS ) ;
2017-08-20 17:45:01 +02:00
BIND_ENUM_CONSTANT ( TIMER_PROCESS_IDLE ) ;
2014-02-10 02:10:30 +01:00
}
2021-02-09 18:24:36 +01:00
Timer : : Timer ( ) { }