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

Coroutine bug

Started by alakazard12, 01 April 2013 - 10:39 AM
alakazard12 #1
Posted 01 April 2013 - 12:39 PM
I noticed this bug back in Minecraft 1.2.5, and it still hasn't been fixed. When you add pullEvent in a coroutine it just stops.

Here is an example (I used sleep, which uses os.pullEvent("timer"))


coroutine.resume(coroutine.create(function()
    sleep(1)
    -- Rest of the code it never gets to
    print("It worked!")
end))

Sometimes this bug gets annoying when I'm creating programs that need it.
Cloudy #2
Posted 01 April 2013 - 01:06 PM
Learn how coroutines work, and how os.pullEvent works.
MysticT #3
Posted 01 April 2013 - 01:09 PM
When you call coroutine.yield (called by os.pullEvent), the coroutine yields until you resume it. So, this is expected behaviour (and it is not some CC thing, that's how lua works).
alakazard12 #4
Posted 01 April 2013 - 01:33 PM
Learn how coroutines work, and how os.pullEvent works.

I know everything about how coroutines work, but I didn't know exactly everything about os.pullEvent.
JokerRH #5
Posted 01 April 2013 - 02:04 PM
The way coroutines work is one coroutine runs until it yields so that anotherone can run…(the're not parallel)
Every CC computer is a coroutine, and it get's its events by yielding.
So instead of os.pullEventRaw(filter) you can use coroutine.yield(filter), too (pullEventRaw simply calls that function).
For you that means whenever your coroutine yields you have to resume it with an event.


while coroutine.status(yourCoroutine) ~= "dead" do
  filter = coroutine.resume(yourCoroutine, coroutine.yield(filter))
end

So it's not a bug, it's intended :P/>
theoriginalbit #6
Posted 01 April 2013 - 04:02 PM
To extend on what JokerRH said…….

You will want to store your coroutine (when you create it) in a variable, that way you can resume it later…. as opposed to creating it in the resume function call…

Some simple code
Spoiler

routineForSomething = coroutine.create(run) -- create it
coroutine.resume(routineForSomething) -- inital run so it can get to the yield


local function run() -- this is the function that the create is passed the pointer for
  while true do
    local event = { coroutine.yield() } -- waits here until I resume it
  end
end

-- I resume it with this every time I want it to run

function resume()
  coroutine.resume(routineForSomething, os.pullEvent())
end


So it's not a bug, it's intended :P/>
I wouldn't even say that "its intended" makes it sound like its an 'intended bug'… "its how coroutines work" might be better :P/>
Lyqyd #7
Posted 01 April 2013 - 08:22 PM
Moved to Ask a Pro.

I know everything about how coroutines work

Clearly not.
alakazard12 #8
Posted 03 April 2013 - 02:15 PM
Moved to Ask a Pro.

I know everything about how coroutines work

Clearly not.

Did you not read my full post? I know everything about how coroutine works, BUT NOT pullEVENT, learn to read.
JokerRH #9
Posted 03 April 2013 - 02:28 PM
Did you not read my full post? I know everything about how coroutine works, BUT NOT pullEVENT, learn to read.
…be careful. Never start a discussion with a moderator, you will always lose :D/>/>
But if you know everything about coroutines why didn't you wonder that the coroutine would never yield if pullEvent
wouldn't do that and 2. why didn't you resume it? :P/>/>
theoriginalbit #10
Posted 03 April 2013 - 04:26 PM
Did you not read my full post? I know everything about how coroutine works, BUT NOT pullEVENT, learn to read.
Wow your risking it. talking to a moderator like that.

We can all read, and from what we are reading, you don't know how to use coroutines. and if you actually look at the code that I posted before you will read that the os.pullEvent is not even anywhere in the coroutine code, the parameters returned from it are given to the coroutine to process, but that is it. really you don't even need the pullEvent there, if you're coroutine is always doing the exact same thing you could have this

function resume()
  coroutine.resume(routineForSomething, 'doThis', doThat, 5, 6, 8) -- do this is a string, do that a function pointer, the rest are numbers...
end
although i don't ever see a reason why you would need a coroutine to do stuff with hard coded values, but hey, some people might have some ideas.

EDIT: It just occurred to me that you may be meaning that you actually have no idea what so ever what os.pullEvent and os.pullEventRaw actually do. so in that case I ask you, what was even the point of posting that it was a bug in coroutines in the "Bugs" section of the forums, instead of just asking here in the "Ask a Pro" section what the pullEvents are?
And in the event that you do not know what it is, I will give you this link to the wiki
Edited on 03 April 2013 - 02:40 PM
Lyqyd #11
Posted 04 April 2013 - 08:57 AM
Moved to Ask a Pro.

I know everything about how coroutines work

Clearly not.

Did you not read my full post? I know everything about how coroutine works, BUT NOT pullEVENT, learn to read.

I read your full post. I know exactly what you wrote. You're either far too overconfident in your supposed knowledge of coroutines, or you're an idiot. Judging by your replies, I'm leaning toward the latter.

If you knew even the first thing about coroutines, you'd know that they need to be resumed repeatedly, as that is the whole purpose behind them (otherwise, you might as well have called the function instead). You should also be aware of the "too long without yielding" error, and know what fixes it (commonly being sleep()). It's no huge leap to realize that something in sleep() must be yielding! Further investigation reveals os.pullEvent, which leads to os.pullEventRaw, which takes us to… coroutine.yield. So, given these two pieces of very basic information, it is very easy to draw the conclusion that you haven't got a single clue what coroutines are, how they work, or how, when, and why to use them.