MagicNStuff/source/components/general/time/stopwatch.gd
2025-02-25 22:07:11 +01:00

93 lines
2.4 KiB
GDScript

@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