Register forum user name Search FAQ

Gammon Forum

Notice: Any messages purporting to come from this site telling you that your password has expired, or that you need to verify your details, confirm your email, resolve issues, making threats, or asking for money, are spam. We do not email users with any such messages. If you have lost your password you can obtain a new one by using the password reset link.
 Entire forum ➜ MUSHclient ➜ Lua ➜ Waiting for text to arrive from the MUD, with a timeout

Waiting for text to arrive from the MUD, with a timeout

It is now over 60 days since the last post. This thread is closed.     Refresh page


Posted by Nick Gammon   Australia  (23,120 posts)  Bio   Forum Administrator
Date Sat 15 Oct 2005 06:13 AM (UTC)

Amended on Sun 23 Oct 2005 09:21 PM (UTC) by Nick Gammon

Message
After reading the posts about speedwalks which wait for you to move from room to room, I thought it might be handy to have a way of building into a script the ability to wait for a line to arrive (eg. Exits: north west) OR a time limit to elapse (eg. 10 seconds).

That way, a script could terminate itself if the desired line did not arrive in a reasonable time.

To do this, the relevant part of the exampscript.lua file has been modified, as below. Lines which have changed are in bold.

Now you can supply an optional timeout argument to the calls to waitforregexp or waitfor. This is the number of seconds to wait.

The functions do this by adding a trigger and a timer. If the trigger fires, it has "send to script" set to delete the corresponding timer. If the timer fires, it deletes the trigger.

In both cases, the thread is resumed. However the return from the resume will indicate whether it timed out or not.



-- ----------------------------------------------------------
-- table of outstanding threads that are waiting
-- ----------------------------------------------------------
wait_table = {}

-- ----------------------------------------------------------
-- called by a timer to resume a thread
-- ----------------------------------------------------------
function wait_timer_resume (name)
  thread = wait_table [name]
  if thread then
    assert (coroutine.resume (thread))
  end -- if
end -- function wait_timer_resume 

-- ----------------------------------------------------------
-- called by a trigger to resume a thread
-- ----------------------------------------------------------
function wait_trigger_resume (name, line, wildcards)
  EnableTrigger (name, false)  -- don't want it to fire again
  DoAfterSpecial (1, "DeleteTrigger ('" .. name .. "')", 12) -- delete it
  thread = wait_table [name]
  if thread then
    assert (coroutine.resume (thread, line, wildcards))
  end -- if
end -- function wait_trigger_resume 


-- ----------------------------------------------------------
-- we call this to wait in a script
-- ----------------------------------------------------------
function wait (thread, seconds, id)
  id = id or "wait_" .. GetUniqueNumber ()
  hours = math.floor (seconds / 3600)
  seconds = seconds - (hours * 3600)
  minutes = math.floor (seconds / 60)
  seconds = seconds - (minutes * 60)
  status = AddTimer (id, hours, minutes, seconds, 
            "DeleteTrigger ('" .. id .. "')",
            timer_flag.Enabled + timer_flag.OneShot + 
            timer_flag.Temporary + timer_flag.Replace, 
            "wait_timer_resume")
  assert (status == error_code.eOK, error_desc [status])
  SetTimerOption (id, "send_to", "12")  -- send to script
  wait_table [id] = thread
  return coroutine.yield ()
end -- function wait

-- ----------------------------------------------------------
-- we call this to wait for a trigger with a regexp
-- ----------------------------------------------------------
function waitforregexp (thread, regexp, timeout)
  local id = "wait_" .. GetUniqueNumber ()
  status = AddTriggerEx (id, regexp, 
            "DeleteTimer ('" .. id .. "')",  -- script to delete the timeout timer
            trigger_flag.Enabled + trigger_flag.RegularExpression + 
            trigger_flag.Temporary + trigger_flag.Replace, 
            custom_colour.NoChange, 
            0, "",  -- wildcard number, sound file name
            "wait_trigger_resume", 
            12, 100)  -- send to scripting
  assert (status == error_code.eOK, error_desc [status])
  if timeout and timeout > 0 then
    return wait (thread, timeout, id)
  end -- if having a timeout
  wait_table [id] = thread
  return coroutine.yield ()  -- return line, wildcards
end -- function waitforregexp 

-- ----------------------------------------------------------
-- we call this to wait for a trigger (not a regexp)
-- ----------------------------------------------------------
function waitfor (thread, match, timeout)
  return waitforregexp (thread, MakeRegularExpression (match), timeout)
end -- function waitfor 




An example of using it is in this alias:


<aliases>
  <alias
   match="test"
   enabled="y"
   send_to="12"
   sequence="100"
  >
  <send>  
do local t = coroutine.create (function (t)

    print ("about to wait for 'east' or 5 seconds")

    line, wildcards = waitforregexp (t, "east", 5) 

    if line then
      print ("line = " .. line)
    else
      print ("timeout!")
    end -- if

end) assert (coroutine.resume (t, t)) end
</send>
  </alias>
</aliases>



This simple example waits for the word "east" to match the regular expression, or 5 seconds. You can tell from the return codes, whether it timed out or not. If the returned line is nil, then the timer fired, and therefore it timed out. If it is not nil, then the matching line is returned.


- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).

To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.


5,765 views.

It is now over 60 days since the last post. This thread is closed.     Refresh page

Go to topic:           Search the forum


[Go to top] top

Information and images on this site are licensed under the Creative Commons Attribution 3.0 Australia License unless stated otherwise.