TaskRunner
Config-driven task template that wires core libraries together
Library Implementation
-- TaskRunner.lua
-- Configurable task template to reduce boilerplate in task scripts
local TaskStateMachine = require("TaskStateMachine")
local SubtaskExecutor = require("SubtaskExecutor")
local CommonChecks = require("CommonChecks")
local TaskHelpers = require("TaskHelpers")
local CoordinationHelpers = require("CoordinationHelpers")
local TaskRunner = {}
-- Create a task implementation from config
function TaskRunner.create(config)
local cfg = config or {}
local timeoutSeconds = cfg.timeoutSeconds or 300
local flags = cfg.flags or {}
local hooks = cfg.hooks or {}
local state = nil
local function init(params)
local success, msg = CommonChecks.initChecks(params)
if not success then
return false, msg
end
local subtaskNames = cfg.subtasks or {}
state = TaskStateMachine.new(subtaskNames)
state.startTime = vrf.getSimulationTime()
state.data = params or {}
TaskHelpers.setData(state, "fallbackNotified", false)
if flags.activateSensors then
ActivateSensors{}
end
if flags.captureTargetLocation and params and params.targetLocation then
TaskHelpers.setData(state, "targetLocation", params.targetLocation)
end
if hooks.onInit then
local hookOk, hookMsg = hooks.onInit(state, params)
if hookOk == false then
return false, hookMsg
end
end
return TaskStateMachine.transition(state, "READY", "Task initialized successfully")
end
local function tick()
if TaskHelpers.isTimeout(state.startTime, timeoutSeconds) then
return "FAILURE", "Task timeout exceeded"
end
if state.current == "READY" then
if flags.sendStartReport then
CoordinationHelpers.sendProgressReport(state, "READY", "Starting task execution")
end
if hooks.onReady then
local nextState, hookMsg = hooks.onReady(state)
if nextState then
return TaskStateMachine.transition(state, nextState, hookMsg or "Ready")
end
end
return TaskStateMachine.transition(state, "EXECUTING", "Beginning execution")
elseif state.current == "EXECUTING" then
local canContinue, checkMsg = CommonChecks.preExecutionChecks()
if not canContinue then
return "FAILURE", checkMsg
end
if flags.enableParallelSensing then
ActivateSensors{}
end
if flags.requireAmmoForEngagement and not HasAmmo{} then
if flags.enableAttackFallback then
TaskHelpers.setData(state, "fallbackReason", "Insufficient ammo")
return TaskStateMachine.transition(state, "FALLBACK", "Insufficient ammo")
end
return "FAILURE", "Insufficient ammo"
end
if flags.requireEngagementAuth then
local target = TaskHelpers.getData(state, "target", nil)
local canEngage, msg = CommonChecks.canEngage(target)
if not canEngage then
if flags.enableAttackFallback then
TaskHelpers.setData(state, "fallbackReason", msg)
return TaskStateMachine.transition(state, "FALLBACK", msg)
end
return "FAILURE", msg
end
end
if hooks.onExecuting then
local action, hookMsg = hooks.onExecuting(state)
if action == "FAILURE" or action == "COMPLETE" then
return action, hookMsg
end
end
local currentIdx = SubtaskExecutor.getCurrentSubtask(state)
if not currentIdx then
local execOk, execMsg = SubtaskExecutor.executeNext(state)
if not execOk then
return "FAILURE", execMsg
end
end
if TaskStateMachine.allSubtasksComplete(state) then
return TaskStateMachine.transition(state, "COMPLETING", "All subtasks executed")
end
local progress = SubtaskExecutor.getProgress(state)
local statusMsg = string.format("Executing subtasks (%.0f%% complete)", progress * 100)
return "CONTINUE", statusMsg
elseif state.current == "FALLBACK" then
local notified = TaskHelpers.getData(state, "fallbackNotified", false)
if not notified then
local reason = TaskHelpers.getData(state, "fallbackReason", "Fallback engaged")
if flags.sendFallbackReport then
CoordinationHelpers.sendProgressReport(state, "FALLBACK", reason)
end
if flags.requestSupport then
local loc = TaskHelpers.getData(state, "targetLocation", nil)
CoordinationHelpers.requestSupport("SUPPORT", {location = loc, urgency = "IMMEDIATE"})
end
TaskHelpers.setData(state, "fallbackNotified", true)
end
local waitSeconds = flags.fallbackWaitSeconds or 30
if TaskHelpers.wait(state, waitSeconds) then
TaskHelpers.setData(state, "fallbackNotified", false)
return TaskStateMachine.transition(state, "EXECUTING", "Retrying execution")
end
return "CONTINUE", "Fallback active"
elseif state.current == "COMPLETING" then
if hooks.onCompleting then
local action, hookMsg = hooks.onCompleting(state)
if action == "FAILURE" or action == "COMPLETE" then
return action, hookMsg
end
end
local complete, completeMsg = CommonChecks.missionCompleteChecks()
if complete == true then
if flags.sendCompletionReport then
CoordinationHelpers.sendCompletionReport(state, true, "Mission accomplished")
end
return TaskStateMachine.transition(state, "COMPLETE", "Task completed successfully")
elseif complete == false then
return "FAILURE", completeMsg
end
return "CONTINUE", "Verifying mission completion"
elseif state.current == "COMPLETE" then
if hooks.onComplete then
local action, hookMsg = hooks.onComplete(state)
if action then
return action, hookMsg
end
end
return "COMPLETE", "Task completed successfully"
end
return "CONTINUE", TaskHelpers.formatStatus(state, "Task in progress")
end
return {init = init, tick = tick}
end
return TaskRunner
6922 characters
Usage Example
-- Usage example:
local TaskRunner = require("TaskRunner")
local config = {
subtasks = {"Plan", "Move", "Execute", "Assess"},
timeoutSeconds = 300,
flags = {
activateSensors = true,
captureTargetLocation = true,
enableParallelSensing = true,
requireAmmoForEngagement = true,
requireEngagementAuth = true,
enableAttackFallback = true,
sendStartReport = true,
sendFallbackReport = true,
requestSupport = true,
sendCompletionReport = true,
fallbackWaitSeconds = 30
}
}
return TaskRunner.create(config)
Quick Reference
Import Statement
local TaskRunner = require("TaskRunner")
Category
task template
Key Features
- Reusable utility functions
- Common task operations
- Helper methods