Send command capture output and return collected data from function

Posted by Lycynder on Sun 04 Jun 2017 06:13 PM — 5 posts, 22,200 views.

#0
New to lua and Mushclient so if this is simple my apologies I've searched quite a bit

I would like to create a lua function that interacts with the mud but behaves like a standard function, i.e. returns data.

The example I have chosen is to gather all area info from the screen after a command and return it as a parsed table.

function capture_area_info()
  local max_captures = 500
  local captures = 0
  local areas = {}
  local area_line_regex = rex.new([[\s+(?P<min_level>\d+)\s+(?P<max_level>\d+)\s+(?:(?P<level_lock>\d+)\s+)?(?P<area_id>\w+)\s+(?P<area_name>[A-za-z0-9 ',-]+\w)\s*$]])
  Send("areas keywords")
  wait.make( --coroutine
    function()
      while captures < max_captures do
        captures = captures + 1
        local line = wait.match('*', 10)
        local a, b, matches = area_line_regex:match(line)
        if matches then
          areas[#areas+1] = {area_id=matches['area_id'], area_name=matches['area_name'], min_level=matches['min_level'], max_level=matches['max_level'], level_lock=matches['level_lock']}
          print(#areas)
        end
        if string.match(line, [[^'Lock' means you cannot enter until you are that level or higher.$]]) then
          done = true
          break
        end
      end
    end
  )
  -- I would like this to return the gathered area info but because wait is a coroutine this returns nil immediately.
  return areas
end

Thanks in advance.
Amended on Sun 04 Jun 2017 06:24 PM by Lycynder
USA Global Moderator #1
.
Amended on Sun 04 Jun 2017 09:44 PM by Fiendish
USA Global Moderator #2
Quote:
I would like to create a lua function that interacts with the mud but behaves like a standard function, i.e. returns data.


See my description of make.wait here to better visualize why what you're trying isn't working: https://mushclient.com/forum/?id=14004&reply=1#reply1

Personally, I think assigning a callback function is the best way to do what you want.
Australia Forum Administrator #3
Quote:

... but because wait is a coroutine this returns nil immediately ...


Exactly. The coroutine might take a few seconds to gather the data, so naturally expecting immediate results won't work.

Some kind of callback, like Fiendish suggested, could work. Or make the function (inside make.wait) display or otherwise deal with the results when they are all obtained.
#4
Thanks for the replies guys, I really appreciate you considering my issue.

I can certainly do the things you've suggested and I've made the adjustments to solve the specific problem I was having. Baking in the logic into the coroutine or passing a callback works but I was just hoping to get more reuse out of functions like this. I don't have much experience with event based languages so maybe I will be able to reuse it and I'm just not seeing the patterns.