Jump to content




Coroutines?


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

#1 sci4me

  • Members
  • 225 posts
  • LocationEarth

Posted 06 September 2013 - 10:03 PM

Hey guys! So, I am trying to make a background "thread" to handle adding and removing devices, and the code works, but the coroutine doesnt actually run.. can someone explain how to do this?

if not fs.exists("dev") then
fs.makeDir("dev")
end

local deviceCoroutine = coroutine.create(function()
while true do
evt, side = os.pullEvent()
if evt == "peripheral" then 
local f = fs.open("dev/"..side, "w")
f.close()
end
if evt == "peripheral_detach" then
fs.delete("dev/"..side)
end
end
end)
coroutine.resume(deviceCoroutine)


#2 Kingdaro

    The Doctor

  • Members
  • 1,636 posts
  • Location'MURICA

Posted 06 September 2013 - 10:13 PM

Once you resume the coroutine, os.pullEvent() yields it, and it never gets resumed again.

You need to run that coroutine alongside other coroutines in an event loop, and resume each of those coroutines with said events. Look at how the parallel API works for an example.

#3 sci4me

  • Members
  • 225 posts
  • LocationEarth

Posted 06 September 2013 - 10:25 PM

Aah, I think I see. Let me try that.

Okay, just FYI, I am using a very barebones system - deleted rom and reduced bios. For the challenge. I have copied over some of the api code. I have the parallel api. I have this code here:

local deviceCoroutine = coroutine.create(function()
while true do
evt, side = os.pullEvent()
if evt == "peripheral" then 
local f = fs.open("dev/"..side, "w")
f.close()
end
if evt == "peripheral_detach" then
fs.delete("dev/"..side)
end
end
end)

waitForAny(
function()
print("Welcome to SciNux V"..os.version().." HC Edition!")
end,
function()
while true do
coroutine.resume(deviceCoroutine)
end
end )

Thats not what you meant is it? Because it doesnt do the trick..

#4 LBPHacker

  • Members
  • 766 posts
  • LocationBudapest, Hungary

Posted 07 September 2013 - 01:17 AM

View Postsci4me, on 06 September 2013 - 10:25 PM, said:

-snip-
Almost. But I think that errors out with "too long without yielding" (you might not be able to actually see that). That's because the second coroutine in .waitForAny runs infinitely (because of the while true do and the lack of anything that'd yield it). Do not make a coroutine of your device handling function, that's the task of the parallel API (if you decide to use it). Just have a function that handles devices:
local deviceHandler = function(...)
    -- do that what you did up there in your code
end

local theOhterOne = function(...)
    -- here runs the OS - I highly suggest to define this function here, not inside .waitForAny
    -- that would make no technical difference, but (at least for me) the code would look cleaner
end

parallel.waitForAny(deviceHandler, theOtherOne) -- .waitForAny will take care of the functions


#5 sci4me

  • Members
  • 225 posts
  • LocationEarth

Posted 07 September 2013 - 01:56 AM

View PostLBPHacker, on 07 September 2013 - 01:17 AM, said:

View Postsci4me, on 06 September 2013 - 10:25 PM, said:

-snip-
Almost. But I think that errors out with "too long without yielding" (you might not be able to actually see that). That's because the second coroutine in .waitForAny runs infinitely (because of the while true do and the lack of anything that'd yield it). Do not make a coroutine of your device handling function, that's the task of the parallel API (if you decide to use it). Just have a function that handles devices:
local deviceHandler = function(...)
	-- do that what you did up there in your code
end

local theOhterOne = function(...)
	-- here runs the OS - I highly suggest to define this function here, not inside .waitForAny
	-- that would make no technical difference, but (at least for me) the code would look cleaner
end

parallel.waitForAny(deviceHandler, theOtherOne) -- .waitForAny will take care of the functions

local deviceHandler = function()
while true do
evt, side = os.pullEvent()
if evt == "peripheral" then 
local f = fs.open("dev/"..side, "w")
f.close()
end
if evt == "peripheral_detach" then
fs.delete("dev/"..side)
end
end
end

local os = function()
print("SciNux V"..os.version().." HC Edition"
end

waitForAny(deviceHandler, os)

Prints nothing, I assume its the too long without yielding? but that doesnt really make sense...

#6 LBPHacker

  • Members
  • 766 posts
  • LocationBudapest, Hungary

Posted 07 September 2013 - 03:58 AM

  • When I say ".waitForAny" (note the dot), I of course mean parallel.waitForAny
  • The print in the os function misses a closing parenthesis at the end of the line
  • Don't overwrite os
  • The os function returns immediately, breaking the loop in .waitForAny


#7 immibis

    Lua God

  • Members
  • 1,033 posts
  • LocationWellington, New Zealand

Posted 07 September 2013 - 07:59 AM

View PostLBPHacker, on 07 September 2013 - 03:58 AM, said:

  • When I say ".waitForAny" (note the dot), I of course mean parallel.waitForAny
  • The print in the os function misses a closing parenthesis at the end of the line
  • Don't overwrite os
  • The os function returns immediately, breaking the loop in .waitForAny
He deleted bios and all of rom (as a challenge?)

Did you copy print?

#8 sci4me

  • Members
  • 225 posts
  • LocationEarth

Posted 07 September 2013 - 03:27 PM

Yeah I copied all the functions that I am using (print, waitForAny) so.. not sure..

Yes immibis its as a challenge :D Kind of fun actually.

Also, I cant seem to figure out how to use the http api natively... http and http.native are both nil... with http enabled in the config...
EDIT: its a table of length 0...

Well, with a tish of investigation, I have the http working :P /lua noob

#9 theoriginalbit

    Semi-Professional ComputerCrafter

  • Moderators
  • 7,332 posts
  • LocationAustralia

Posted 08 September 2013 - 04:26 AM

Unless you copied waitForAll/Any into the bios then it wont be in the global scope and you'll need to do an API call.

Really as more of a challenge you should not use code from the parallel API and make your own Coroutine Management API :P Thats what I did to get a better understanding of how coroutines work.

View Postsci4me, on 07 September 2013 - 03:27 PM, said:

EDIT: its a table of length 0...
From now on use a function like this to count all elements in a table
local function count( t )
  local c = 0
  for _ in pairs(t) do
    c = c + 1
  end
  return c
end






2 user(s) are reading this topic

0 members, 2 guests, 0 anonymous users