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

Sleep() changes behavior of os.pullEvent()

Started by Diver, 12 January 2013 - 12:56 PM
Diver #1
Posted 12 January 2013 - 01:56 PM
Hey Everyone,

I've got some troubles with one of my Programs and was able to track it down a little.

An Example:

while true do
test1,test2=os.pullEvent()
print(test1)
print(test2)
end
If i press e it prints key 18 and char e.
Just as it's supposed to do. :P/>

But if i add some Sleep-time like this:

while true do
test1,test2=os.pullEvent()
print(test1)
print(test2)
sleep(1)
end
it only prints key 18.

Is there any way to get the char value again without removing the sleep() ?

Using CC version 1.48
theoriginalbit #2
Posted 12 January 2013 - 02:02 PM
The reason this works without the sleep is most likely you are holding in the key for long enough to trigger the event twice…

You can get the char from the unlisted 'keys' API…

keys.getName( keyNum )
Diver #3
Posted 12 January 2013 - 02:21 PM
Thanks for the fast reply :)/>

This will help me alot, but i don't quite understand why it's switching between key and char in the first place.
theoriginalbit #4
Posted 12 January 2013 - 02:24 PM
Thanks for the fast reply :)/>

This will help me alot, but i don't quite understand why it's switching between key and char in the first place.
One of my slower replies ;)/>

Anything like tab, space, enter, etc doesn't have a char reference, so it would print the number… anything like a-z, A-Z, 1-9, etc have a char reference so it returns that…

EDIT: you can easily see which is which by doing this


event, p1 = os.pullEvent()

if event == "key" then

elseif event == "char" then

end
this could also become


event, p1 = os.pullEvent()

if event == "key" and p1 == keys.enter then

elseif event == "char" and p1 == "a" then

end
Edited on 12 January 2013 - 01:26 PM
Diver #5
Posted 12 January 2013 - 02:46 PM
One of my slower replies ;)/>
Ok thanks for your slower reply then :P/>

Anything like tab, space, enter, etc doesn't have a char reference, so it would print the number… anything like a-z, A-Z, 1-9, etc have a char reference so it returns that…

Thats what i thought but as soon i add a sleep somewhere in the while, the event will never be a char, no matter what key i press.
But nevermind… got my program working again, thanks to you. ;)/>
theoriginalbit #6
Posted 12 January 2013 - 02:52 PM
- snip -
Thats what i thought but as soon i add a sleep somewhere in the while, the event will never be a char, no matter what key i press.
But nevermind… got my program working again, thanks to you. ;)/>
Thats interesting…… I have never encountered this before… mind you I never use sleep though…
Ok cool :)/>

EDIT: Also if your planning on doing something with the char, make sure that the getName value isn't nil first… have a look at the keys api to understand what I mean…
Aichan #7
Posted 12 January 2013 - 02:54 PM
<Cloudy> sleep() eats events
<Cloudy> if you care about events, yo ushouldn't use that
Lyqyd #8
Posted 12 January 2013 - 03:00 PM
<Cloudy> sleep() eats events
<Cloudy> if you care about events, yo ushouldn't use that

This is correct, though could use further explanation. Quoting IRC chat, however accurate, isn't always the most helpful answer. ;)/>

Each key except escape will send a "key" event when pressed. A subset of these, the keys which are associated with printable characters, also send a "char" event, immediately after the key event. Usually, you can use the char event no problem, but if you have a sleep in an event-pulling loop, it will eat the char event associated with the key event (since it is itself a loop that waits for a specific event and discards all others). In order for this not to happen, you can either use the key event generated for the character (inadvisable if you want to write your character to a string, since it means a lot more work), or replace your sleep call with the use of a timer to perform whatever actions are necessary after the sleep. Use os.startTimer(time) to start a timer, which will throw a "timer" event when it fires. You should also store the number that os.startTimer() returns, as it will be the ID of the timer, and show up as the first parameter for the "timer" event. In this way, you can make sure that you are acting upon the correct timer.
Diver #9
Posted 12 January 2013 - 03:09 PM
Alright,
i'll try to use timers from now on ;)/>

Thanks to everyone.