Client crash, issue with while loop, need a code review...

Posted by Randm on Thu 13 May 2021 03:41 PM — 5 posts, 18,763 views.

#0
I'm sure this code makes the whole client crash, but I'm not sure what is the issue.

Could you please help me out?

Thanks!


function wait_busy(cmd)
    
    EnableGroup("wait_busy",1)
    SetVariable("wait_busy_isbusy", "y")
    while true do
        if GetVariable("wait_busy_isbusy") == "y" then
            DoAfterSpecial(0.3,'SendNoEcho("checkbusy")',12)
        elseif GetVariable("wait_busy_isbusy") == "n" then
            EnableGroup("wait_busy",0)
            if cmd then 
                Execute(cmd) 
            end
            break
        else
            break
        end
    end
end
<triggers>
  <trigger
   expand_variables="y"
   group="wait_busy"
   keep_evaluating="y"
   match="^You are not busy$"
   name="wait_busy_disable"
   regexp="y"
   script="wait_busy_disable"
   send_to="12"
   sequence="100"
   variable="wait_busy_disable"
  >
  <send>SetVariable("wait_busy_isbusy", "n")</send>
  </trigger>
</triggers>
Australia Forum Administrator #1

 SetVariable("wait_busy_isbusy", "y")
    while true do
        if GetVariable("wait_busy_isbusy") == "y" then
        ...
        end
    end


There is nothing there to make that condition not true, thus the client will go into an infinite loop.

Despite you issuing function calls to do things after 0.3 seconds and so on, nothing else is done until the script ends. In particular, those calls to DoAfterSpecial will not do anything yet.

See http://www.gammon.com.au/forum/?id=4956 for how to make a pause.
Amended on Thu 13 May 2021 10:11 PM by Nick Gammon
Australia Forum Administrator #2
See http://www.gammon.com.au/forum/?id=6534 for a small timer script that you can use to break out of long loops. That can get control back to the client so you don't lose any changes you made.
Amended on Thu 13 May 2021 10:09 PM by Nick Gammon
#3
Thanks Nick!

Especially for that small timer script. It saves a lot.

However, I still have some question for the wait.make function.

What I want to do is make an common function to check the busy status.
If I make a busy test function like this

require "wait"
function checkbusy()
  wait.make(function ()
    while true do 
        wait.time(0.3)
        SendNoEcho("checkbusy")
        local l = wait.regexp("^You are not busy$",3,4)
        if l and string.find(l, "not busy") then 
            break 
        end
    end
  end)
end


can it be called in other functions? like

require "wait"
function doSomething()
  wait.make(function()

        do something here ...
        
        checkbusy()

        do something else ...
  end)
end
Amended on Thu 13 May 2021 11:42 PM by Randm
Australia Forum Administrator #4
The waiting is done in the inner function, not the outer one. So I think instead you could do this (not tested however):


require "wait"
function checkbusy()
  while true do 
      wait.time(0.3)
      SendNoEcho("checkbusy")
      local l = wait.regexp("^You are not busy$",3,4)
      if l and string.find(l, "not busy") then 
          break 
      end -- if
  end -- while
end  -- function checkbusy


And then:


require "wait"
function doSomething()
  wait.make(function()

     --   do something here ...
        
        checkbusy()

     --   do something else ...
  end)
end


So "checkbusy" does the work of finding when you are not busy, however your other functions just call that to save doing it themselves every time.