## 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 "" 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