51 lines
1.4 KiB
GDScript
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
|