2024-01-02 19:34:41 -08:00
|
|
|
class_name Task extends RefCounted
|
|
|
|
## Promise-like abstraction for (hopefully) safer concurrency.
|
|
|
|
|
|
|
|
signal _sig_finished
|
|
|
|
|
|
|
|
## Value returned by task. Null if, but not only if, task has not finished.
|
|
|
|
var result: Variant = null
|
|
|
|
var _finished := false
|
|
|
|
|
|
|
|
## Awaits the given Callable concurrently and reports back when it finishes.
|
|
|
|
func _init(thunk: Callable) -> void:
|
|
|
|
var coro := func() -> void:
|
|
|
|
result = await thunk.call()
|
|
|
|
_finished = true
|
|
|
|
_sig_finished.emit()
|
|
|
|
coro.call()
|
|
|
|
|
|
|
|
## Returns true iff the task has finished.
|
|
|
|
func is_finished() -> bool:
|
|
|
|
return _finished
|
|
|
|
|
|
|
|
## Waits for the task to finish (if necessary) and returns its result.
|
|
|
|
func sync() -> Variant:
|
|
|
|
if not _finished:
|
|
|
|
await _sig_finished
|
|
|
|
return result
|
|
|
|
|
|
|
|
## Creates a Task which can only finish when all subtasks have finished.
|
|
|
|
##
|
2024-01-07 09:28:08 -08:00
|
|
|
## Syncing the task will return an array of the tasks' results
|
|
|
|
## in the same respective order.
|
2024-01-02 19:34:41 -08:00
|
|
|
static func group(subtasks: Array[Task]) -> Task:
|
|
|
|
var thunk := func() -> Array:
|
|
|
|
var results := []
|
|
|
|
for task in subtasks:
|
|
|
|
results.push_back(await task.sync())
|
|
|
|
return results
|
|
|
|
return Task.new(thunk)
|