This is a read-only snapshot of the ComputerCraft forums,
taken in April 2020.
How does one apply a timeout to read()
Started by tom2018, 29 October 2012 - 10:34 PMPosted 29 October 2012 - 11:34 PM
basically what the titles says how does one apply a timeout to read
Posted 30 October 2012 - 12:34 AM
Make a copy of the read function that starts a timer at the beginning, then listens for the event to fire.
Posted 30 October 2012 - 08:01 AM
or try this out, I got it to work but it is fairly complicated
the variable 'result' gets the read value
Edit: argh… doen't break when result has a value. does anyone know why this is?
a=coroutine.wrap(function() result=read() end)
local evts={}
os.startTimer(5)
while true do
if evts[1]=='timer' or result then break end
a(unpack(evts))
evts={os.pullEvent()}
end
the variable 'result' gets the read value
Edit: argh… doen't break when result has a value. does anyone know why this is?
Posted 30 October 2012 - 08:22 AM
ahah. got it. it was waiting for an event. if you submit the result and then press a key it finishes. I figured a better way though. compiled into a function too
EDIT: I made a function for running anything for a certain amount of time. go ahead and try it
local function readFor(time,char)
result=nil
a=coroutine.wrap(function() result=read(char) os.queueEvent('timer') end)
local evts={}
os.startTimer(time)
while true do
a(unpack(evts))
evts={os.pullEvent()}
if evts[1]=='timer' then break end
end
return result
end
EDIT: I made a function for running anything for a certain amount of time. go ahead and try it
local function runfor(func,timeout,tArgs)
local result=nil
local co=coroutine.wrap(function() os.queueEvent('done',func(unpack(tArgs or {}))) end)
local evt={}
local timer=os.startTimer(timeout)
while true do
co(unpack(evt))
evt={os.pullEvent()}
if evt[1]=='timer' then return 'timed out' elseif evt[1]=='done' then return evt[2] end
end
end
Posted 26 March 2016 - 11:33 AM
is there a way for it to end or break? as soon as someone inputted something?ahah. got it. it was waiting for an event. if you submit the result and then press a key it finishes. I figured a better way though. compiled into a function toolocal function readFor(time,char) result=nil a=coroutine.wrap(function() result=read(char) os.queueEvent('timer') end) local evts={} os.startTimer(time) while true do a(unpack(evts)) evts={os.pullEvent()} if evts[1]=='timer' then break end end return result end
EDIT: I made a function for running anything for a certain amount of time. go ahead and try itlocal function runfor(func,timeout,tArgs) local result=nil local co=coroutine.wrap(function() os.queueEvent('done',func(unpack(tArgs or {}))) end) local evt={} local timer=os.startTimer(timeout) while true do co(unpack(evt)) evt={os.pullEvent()} if evt[1]=='timer' then return 'timed out' elseif evt[1]=='done' then return evt[2] end end end
Edited on 26 March 2016 - 10:33 AM
Posted 27 March 2016 - 10:02 AM
parallel.waitForAny(result=read(), sleep(timeout))
Try this, continues then one of read or sleep finnish.Posted 27 March 2016 - 10:46 AM
is there a way for it to end or break? as soon as someone inputted something?
That seems to be what it's built to do. External timers may mess up the code you quoted, though.
Try this, continues then one of read or sleep finnish.parallel.waitForAny(result=read(), sleep(timeout))
Methinks you should take your own advice about "trying it".
Here's what you were going for:
local result
parallel.waitForAny(
function()
result = read()
end,
function()
sleep(30) --# Or whatever timeout you want.
end
)
if result then
--# Got input before the timeout.
else
--# Didn't.
end
If you wanted to gather whatever the user typed before the timeout, you'd indeed need a custom version of read(). But really it may be better to cancel the timeout if the user starts typing:
local result
parallel.waitForAny(
function()
result = read()
end,
function()
local myTimer = os.startTimer(30)
while true do
local myEvent = {os.pullEvent()}
if myEvent[1] == "timer" and myEvent[2] == myTimer then
break
elseif myEvent[1] == "char" then
os.pullEvent("yield forever")
end
end
end
)
if result then
--# Got input before the timeout.
else
--# Didn't.
end