This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
Victor's profile picture

[Lua] How to launch a background program/function

Started by Victor, 12 February 2013 - 06:02 PM
Victor #1
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?
Lyqyd #2
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.
Victor #3
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.
InputUsername #4
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) ).
LBPHacker #5
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.
Victor #6
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.