stick-the-quick/util/Wait.gd

51 lines
1.4 KiB
GDScript

extends Node
## Global reference point node for tick-based delays.
##
## Serves as a terser alternative to SceneTreeTimer.
signal _ticked(delay: float)
func _ready() -> void:
process_mode = Node.PROCESS_MODE_ALWAYS
func _process(delta: float) -> void:
_ticked.emit(delta)
## Waits one tick. Returns the tick's duration.
func tick() -> float:
return await _ticked
## Waits n ticks. Returns the total duration.
func ticks(n: int) -> float:
var duration: float = 0.0
for _dont_care in n:
duration += await _ticked
return duration
## Waits approximately n seconds. Returns the actual duration waited.
func seconds(n: float) -> float:
var duration: float = 0.0
while duration < n:
duration += await _ticked
return duration
## Waits until condition is fulfilled. Returns the duration waited.
func until(p: Callable) -> float:
var duration: float = 0.0
# Wrap condition in case it is a coroutine.
var task := Task.new(p)
while true:
# Wait for task, but do not actually await it,
# because we need to tally the time waited in the meantime.
while not task.is_finished():
duration += await _ticked
# Task is supposed to be a condition, not just any task.
# Therefore, even when it finishes, only conclude waiting
# if its result was affirmative (meaning the condition has been met);
# otherwise, repeat the task.
if task.result:
break
else:
task = Task.new(p)
return duration