Jump to content




parallel API workaround


  • You cannot reply to this topic
7 replies to this topic

#1 Milchschokolade

  • New Members
  • 1 posts

Posted 20 June 2013 - 01:01 PM

I am writing a custom Program to control my entire Base via rednet. To do this, I want to have the main program running useing coroutines to pause and resume different functions while the computer is also waiting for an event to happen. If an evvent occurs, the currently running coroutine is supposed to run until it hits coroutine.yield() before the program reacts to the occured event. I first looked into the parallel API and used that in my Code, but after reading a bit more in the wiki and this Forum, I found out, that the parallel API itsself is useing Coroutines which means, that it would probably mess up with the rest of my program. Now I am looking for a way to work around this. Most important is, not to loose an occuring Event. I have all coroutines, that are not dead in an array co={}.
The loop function is not yet finished, but it will handle my coroutines. I am looking for a way to work around the parallel API so I don't loose either the state of my coroutines nor an event, Please, help me...
--[Main Program]--
local function event()
  e,p1,p2,p3,p4,p5=os.pullEvent()
  occ=="event"
  return e
end

--this function is part of the main program
--it gives the Main loop to control everything
function loop()
while true do
  if co[1]==0 then
	co[2]=coroutine.create(home())
	co[1]=1
  end
  for local coi=1,co[1] do
	coroutine.resume(co[coi+1])


  end
end
occ="loop"
end
while true do
  --checking for any occurance (event or feedback from the loop)
  parallel.waitForAny(event(),loop())
  --the next part of code decides how to handle the occurance
--not yet implemented
end

Complete Code:
Spoiler


#2 Lyqyd

    Lua Liquidator

  • Moderators
  • 8,465 posts

Posted 20 June 2013 - 01:12 PM

Split into new topic.

#3 ElvishJerricco

  • Members
  • 803 posts

Posted 20 June 2013 - 01:23 PM

I don't understand what it is you lose by using the parallel API. BTW, in the code posted above, you using parallel.waitForAny wrong. You pass it the functions you want to wait for, you don't call them.

parallel.waitForAny(event, loop) -- right
parallel.waitForAny(event(), loop()) -- wrong


#4 Bomb Bloke

    Hobbyist Coder

  • Moderators
  • 7,099 posts
  • LocationTasmania (AU)

Posted 20 June 2013 - 05:22 PM

The idea is that both co-routines run until they want to pull events. When they do, both co-routines end up getting both events.

Speaking as one who doesn't know what you want to do with this program, probably the easiest implementation is to rig things so that neither function ends. Eg:

--[Main Program]--
local function event()
  while true do
    e,p1,p2,p3,p4,p5=os.pullEvent()
    -- You probably want to put some "reactions" to the events here. Eg:
    -- if e == "timer" then waiting = false end
  end
end

--this function is part of the main program
--it IS the Main loop to control everything
local function loop()
  while true do
    -- Do "occurance handling" stuff here based on whatever e,p1,p2,etc are set to at the time.
    -- Feel free to use event-consumers like read() and turtle.forward() etc.
  end
end

local e,p1,p2,p3,p4,p5 = "","","","","",""
parallel.waitForAny(event,loop)


#5 ElvishJerricco

  • Members
  • 803 posts

Posted 20 June 2013 - 06:23 PM

View PostBomb Bloke, on 20 June 2013 - 05:22 PM, said:

The idea is that both co-routines run until they want to pull events. When they do, both co-routines end up getting both events.

Speaking as one who doesn't know what you want to do with this program, probably the easiest implementation is to rig things so that neither function ends. Eg:

--[Main Program]--
local function event()
  while true do
    e,p1,p2,p3,p4,p5=os.pullEvent()
    -- You probably want to put some "reactions" to the events here. Eg:
    -- if e == "timer" then waiting = false end
  end
end

--this function is part of the main program
--it IS the Main loop to control everything
local function loop()
  while true do
    -- Do "occurance handling" stuff here based on whatever e,p1,p2,etc are set to at the time.
    -- Feel free to use event-consumers like read() and turtle.forward() etc.
  end
end

local e,p1,p2,p3,p4,p5 = "","","","","",""
parallel.waitForAny(event,loop)

FYI what you have here won't put the event data into the locals declared near the bottom. For a function to use and upper local, it has to be declared before the function.

Anyway the best way to use parallel is to create functions that each individually act as event receivers.

parallel.waitForAny(function()
    while true do
        local eventTable = { os.pullEvent() }
        -- do something with the event
    end
end, function()
    while true do
        local eventTable = { os.pullEvent() }
        -- do something else. Both functions are getting the same event.
    end
end)


#6 theoriginalbit

    Semi-Professional ComputerCrafter

  • Moderators
  • 7,332 posts
  • LocationAustralia

Posted 20 June 2013 - 11:15 PM

I completely agree with Bomb Bloke. I am unsure what you're trying to do exactly, but rigging your functions correctly so they don't end, or using parallel.waitForAll if you do want some to end, is your best bet. If these are not what you want to do then you will have to be a little clearer with what you want.

View PostElvishJerricco, on 20 June 2013 - 06:23 PM, said:

Anyway the best way to use parallel is to create functions that each individually act as event receivers.

parallel.waitForAny(function()
	while true do
		local eventTable = { os.pullEvent() }
		-- do something with the event
	end
end, function()
	while true do
		local eventTable = { os.pullEvent() }
		-- do something else. Both functions are getting the same event.
	end
end)
That is exactly the same code as what Bomb Bloke posted except that it uses anonymous functions, which can be quite bad for readability....

#7 ElvishJerricco

  • Members
  • 803 posts

Posted 21 June 2013 - 01:54 AM

View Posttheoriginalbit, on 20 June 2013 - 11:15 PM, said:

That is exactly the same code as what Bomb Bloke posted except that it uses anonymous functions, which can be quite bad for readability....

Right I was just... I don't really know what I was thinking. Sorry bout that.

#8 GopherAtl

  • Members
  • 888 posts

Posted 21 June 2013 - 06:07 AM

your code had one important fix that seems to be getting overlooked. Bomb's loop function did not ever wait for events; it's important that all coroutines do this, or you'll get failure to yield. They'd don't necessarily have to call pullEvent directly, but it's a bit more than allowed to call functions that eat events; you absolutely must be calling functions that yield and wait for events almost continuously to avoid getting terminated for a failure to yield.





2 user(s) are reading this topic

0 members, 2 guests, 0 anonymous users