updated
This commit is contained in:
146
task-manager.lua
Normal file
146
task-manager.lua
Normal file
@@ -0,0 +1,146 @@
|
||||
local monitor = peripheral.find("monitor")
|
||||
local programs = {}
|
||||
local isRunning = false
|
||||
|
||||
|
||||
local function addProgram(name, program)
|
||||
table.insert(programs, {name = name, program = program})
|
||||
end
|
||||
|
||||
local function runProgram(programOrPath)
|
||||
local programModule
|
||||
|
||||
if type(programOrPath) == "string" then
|
||||
if fs.exists(programOrPath) then
|
||||
-- Load the file as a chunk. In Lua 5.2+ use the env parameter instead of setfenv.
|
||||
local env = _ENV or _G
|
||||
local programChunk, err = loadfile(programOrPath, "t", env)
|
||||
if not programChunk then
|
||||
print("Error loading program: " .. err)
|
||||
return false
|
||||
end
|
||||
|
||||
-- Run the chunk to get the module table
|
||||
local success, result = pcall(programChunk)
|
||||
|
||||
if not success then
|
||||
print("Error executing program file: " .. tostring(result))
|
||||
return false
|
||||
end
|
||||
programModule = result
|
||||
else
|
||||
print("Program not found: " .. programOrPath)
|
||||
return false
|
||||
end
|
||||
elseif type(programOrPath) == "table" then
|
||||
programModule = programOrPath
|
||||
else
|
||||
print("Invalid program type")
|
||||
return false
|
||||
end
|
||||
|
||||
if type(programModule) ~= "table" or not programModule.main then
|
||||
print("Error: Program must return a table with at least a 'main' function.")
|
||||
return false
|
||||
end
|
||||
|
||||
-- Setup Monitor
|
||||
local w, h = monitor.getSize()
|
||||
monitor.setBackgroundColor(colors.black)
|
||||
monitor.clear()
|
||||
|
||||
-- Draw X button
|
||||
monitor.setCursorPos(w, 1)
|
||||
monitor.setBackgroundColor(colors.red)
|
||||
monitor.setTextColor(colors.white)
|
||||
monitor.write("X")
|
||||
monitor.setBackgroundColor(colors.black)
|
||||
|
||||
-- Create window for program
|
||||
local win = window.create(monitor, 1, 2, w, h - 1)
|
||||
local oldTerm = term.redirect(win)
|
||||
|
||||
-- Lifecycle: START
|
||||
if programModule.start then
|
||||
local ok, err = pcall(programModule.start)
|
||||
if not ok then
|
||||
print("Error in start(): " .. tostring(err))
|
||||
term.redirect(oldTerm)
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
-- Lifecycle: MAIN (Run in parallel with exit watcher)
|
||||
local function runMain()
|
||||
-- We wrap main in pcall to catch errors without crashing the driver
|
||||
local ok, err = pcall(programModule.main)
|
||||
if not ok then
|
||||
win.setTextColor(colors.red)
|
||||
win.write("Runtime Error: " .. tostring(err))
|
||||
sleep(2) -- Let user see error
|
||||
end
|
||||
end
|
||||
|
||||
local function watchExit()
|
||||
while true do
|
||||
local _, _, x, y = os.pullEvent("monitor_touch")
|
||||
if x == w and y == 1 then
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
parallel.waitForAny(runMain, watchExit)
|
||||
|
||||
-- Lifecycle: STOP
|
||||
if programModule.stop then
|
||||
pcall(programModule.stop)
|
||||
end
|
||||
|
||||
term.redirect(oldTerm)
|
||||
return true
|
||||
end
|
||||
|
||||
local function exitProgram()
|
||||
isRunning = false
|
||||
end
|
||||
|
||||
local function drawList()
|
||||
monitor.clear()
|
||||
monitor.setCursorPos(1, 1)
|
||||
monitor.write("Available Programs:")
|
||||
|
||||
for i, program in ipairs(programs) do
|
||||
monitor.setCursorPos(1, i + 2) -- Start from line 3
|
||||
monitor.write(i .. ". " .. program.name)
|
||||
end
|
||||
|
||||
monitor.setCursorPos(1, #programs + 4)
|
||||
monitor.write("Click to run")
|
||||
end
|
||||
|
||||
local function listPrograms()
|
||||
isRunning = true
|
||||
while isRunning do
|
||||
drawList()
|
||||
|
||||
local event, side, x, y = os.pullEvent("monitor_touch")
|
||||
local programIndex = y - 2
|
||||
|
||||
if programIndex > 0 and programIndex <= #programs then
|
||||
local program = programs[programIndex]
|
||||
monitor.clear()
|
||||
monitor.setCursorPos(1,1)
|
||||
monitor.write("Running " .. program.name .. "...")
|
||||
sleep(0.5)
|
||||
runProgram(program.program)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return {
|
||||
addProgram = addProgram,
|
||||
runProgram = runProgram,
|
||||
exitProgram = exitProgram,
|
||||
listPrograms = listPrograms
|
||||
}
|
||||
Reference in New Issue
Block a user