OK, think I figured out and implemented the parallel api stuff, a quick question about the line in my code:
funct = parallel.waitForAny(channel,searching = waitForOpenInfuser(), infusionCompletionListener())
Is that a valid way to get results from a function run by parallel? If not how can I do that?
Manager Program:
Spoiler
infusersrunning = {0, 0, 0, 0}
recipefile = "recipes"
function trim(s)
return (s:gsub("^%s*(.-)%s*$", "%1"))
end
function load(filename)
file = fs.open(filename, "r")
data = file.readAll()
file.close()
return textutils.unserialize(data)
end
function pullItem(direction)
while sorter.pull(direction) == false do
sleep(10)
end
end
function infusionCompletionListener()
local event, side, channel, replychannel, message, distance = os.pullEvent("modem_message")
if trim(message) == "Infuser "..tostring(replychannel)..": Infusion complete." then
infusersrunning[replychannel] = 0
end
end
function waitForOpenInfuser()
while true do
for i=1, #infusersrunning do
if infusersrunning[i] < 1 then
infusersrunning[i] = item[amount]
return i, false
end
end
end
end
function pushItem(direction)
while sorter.push(direction) == false do
sleep(5)
end
end
screen = peripheral.wrap("back")
modem = peripheral.wrap("top")
modem.open(5)
recipes = loadRecipes(recipefile)
sorter = peripheral.wrap("left")
escape = false
while escape == false do
func = parallel.waitForAny(pullItem("east"), infusionCompletionListener())
if func == 1 then
item = sorter.analyze()
if item[stringId] == "minecraft:cobblestone" then
command = "infuse "..tostring(item[amount])
searching = true
channel = 0
while searching do
funct = parallel.waitForAny(channel,searching = waitForOpenInfuser(), infusionCompletionListener())
if funct == 1 then
modem.transmit(channel, 5, command)
elseif funct == 2 then
end
end
end
elseif func == 2 then
end
func = parallel.waitForAny(pushItem("south"), infusionCompletionListener())
if func == 1 then
elseif func == 2 then
end
end
Either way here is the other two, I'll start testing and debugging on monday when I'm off work.
Infuser Program:
Spoiler
myidnum = 1
fillerItem = "minecraft:wooden_sword"
quantitydelimiter = "*"
recipefile = "recipes"
bridgechestdirection = {"north", "east", "south", "west"}
function trim(s)
return (s:gsub("^%s*(.-)%s*$", "%1"))
end
function split(s, delimiter)
result = {};
for match in (s..delimiter):gmatch("(.-)"..delimiter) do
table.insert(result, match);
end
return result;
end
function loadRecipes(filename)
file = fs.open(filename, "r")
data = file.readAll()
file.close()
return textutils.unserialize(data)
end
function grabItem(item)
local itemname, quantity
if item == nil or item == "" or item == "x" then
itemname = fillerItem
quantity = 1
else
table = split(item, quantitydelimiter)
if #table == 1 then
itemname = trim(table[1])
quantity = 1
elseif #table >= 2 then
itemname = trim(table[1])
quantity = tonumber(trim(table[2]))
else
itemname = fillerItem
quantity = 1
end
end
quantity = quantity - bridge.retrieve(itemname, quantity, bridgechestdirection[myidnum])
while quantity > 0 do
bridge.craft(itemname, quantity)
crafting = true
while crafting do
local event, name, amount, bytes = os.pullEvent("craftingComplete")
if name == itemname then
crafting = false
end
end
quantity = quantity - bridge.retrieve(itemname, quantity, bridgechestdirection[myidnum])
end
end
function infuse(modem, channel, recipes, recipenum)
redstone.setOutput("left", true)
local thisRecipe = recipes[recipenum]
for i = 1, #thisRecipe do
grabItem(thisRecipe[i])
end
sleep(20)
redstone.setOutput("left", false)
sleep(180)
redstone.setOutput("front", true)
sleep(2)
redstone.setOutput("front", false)
sleep(300)
redstone.setOutput("back", true)
sleep(10)
redstone.setOutput("back", false)
modem.transmit(channel, myidnum, "Infuser "..tostring(myidnum)..": Infusion complete.")
end
recipes = loadRecipes(recipefile)
modem = peripheral.wrap("top")
modem.open(myidnum)
bridge = peripheral.wrap("right")
escape = false
while escape == false do
listening = true
command = ""
replychannel
while listening do
local event, side, senton, replyon, message, distance = os.pullEvent("modem_message")
if senton == myidnum and replyon == 5 then
listening = false
command = message
replychannel = replyon
end
end
commandtable = split(trim(command), " ")
prefix = trim(commandtable[1])
if prefix == "infuse" then
recipenum = tonumber(trim(commandtable[2]))
infuse(modem, replychannel, recipes, recipenum)
end
end
Listener Program:
Spoiler
chat = peripheral.wrap("left")
screen = peripheral.wrap("back")
screen.clear()
recipefile = "recipes"
mytag = "infuser:"
screenlines = 2 * 4
function trim(s)
return (s:gsub("^%s*(.-)%s*$", "%1"))
end
function listen(mytag)
listening = true
while listening do
local event, name, text = os.pullEvent("chat")
start, stop = string.find(text, mytag)
if start ~= nil and start >= 0 then
return string.sub(text, stop + 1)
end
end
end
function load(filename)
file = fs.open(filename, "r")
data = file.readAll()
file.close()
return textutils.unserialize(data)
end
function save(filename, recipes)
file = fs.open(filename, "w")
data = textutils.serialize(recipes)
file.write(data)
file.close()
end
function write(screen, message)
screen.write(message)
x, y = screen.getCursorPos()
screen.setCursorPos(x + 1, y)
if (x + 1) >= screenlines
screen.scroll(1)
end
recipes = load(recipefile)
escape = false
while escape == false do
command = listen(mytag)
write(screen, "Command Heard:" .. command)
words = {}
for word in command:gmatch("%S+") do
table.insert(words, trim(word))
end
prefix = table.remove(words, 1)
if prefix == "save" then
save(recipefile)
write(screen, "Recipes saved.")
elseif prefix == "reload" then
recipes = load(recipefile)
write(screen, "Recipes loaded.")
elseif prefix == "add" then
newrecipe = {}
for i=1, #words do
table.insert(newrecipe, words[i])
end
table.insert(recipes, newrecipe)
write(screen, "Recipe added.")
elseif prefix == "remove" then
num = table.remove(words, 1)
table.remove(recipes, tonumber(num))
write(screen, "Recipe removed: " .. tostring(num))
elseif prefix == "read" then
num = tonumber(table.remove(words, 1))
if num > #recipes then
write(screen, "No such recipe...")
else
recipetoread = recipes[num]
for i = 1, #recipetoread do
write(screen, recipetoread[i])
end
write(screen, "End of recipe.")
end
end
end
And incase its helpful:
Manager tells each infuser what to make, making 4 things at once gives my system better throughput, might increase to 8 if I run into issues with speed
Infuser looks up recipe and grabs items then whacks runic matrix with a wand
Listener allows me to do ingame modification of my recipes for ease