18 posts
Posted 22 December 2012 - 12:17 PM
Im trying to write a sleep function that displays for the user how much time it has left. I got that part working so then I decided that it would be nice to let the user cancel sleeping if they wish. But the os.pullEvent seems to perminently freeze the program until input is detected. Is there some other way to make this work?
below is the code:
function sleepmode(duration)
repeat
term.clear()
term.setCursorPos(1,1)
print("Status - Sleeping... "..duration.."sec")
print("Press 'x' to cancel.")
local id, key = os.pullEvent("key")
if key == 45 then break end
sleep(1)
duration = duration-1
until duration < 0
end
Thanks alot for your help
767 posts
Posted 22 December 2012 - 12:35 PM
When calling os.pullEvent, it listen, until it is triggered. So it actually waits for the input, before it can countinue. So you
should use the parallel api, so it is counting, and waiting for input, at the same time:D i cant post any code, since im posting this on my phone :(/>
i Hope i could help :D/>
1214 posts
Location
The Sammich Kingdom
Posted 22 December 2012 - 12:39 PM
Look on the wiki for the usage of the parallel API that will "run two functions at once".(Not really. Just switches between them very fast.)
2005 posts
Posted 22 December 2012 - 12:41 PM
Set a timer event using
os.startTimer(), and don't specify the event to pull.
18 posts
Posted 22 December 2012 - 01:05 PM
ok looking up info for both parallel api and os.startTimer. Seems either way i need to write another function to make this work xD I got function on functions goin now =P let the experiments continue… =)
good thing turtles never get bored!
2088 posts
Location
South Africa
Posted 22 December 2012 - 01:30 PM
Using os.startTimer() should work, I haven't really used it but I
think this would work :P/>
function sleepmode(duration)
timer = os.startTimer(1)
repeat
term.clear()
term.setCursorPos(1,1)
print("Status - Sleeping... "..duration.."sec")
print("Press 'x' to cancel.")
local id, p1 = os.pullEvent()
if id == "key" and p1 == 45 then break
elseif id == "timer" and p1 == timer then
duration = duration-1
timer = os.startTimer(1)
end
until duration < 0
end
7508 posts
Location
Australia
Posted 22 December 2012 - 01:38 PM
When calling os.pullEvent, it listen, until it is triggered. So it actually waits for the input, before it can countinue. So you
should use the parallel api
The only reason it waits for input is because in OP it has os.pullEvent("key") so using parallel is not needed here, just a removal of "key"
In terms of getting it to work, remiX's solution WILL work. I use this method all the time over using the parallel api (no point using coroutines when they aren't needed for the solution).
EDIT: Also when timing is important between 2 functions (lets say updating a clock and accepting user input), its most of the time easier to use timers over the parallel api as parallel doesn't always get things timed perfectly. (and before anyone tries to debate this, I have tested it extensively and its small amounts each time, but that can eventually build up to a big difference in a program that needs perfect timing. when testing i found a large fluctuation in the amount of time the coroutine runs for, vs doing the timers with pull events, while still having a fluctuation, was much smaller. :)/> )
EDIT: Side note too, the sleep( ) function never perfectly sleeps for the time supplied, now i could go down to the assembly level programming and tell you why it doesn't but that would most likely bore you all, I'll just tell you that a 1 second timer loop in assembly is actually 0.999 (or if you prefer it in milliseconds 1000ms is actually 999ms)
Edited on 22 December 2012 - 12:53 PM
18 posts
Posted 22 December 2012 - 01:44 PM
Yey thats exactly what I was hoping! The function is sound and I dont think it needs to be compounded to make it work. So I cant call the event on an object! Thanks very much remiX and TOB
7508 posts
Location
Australia
Posted 22 December 2012 - 01:46 PM
So I cant call the event on an object!
What object?
18 posts
Posted 22 December 2012 - 01:49 PM
I meant I was setting it to something.. the value "key" which was my error.
7508 posts
Location
Australia
Posted 22 December 2012 - 01:51 PM
oh yeh, well it wasn't an error per-say, since pull event is designed to only pull a specified event, you were just doing something that caused the program not to run as expected.
18 posts
Posted 22 December 2012 - 02:02 PM
I pluged in remiX's solution and its works perfectly. It seemed that the timer function is set 2x so I thought I would have to change the code. but it counts down 1sec at a time even with the 2 calls. Not sure why thats working… lol but it is
edit: no never mind..it calls once before and then again for the next..its right
Im gonna be using this a whole lot xD thanks everyone
7508 posts
Location
Australia
Posted 22 December 2012 - 02:10 PM
yeh the timer needs to be started first outside the loop so an event is pulled then its just started again each time its pulled.
8543 posts
Posted 22 December 2012 - 10:34 PM
EDIT: Side note too, the sleep( ) function never perfectly sleeps for the time supplied, now i could go down to the assembly level programming and tell you why it doesn't but that would most likely bore you all, I'll just tell you that a 1 second timer loop in assembly is actually 0.999 (or if you prefer it in milliseconds 1000ms is actually 999ms)
That's probably far less relevant than the fact that only one computer is ever running at a time, so all sleep does is give you an approximate minimum wait time. If you were to sleep(1) and, while that computer was yielded, another computer refused to yield until it was forced to, that sleep wouldn't end for at least ten seconds. :)/>
7508 posts
Location
Australia
Posted 22 December 2012 - 11:16 PM
Yeh that too :P/>