8 posts
Posted 12 February 2013 - 07:02 PM
Title [Lua] How to launch a background program/function
Hello, I'm relatively new to programming, let alone Lua, so a little help is appreciated. I'm working on a server program that will constantly keep an active communication with multiple turtles and get information. I've set up a coroutine system that regulates the data flow but I can't figure out how to keep that certain loop active constantly behind the scenes.
The real problem is I can't get my program to communicate when I call a read or os.pullEvent on my main function. I've tried using parallel api but it doesn't seem to launch 2 functions at the same time like it is stated. I've set up simple tests and observed that parallel api also hangs when one of the functions calls for a read and suspends the second function.
I've seen programs and apis that does multi tasking. I can very well use them but I want to learn. I don't want anyone to hold my hand but it's like I'm missing something here. Can anybody help with an explanation?
TLDR: How to run a constant function in the background which communicates via rednet and continuously modifies globals that main function uses time to time?
8543 posts
Posted 13 February 2013 - 03:41 AM
Parallel does run two or more functions "simultaneously". It would not block rednet traffic to one coroutine while the other was yielded in a read or pullEvent call. Let's see the code you tried.
8 posts
Posted 13 February 2013 - 04:59 AM
request = coroutine.create(function ()
while true do
for x = 1,table.getn(reg) do
rednet.send(reg[x].turtleid,"req")
end
coroutine.resume(control)
end
end)
control = coroutine.create(function ()
while true do
local turtid local msg
while true do
local tab = {}
turtid, msg = rednet.receive(4)
if msg then
tab = textutils.unserialize(msg)
for x = 1,table.getn(reg) do
if turtid == reg[x].turtleid then
local tur = { name = reg[x].name, turtleid = turtid, location = tab[2], fuellevel = tab[1] }
table.remove(reg, x)
table.insert(reg, tur)
rednet.send(turtid,"got")
break
else
break
end
end
end
end
coroutine.yield()
end
end)
function testmain()
while true do
local m = read()
print(m)
end
end
function test()
coroutine.resume(request)
end
parallel.waitForAll(testmain(), test())
reg is the table that I use to store all turtles' info. Basically 'request' sends every turtle in the reg table a request and then resumes control. Control recieves the info and replaces the old info in the table with the new one for each turtle until recieve(4) times out in which case control yields and request runs again. This is an infinite loop and the reason I made 2 coroutines for this is to in the future add a control switch to the 'control' to block or delay its yield if certain conditions are met in the main function.
The problem is when I use parallel.waitForAny with 2 functions, first one being my main function and second being a function simply resumes(starts) 'request', the second one never works because my main function never returns. When I test it by replacing the main function with a simple infinite loop read() func(like in the code), again the second function(hence the coroutines) never start. I can't seem to run them simultaneously.
Thanks.
edit: Forgot some code.
252 posts
Location
The Netherlands
Posted 13 February 2013 - 05:39 AM
Spoiler
request = coroutine.create(function ()
while true do
for x = 1,table.getn(reg) do
rednet.send(reg[x].turtleid,"req")
end
coroutine.resume(control)
end
end)
control = coroutine.create(function ()
while true do
local turtid local msg
while true do
local tab = {}
turtid, msg = rednet.receive(4)
if msg then
tab = textutils.unserialize(msg)
for x = 1,table.getn(reg) do
if turtid == reg[x].turtleid then
local tur = { name = reg[x].name, turtleid = turtid, location = tab[2], fuellevel = tab[1] }
table.remove(reg, x)
table.insert(reg, tur)
rednet.send(turtid,"got")
break
else
break
end
end
end
end
coroutine.yield()
end
end)
function testmain()
while true do
local m = read()
print(m)
end
end
function test()
coroutine.resume(request)
end
parallel.waitForAll(testmain(), test())
reg is the table that I use to store all turtles' info. Basically 'request' sends every turtle in the reg table a request and then resumes control. Control recieves the info and replaces the old info in the table with the new one for each turtle until recieve(4) times out in which case control yields and request runs again. This is an infinite loop and the reason I made 2 coroutines for this is to in the future add a control switch to the 'control' to block or delay its yield if certain conditions are met in the main function.
The problem is when I use parallel.waitForAny with 2 functions, first one being my main function and second being a function simply resumes(starts) 'request', the second one never works because my main function never returns. When I test it by replacing the main function with a simple infinite loop read() func(like in the code), again the second function(hence the coroutines) never start. I can't seem to run them simultaneously.
Thanks.
edit: Forgot some code.
I don't wan't to sound annoying and I don't know anything about coroutines and such, but when using the parallel API, you have to provide the functions without parentheses ( parallel.waitForAll(testmain, test) ).
758 posts
Location
Budapest, Hungary
Posted 13 February 2013 - 05:59 AM
I don't wan't to sound annoying and I don't know anything about coroutines and such, but when using the parallel API, you have to provide the functions without parentheses ( parallel.waitForAll(testmain, test) ).
Yup - when you call parallel.waitForAll(something1(), something2()), something1 will be executed and its return value will be passed to .waitForAll. And since testmain has an infinite loop in it, it won't return.
8 posts
Posted 13 February 2013 - 08:19 AM
I don't know how I missed that. I had got some quirks with the code too but now I fixed them and it's working. Thanks.