97 lines
2.2 KiB
Lua
97 lines
2.2 KiB
Lua
local os = _G.os
|
|
local peripheral = _G.peripheral
|
|
|
|
local running, modemSide
|
|
local tasks = { }
|
|
|
|
local sides = { 'front', 'back', 'left', 'right', 'top', 'bottom' }
|
|
for _,v in pairs(sides) do
|
|
if peripheral.getType(v) == 'modem' and not peripheral.call(v, 'isWireless') then
|
|
modemSide = v
|
|
break
|
|
end
|
|
end
|
|
|
|
if not modemSide then
|
|
error('Must be conncted to a wired modem')
|
|
end
|
|
|
|
print('Using modem at side: ' .. modemSide)
|
|
peripheral.call(modemSide, 'open', 42)
|
|
|
|
local function addTask(fn)
|
|
local task
|
|
task = {
|
|
co = coroutine.create(fn)
|
|
}
|
|
table.insert(tasks, task)
|
|
return task
|
|
end
|
|
|
|
local function run()
|
|
if #tasks > 0 then
|
|
local event = { }
|
|
|
|
while true do
|
|
for n = #tasks, 1, -1 do
|
|
local task = tasks[n]
|
|
if coroutine.status(task.co) == 'dead' then
|
|
table.remove(tasks, n)
|
|
elseif task.filter == nil or task.filter == event[1] or event[1] == "terminate" then
|
|
local ok, param = coroutine.resume(task.co, table.unpack(event))
|
|
if not ok then
|
|
_G.printError(param)
|
|
else
|
|
task.filter = param
|
|
end
|
|
if coroutine.status(task.co) == 'dead' then
|
|
table.remove(tasks, n)
|
|
end
|
|
end
|
|
end
|
|
if #tasks == 0 then
|
|
break
|
|
end
|
|
event = { os.pullEventRaw() }
|
|
end
|
|
end
|
|
end
|
|
|
|
local function startProgram(program)
|
|
print('Starting: ' .. program.name)
|
|
|
|
local sandbox = { }
|
|
for k,v in pairs(_ENV) do
|
|
sandbox[k] = v
|
|
end
|
|
|
|
local env = setmetatable(sandbox, { __index = _G })
|
|
local fn, m = load(program.data, program.name, nil, env)
|
|
if fn then
|
|
running = addTask(function()
|
|
pcall(fn)
|
|
print('Ended: ' .. program.name)
|
|
end)
|
|
else
|
|
_G.printError(m)
|
|
end
|
|
end
|
|
|
|
addTask(function()
|
|
print('Waiting for program...')
|
|
while true do
|
|
local _, side, dport, dhost, msg = os.pullEvent('modem_message')
|
|
if side == modemSide and dport == 42 and dhost == os.getComputerID() then
|
|
if running and coroutine.status(running.co) ~= 'dead' then
|
|
coroutine.resume(running.co, 'terminate')
|
|
end
|
|
if msg.type == 'start' then
|
|
startProgram(msg)
|
|
end
|
|
os.queueEvent('dummy')
|
|
end
|
|
end
|
|
end)
|
|
|
|
run()
|