Jump to content




How does one apply a timeout to read()


  • You cannot reply to this topic
6 replies to this topic

#1 tom2018

  • Members
  • 135 posts

Posted 29 October 2012 - 11:34 PM

basically what the titles says how does one apply a timeout to read

#2 Lyqyd

    Lua Liquidator

  • Moderators
  • 8,465 posts

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.

#3 KaoS

    Diabolical Coder

  • Members
  • 1,510 posts
  • LocationThat dark shadow under your bed...

Posted 30 October 2012 - 08:01 AM

or try this out, I got it to work but it is fairly complicated

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?

#4 KaoS

    Diabolical Coder

  • Members
  • 1,510 posts
  • LocationThat dark shadow under your bed...

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

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


#5 Duster

  • Members
  • 38 posts
  • LocationMassachusetts USA

Posted 26 March 2016 - 11:33 AM

View PostKaoS, on 30 October 2012 - 08:22 AM, said:

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

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
is there a way for it to end or break? as soon as someone inputted something?

Edited by Duster, 26 March 2016 - 11:33 AM.


#6 Stekeblad

  • Members
  • 62 posts
  • LocationSweden

Posted 27 March 2016 - 09:02 AM

parallel.waitForAny(result=read(), sleep(timeout))
Try this, continues then one of read or sleep finnish.

#7 Bomb Bloke

    Hobbyist Coder

  • Moderators
  • 7,099 posts
  • LocationTasmania (AU)

Posted 27 March 2016 - 09:46 AM

View PostDuster, on 26 March 2016 - 11:33 AM, said:

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.

View PostStekeblad, on 27 March 2016 - 09:02 AM, said:

parallel.waitForAny(result=read(), sleep(timeout))
Try this, continues then one of read or sleep finnish.

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






1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users