mirror of
https://github.com/osmarks/random-stuff
synced 2024-11-08 05:29:54 +00:00
97 lines
2.3 KiB
Lua
97 lines
2.3 KiB
Lua
local channel = settings.get "basenet.channel" or 23032
|
|
local modem = peripheral.find "modem"
|
|
if not modem then error "modem required" end
|
|
modem.open(channel)
|
|
local name = settings.get "basenet.name" or _G.basenet_name or error "name required"
|
|
|
|
local basenet = {
|
|
listening_to = {},
|
|
tasks = {}
|
|
}
|
|
|
|
function basenet.listen(fn, from)
|
|
if type(from) ~= "string" then error "from must be a string" end
|
|
basenet.listening_to[from] = true
|
|
basenet.run_task(function()
|
|
while true do
|
|
local _, ufrom, data = os.pullEvent "update"
|
|
if ufrom == from then
|
|
fn(data)
|
|
end
|
|
end
|
|
end)
|
|
end
|
|
|
|
function basenet.update(data)
|
|
modem.transmit(channel, channel, { type = "update", from = name, data = data })
|
|
end
|
|
|
|
local task_ID = 0
|
|
function basenet.run_task(fn, ...)
|
|
local args = {...}
|
|
task_ID = task_ID + 1
|
|
basenet.tasks[task_ID] = { coroutine = coroutine.create(fn), init_args = args, ID = task_ID }
|
|
os.queueEvent "dummy"
|
|
return task_ID
|
|
end
|
|
|
|
function basenet.interval(fn, time)
|
|
if not time then error "time required" end
|
|
basenet.run_task(function()
|
|
while true do
|
|
fn()
|
|
sleep(time)
|
|
end
|
|
end)
|
|
end
|
|
|
|
local function process_message(msg)
|
|
if msg.type == "update" and type(msg.from) == "string" then
|
|
if basenet.listening_to[msg.from] then
|
|
os.queueEvent("update", msg.from, msg.data)
|
|
end
|
|
end
|
|
end
|
|
|
|
basenet.run_task(function()
|
|
while true do
|
|
local _, _, c, rc, msg, distance = os.pullEvent "modem_message"
|
|
if c == channel and type(msg) == "table" then
|
|
process_message(msg)
|
|
end
|
|
end
|
|
end)
|
|
|
|
local function tick_task(task, evt)
|
|
if task.init_args then
|
|
local init = task.init_args
|
|
task.init_args = nil
|
|
local ok = tick_task(task, init)
|
|
if not ok then return end
|
|
end
|
|
if coroutine.status(task.coroutine) == "dead" then
|
|
basenet.tasks[task.ID] = nil
|
|
else
|
|
if task.filter == nil or task.filter == evt[1] then
|
|
local ok, result = coroutine.resume(task.coroutine, unpack(evt))
|
|
if ok then
|
|
task.filter = result
|
|
else
|
|
printError(("TASK %d ERROR: %s"):format(task.ID, result))
|
|
basenet.tasks[task.ID] = nil
|
|
end
|
|
return ok
|
|
end
|
|
end
|
|
end
|
|
|
|
function basenet.run()
|
|
while true do
|
|
local evt = {os.pullEvent()}
|
|
for ID, task in pairs(basenet.tasks) do
|
|
tick_task(task, evt)
|
|
end
|
|
end
|
|
end
|
|
|
|
return basenet |