mirror of
https://github.com/osmarks/random-stuff
synced 2024-12-28 02:50:33 +00:00
124 lines
3.3 KiB
Lua
124 lines
3.3 KiB
Lua
|
local m = peripheral.find "modem"
|
||
|
local CHAN = 7101
|
||
|
m.open(CHAN)
|
||
|
|
||
|
local ephem_ID = math.random(0, 0xFFFFFFF)
|
||
|
|
||
|
local function receive()
|
||
|
while true do
|
||
|
local _, _, c, rc, ms = os.pullEvent "modem_message"
|
||
|
if type(ms) == "table" then
|
||
|
return ms
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
local function send(ms) m.transmit(CHAN, CHAN, ms) end
|
||
|
|
||
|
local raw_exec_async, pull_event = commands.execAsync, os.pullEvent
|
||
|
|
||
|
local tasks = {}
|
||
|
local tasks_debug = {}
|
||
|
local tasks_count = 0
|
||
|
local tasks_limit = 1000
|
||
|
local half_tasks_limit = tasks_limit / 2
|
||
|
local function exec_async(name, ...)
|
||
|
if tasks_count >= tasks_limit then
|
||
|
print "task limit reached, blocking"
|
||
|
while tasks_count >= half_tasks_limit do
|
||
|
pull_event "task_complete"
|
||
|
end
|
||
|
print "blocking complete"
|
||
|
end
|
||
|
local id = raw_exec_async(table.concat({name, ...}, " "))
|
||
|
tasks_count = tasks_count + 1
|
||
|
tasks[id] = true
|
||
|
tasks_debug[id] = {name, ...}
|
||
|
end
|
||
|
|
||
|
local function fill(ax, ay, az, bx, by, bz, block)
|
||
|
exec_async("fill", ax, ay, az, bx, by, bz, block, 0, "replace")
|
||
|
end
|
||
|
|
||
|
local env = {}
|
||
|
local function add(x) for k, v in pairs(x) do env[k] = v end end
|
||
|
add(math)
|
||
|
add(bit)
|
||
|
add(bit32)
|
||
|
env[vector] = vector
|
||
|
|
||
|
local function plot(args)
|
||
|
print "plotting"
|
||
|
parallel.waitForAll(function()
|
||
|
local ax, ay, az = unpack(args.f_min)
|
||
|
local bx, by, bz = unpack(args.f_max)
|
||
|
local rx, ry, rz = (bx-ax), (by-ay), (bz-az)
|
||
|
local fn = load(("local x, y, z = ...; return %s"):format(args.equation), "=eqn", "t", math)
|
||
|
|
||
|
--[[print "Clearing"
|
||
|
for x = args.x_min, args.x_max do
|
||
|
|
||
|
end
|
||
|
print "Cleared plot area"]]
|
||
|
|
||
|
for x = args.x_min, args.x_max do
|
||
|
local go = true
|
||
|
if args.x_mod and args.x_mod_eq then
|
||
|
if x % args.x_mod ~= args.x_mod_eq then
|
||
|
go = false
|
||
|
end
|
||
|
end
|
||
|
if go then
|
||
|
-- clear thing
|
||
|
fill(x, args.y_min, args.z_min, x, args.y_max, args.z_max, "air")
|
||
|
for y = args.y_min, args.y_max do
|
||
|
local pz = nil
|
||
|
for z = args.z_min, args.z_max do
|
||
|
local sx, sy, sz = (((x-ax)/rx)*2)-1, (((y-ay)/ry)*2)-1, (((z-az)/rz)*2)-1
|
||
|
--print(sx, sy, sz)
|
||
|
local place_here = fn(sx, sy, sz)
|
||
|
if place_here and not pz then pz = z
|
||
|
elseif pz and not place_here then
|
||
|
fill(x, y, pz, x, y, z - 1, args.block)
|
||
|
--print(x, y, pz, x, y, z - 1, args.block)
|
||
|
pz = nil
|
||
|
end
|
||
|
end
|
||
|
if pz then
|
||
|
fill(x, y, pz, x, y, args.z_max, args.block)
|
||
|
--print(x, y, pz, x, y, args.z_max, args.block)
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end, function()
|
||
|
while true do
|
||
|
local event, id, success, result, output = pull_event "task_complete"
|
||
|
if tasks[id] then
|
||
|
tasks_count = tasks_count - 1
|
||
|
tasks[id] = nil
|
||
|
if not success then
|
||
|
error("thing failed: " .. table.concat(output, " "))
|
||
|
elseif not result and output[1] ~= "No blocks filled" then
|
||
|
printError(table.concat(output, " "))
|
||
|
_G.debug_task = tasks_debug[id]
|
||
|
end
|
||
|
tasks_debug[id] = nil
|
||
|
end
|
||
|
if tasks_count == 0 then return end
|
||
|
end
|
||
|
end)
|
||
|
|
||
|
return "done"
|
||
|
end
|
||
|
|
||
|
while true do
|
||
|
local ty, arg = unpack(receive())
|
||
|
if ty == "ping" then send { "pong", ephem_ID }
|
||
|
elseif ty == "plot" and arg.id == ephem_ID then
|
||
|
print("plot command received, running", arg.x_min, arg.x_max)
|
||
|
local ok, err = pcall(plot, arg)
|
||
|
print(err)
|
||
|
send { "response", { id = ephem_ID, response = err } }
|
||
|
end
|
||
|
end
|