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

Pull event without yelding?

Started by Nix, 26 October 2012 - 12:17 PM
Nix #1
Posted 26 October 2012 - 02:17 PM
Is it possible to pull an event without yelding the PC (like an os.pullEvent that returns nil if no event is in the queue) or even to read the event queue maually to implement the former?
PixelToast #2
Posted 26 October 2012 - 02:23 PM
no its not, it yields till it gets an event, thats the whole point in having a coroutine anyway, what would you need this for?
Ditto8353 #3
Posted 26 October 2012 - 02:23 PM
os.pullEvent is based off os.pullEventRaw
os.pullEventRaw consists of a single line of code, unfortunately for you that line is return coroutine.yield
Ditto8353 #4
Posted 26 October 2012 - 02:26 PM
However! You can try the following!
local evtTimeout = os.startTimer(0.05) //Single-Tick Timer
local evt = {os.pullEvent()}
if evt[2] == evtTimeout then
   //Event Timeout
end
Nix #5
Posted 26 October 2012 - 02:43 PM
That's a clever way to solve the problem, Ditto. Thanks! ^^
Ditto8353 #6
Posted 26 October 2012 - 02:47 PM
That's a clever way to solve the problem, Ditto. Thanks! ^^
D'Awww! :3 Well thank you, but it does still yield, and you may have to change the timing (I've never actually done this).
Nix #7
Posted 26 October 2012 - 02:57 PM
I would have to make the loop sleep, I hope that works too
Orwell #8
Posted 26 October 2012 - 03:11 PM
I would have to make the loop sleep, I hope that works too

Sleep yields too. :D/>/> (it's basically os.setTimer(t) and os.pullEvent('timer') if I'm not mistaken)
Cloudy #9
Posted 26 October 2012 - 03:15 PM
And sleep eats events. Why do you need this anyway? Chances are you're over complicating things.
Orwell #10
Posted 26 October 2012 - 03:18 PM
After reading the OP again. Can't you just use the parallel API to run a coroutine that pulls events and adds them to an internal queue. Then from another coroutine you can just check that internal queue for (all) new events without yielding (and waiting). You'd still want to yield now and then in that coroutine though. :D/>/>
KaoS #11
Posted 26 October 2012 - 03:29 PM
simply do Orwell's idea with only one coroutine


local tQueue={}
local queuer=coroutine.wrap(function() while true do tQueue[#tQueue+1]={os.pullEvent()} end end)
local function pull()
  return table.remove(tQueue,1)
end

unfortunately you will need to make your code a coroutine too though
Nix #12
Posted 26 October 2012 - 03:31 PM
I would have to make the loop sleep, I hope that works too

Sleep yields too. :D/>/> (it's basically os.setTimer(t) and os.pullEvent('timer') if I'm not mistaken)
I know, I mean: if I didn't yeld it for a while, the script would stop: "too long without yelding"

And sleep eats events. Why do you need this anyway? Chances are you're over complicating things.
What do you mean, "Sleep eats events"?

After reading the OP again. Can't you just use the parallel API to run a coroutine that pulls events and adds them to an internal queue. Then from another coroutine you can just check that internal queue for (all) new events without yielding (and waiting). You'd still want to yield now and then in that coroutine though. :)/>/>
Ehrm… I think "my" (Thanks again, Ditto) way is simpler, so I prefer it ^^'
Ditto8353 #13
Posted 26 October 2012 - 03:35 PM
Sleep yields too. :D/>/> (it's basically os.setTimer(t) and os.pullEvent('timer') if I'm not mistaken)
Huh… That's good to know (I just checked and you are correct).
It starts a timer and then pulls events until it gets that timer.
Basically it's intercepting events from being passed to the calling program until the timer ends.
Lyqyd #14
Posted 26 October 2012 - 03:45 PM
Sleep eats events. If you start a five-second sleep, any and all events that the program would have otherwise received during those five seconds will be discarded by the sleep function waiting for its timer event to fire.
Nix #15
Posted 26 October 2012 - 04:13 PM
Ok, thank all of you
KaoS #16
Posted 26 October 2012 - 04:30 PM
Sleep eats events. If you start a five-second sleep, any and all events that the program would have otherwise received during those five seconds will be discarded by the sleep function waiting for its timer event to fire.

if you have a simultaneous coroutine listening it will still be recorded though
Lyqyd #17
Posted 26 October 2012 - 05:49 PM
Sleep eats events. If you start a five-second sleep, any and all events that the program would have otherwise received during those five seconds will be discarded by the sleep function waiting for its timer event to fire.

if you have a simultaneous coroutine listening it will still be recorded though

Sleep eats events. If you start a five-second sleep, any and all events that the program would have otherwise received during those five seconds will be discarded by the sleep function waiting for its timer event to fire.

As you can see, I am well aware of that fact. An easy way to demonstrate this is to use bundled cable rednet to send a large message to a computer, then have the receiving computer sleep for a short time when the message starts being received. The rednet.run() function, running in parallel with the shell, will still see all of the events come in, despite the other program sleeping.
KaoS #18
Posted 26 October 2012 - 06:12 PM
erm, ok… I must have misunderstood. I apologize
Lyqyd #19
Posted 26 October 2012 - 07:52 PM
erm, ok… I must have misunderstood. I apologize

No, you were correct, I was simply stating that it had already been said. I then provided an easy example to see it in action.