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. ## ## Syncing the task will return an array of the tasks' results ## in the same respective order. 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)