@icon("stopwatch.svg") class_name Stopwatch extends Node ## A clock that counts upwards, like a stopwatch. ## Emitted, whenever the elapsed time reaches the [param max_time] limit. signal max_time_reached ## See documentation for [param process_callback] in [Timer] @export var process_callback: Timer.TimerProcessCallback ## The time, where we count upwards from when [method start] is called. @export var start_time: float = 0.0 ## The maximum allowed elapsed time we can have.[br]If this is under [code]0[/code] ## we don't have any limit and we count towards infinity. @export var max_time: float = -1.0 ## If [code]true[/code], the stopwatch will call [method start] when entering the scene tree. @export var autostart: bool = false ## If [code]true[/code], it will reset the timer when [method stop] is being called. @export var reset_timer_on_stop: bool = true ## The stopwatch will halt it's counting when this is [code]true[/code]. var paused: bool = false var _stopped: bool = true var _time_elapsed: float = 0.0 func _ready() -> void: if autostart: start() func _process(delta: float) -> void: if process_callback == Timer.TIMER_PROCESS_IDLE: _process_timer(delta) func _physics_process(delta: float) -> void: if process_callback == Timer.TIMER_PROCESS_PHYSICS: _process_timer(delta) func _process_timer(delta: float) -> void: if is_stopped() or is_paused(): return _time_elapsed += delta if (max_time >= 0.0) and (_time_elapsed >= max_time): max_time_reached.emit() stop() #region Starting/Stopping ## Starts the stopwatch. [param custom_start_time] will set the elapsed time to it instead of ## using [param start_time]. func start(custom_start_time: float = start_time) -> void: _time_elapsed = custom_start_time _stopped = false ## Stops the stopwatch. func stop(reset_time: bool = reset_timer_on_stop) -> float: var final_time: float = _time_elapsed if reset_time: _time_elapsed = start_time _stopped = true return final_time #endregion ## Returns the elapsed time since this stopwatch was started. func get_elapsed_time() -> float: return _time_elapsed ## Will pause or unpause the counting. func set_paused(value: bool) -> void: paused = value ## Returns [code]true[/code] when this stopwatch isn't running. func is_stopped() -> bool: return _stopped ## Returns [code]true[/code] when this stopwatch is [u]paused[/u]. func is_paused() -> bool: return paused