88 lines
2.9 KiB
GDScript3
88 lines
2.9 KiB
GDScript3
|
## Task
|
||
|
##
|
||
|
## [color=yellow][b]Note:[/b] You probably won't be generating these yourself.
|
||
|
## Primarily intended to be generated and used by [TaskManager][/color].[br]
|
||
|
## A stateful task container, containing a list of functions.
|
||
|
|
||
|
class_name Task extends RefCounted
|
||
|
|
||
|
## Called when this task completes, emitting itself as [param task].
|
||
|
signal on_finished(task:Task)
|
||
|
|
||
|
## Nice name.
|
||
|
var name:String = ""
|
||
|
## List of queued commands.
|
||
|
var commands:Array[Callable] = []
|
||
|
## List of exit conditions. Any set to true will end this process.
|
||
|
var exit_conditions:Array[Callable] = [
|
||
|
func()->bool: return halt
|
||
|
]
|
||
|
## Internal tracker for showing what's running
|
||
|
var current_execution:int = 0
|
||
|
## Are we done yet?
|
||
|
var finished := false
|
||
|
## Are we paused?
|
||
|
var paused := false
|
||
|
## Are we flagged to stop when possible?
|
||
|
var halt := false
|
||
|
|
||
|
## Assign pause state to [param to_pause].
|
||
|
func set_pause(to_pause:bool)->void: paused = to_pause
|
||
|
|
||
|
## Assign pause state to [param to_pause] upon all [param tasks].
|
||
|
static func set_pause_many(tasks:Array[Task], to_pause:bool)->void:
|
||
|
tasks.map(func(t:Task): t.paused = to_pause)
|
||
|
|
||
|
## Initialize.[br]
|
||
|
## [param _name] Nice name.[br]
|
||
|
## [param _commands] List of commands.[br]
|
||
|
## [param exit_conds] List of functions that take 0 args and return boolean.
|
||
|
## if any of these are true when ticked, the task will terminate.
|
||
|
func _init(_name:String, _commands:Array[Callable], exit_conds:Array[Callable])->void:
|
||
|
name = _name
|
||
|
commands = _commands
|
||
|
for p_exit:Callable in exit_conds:
|
||
|
if p_exit.is_valid():
|
||
|
exit_conditions.append(p_exit)
|
||
|
|
||
|
|
||
|
## Execute all [member Task.commands]. Triggers [signal Task.on_finished] when complete.
|
||
|
func execute()->void:
|
||
|
finished = false
|
||
|
var _check_halt_conds := func(p:Callable)->bool: return p.call()
|
||
|
for index:int in commands.size():
|
||
|
if exit_conditions.any(_check_halt_conds):
|
||
|
break
|
||
|
while paused:
|
||
|
await Engine.get_main_loop().root.get_tree().process_frame
|
||
|
if exit_conditions.any(_check_halt_conds):
|
||
|
break
|
||
|
current_execution = index
|
||
|
await commands[index].call()
|
||
|
finished = true
|
||
|
on_finished.emit(self)
|
||
|
|
||
|
## Dump a string of [param task] and all functions in the queue.
|
||
|
static func dump_to_text(task:Task)->String:
|
||
|
var _name_out := "[%s]\n" % "Unnamed tasklist" \
|
||
|
if task.name.is_empty() else task.name
|
||
|
var _commands_out:String = ""
|
||
|
for index:int in task.commands.size():
|
||
|
var cmd := task.commands[index]
|
||
|
var _label_id := "[%s]%s" % [
|
||
|
str(index).pad_zeros(2),
|
||
|
">" if index == task.current_execution else ""]
|
||
|
var _broken := "" if cmd.is_valid() else "<Invalid Callable?>"
|
||
|
var _cmd_out := cmd.get_method() + "("
|
||
|
for arg in cmd.get_bound_arguments():
|
||
|
_cmd_out += str(arg) + ","
|
||
|
_cmd_out = _cmd_out.trim_suffix(",") + ")\n"
|
||
|
_commands_out += _label_id + _broken + _cmd_out
|
||
|
return _name_out + _commands_out
|
||
|
|
||
|
## Dump strings of all given [param tasks].
|
||
|
static func dump_commands(tasks:Array[Task])->Array[String]:
|
||
|
var task_text:Array[String] = []
|
||
|
task_text.assign(tasks.map(dump_to_text))
|
||
|
return task_text
|