random-stuff/computercraft/3dgraph_slave.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