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

os.pullEvent("timer") run in parallel doesn't work properly?

Started by Patric20878, 14 December 2013 - 12:49 AM
Patric20878 #1
Posted 14 December 2013 - 01:49 AM

function funcA()
  while true do
	os.pullEvent("timer")
	print("asdf")
  end
end
function funcB()
  while true do
	sleep(0.5)
  end
end

parallel.waitForAny(funcA,funcB)

The above test program executed in CC 1.33 prints "asdf" every 0.5 seconds instead of listening for a timer event on function a and sleeping constantly on function b. Both running the function by itself (not in parallel), and using os.pullEvent("redstone") instead makes it listen properly for the respective type of event. Is this a bug or am I missing something?

Edit: Seems like the sleep(0.5) triggers the timer event…how do you make os.pullEvent detect os.startTimer() but NOT sleep()? No solutions involving setting os.startTimer to a variable and checking if it matches os.pullEvent please, as that only filters input, not prevent detecting sleep().
Edited on 14 December 2013 - 01:09 AM
theoriginalbit #2
Posted 14 December 2013 - 02:00 AM
this is because sleep makes use of timers in order to function, because of this you need to make sure that you're checking for the timer that you want, like so


local timerId = os.startTimer(5)

repeat
  local _, id = os.pullEvent("timer")
until id == timerId

the above code will start a 5 second timer and only move on once the timer has completed, no matter any other timers that have occurred.
Edited on 14 December 2013 - 01:01 AM
Bomb Bloke #3
Posted 14 December 2013 - 02:24 AM
Edit: Seems like the sleep(0.5) triggers the timer event…how do you make os.pullEvent detect os.startTimer() but NOT sleep()? No solutions involving setting os.startTimer to a variable and checking if it matches os.pullEvent please, as that only filters input, not prevent detecting sleep().
Sleep is going to put timers in the event queue. Period. You may later run into other situations where timers are being set up by functions you didn't start "yourself"; it only stands to reason that you must make sure the ones expiring are the ones you want, instead of just waiting for "any old timer event".

Please don't respond to people by editing your prior posts. It makes for a confusing conversation.
Patric20878 #4
Posted 14 December 2013 - 02:24 AM
Hmm, pity. As said, identifying the event isn't a solution I want to use in my program. The program uses a timer to tell another function to start running in parallel and the idea with the generic timer event pull was to get as many as triggered, instead of overwriting the variable to hold it, thus resetting the timer.

Related: Is there a similar event type that can just be triggered from the code itself, and can be picked up by pullEvent? Something that just triggers a generic event (and doesn't take user input) so pullEvent can detect it?

@Bomb Bloke: that original post edit was before he answered. This post is the answer to his post. And reading your post, it sounds like "any old timer" event is exactly what I want, except sleep(). I don't want a specific one.
Edited on 14 December 2013 - 01:26 AM
Bomb Bloke #5
Posted 14 December 2013 - 02:27 AM
os.queueEvent() may be what you're after.
Patric20878 #6
Posted 14 December 2013 - 02:38 AM
Ah, that seems to be what I want…though on second look, is there any way to queue a nameless event? That again sets an event name, which can be overriden…but it shouldn't matter since pullEvent would pull the latest one, I think…

Edit: owait, the first parameter on queueEvent sets a custom event type, not a name? So it is nameless then?

On a tangent, if that's true, couldn't you also fake a "redstone" event too by queuing one? Wonder if I could overwrite rednet.send or something so when it sends a message, the event type is "asdjk" instead of "rednet_message"…
Edited on 14 December 2013 - 01:50 AM
Bomb Bloke #7
Posted 14 December 2013 - 02:46 AM
Sorry, you've lost me there - an event name that can be "overridden" how? Are you talking about the filter system built into os.pullEvent()? And why would you specifically want a "nameless" event, when you can simply ignore the name? It's not easy to provide answers without knowing the context of the questions.

If you want an event that can be picked up by os.pullEvent("timer"), then you queue an event with the name of "timer".

If you want an event that is not picked up by os.pullEvent("timer"), then you can queue an event with the name of "cabbage".

Bear in mind calling os.pullEvent() with no parameters will give you whatever event is next in the queue, regardless of name/type.
theoriginalbit #8
Posted 14 December 2013 - 02:49 AM
@Bomb Bloke: that original post edit was before he answered.
No it wasn't… My reply post time: 6:08PM … Your post edit time: 6:17PM
Edited on 14 December 2013 - 01:49 AM
Patric20878 #9
Posted 14 December 2013 - 03:01 AM
@theoriginalbit: Probably edited it before you posted, then edited it again for grammar after you posted. Either way, I edited it without knowing you replied, and put Edit: in case answerers are answering the unedited question.

@Bomb Bloke: I think your post answers the question. If I understand you correctly, queueEvent can queue an event type of anything, including actual ones such as redstone, rednet_message, timer, etc. Very handy command! Thanks for the info, and sorry for the confusion.

When I posted the original post, I couldn't just ignore the name, because then it picks up sleep() as well as named os.startTimer()'s. With queueEvent, the problem should be solved since I can now queue unique types of events. Would you take a look at my other question topic as well?

http://www.computerc...t-classiccc133/
Edited on 14 December 2013 - 02:11 AM