Jump to content

Recommended Posts

Posted (edited)

Update 2017-04-21:

  1. Added a timeout
  2. My previous attempt of checking that the function is valid was not working. Added a 1 time function call before entering the While loop to test the function. Now sets error to $SLEEP_UNTIL_INVALID_CALL if the function supplied is does not exist or invalid arguments supplied
  3. Added an @Error value $SLEEP_UNTIL_TIMEOUT_REACHED, set when the condition was not met but timeout reached

Update 2017-04-25:

  1. Thanks to @jguinchfor letting me know about Execute(). Greatly simplified the loop (didn't know that Execute would execute a function call statement)
    Any strings passed to the SleepUntil() function need to be enclosed in " or ' (I.e', SleepUntil("ConsoleWrite('This is a test' & @LF)"))
  2. Adjusted SleepUntil() to use the Execute() function instead

Inspired by a very vague topic, and completely unnecessary, I had fun trying to making this up. A function that will sleep until the conditional statement, or function call statement, provided executes to the condition you want! I know, completely useless!!! It's pretty interesting actually. Instead of having to write multiple while loops per conditions, you just need to use SleepUntil and set your own condition.

Basic syntax:

SleepUntil("$iMyNumber = 100")

Will sleep until the variable in your script $iMyNumber is 100. All conditional operators are supported (=, <>, >=, <=, >, and <). Currently does not support multiple conditions (i.e., $iMyNumber > 100 and $iMyNumber < 1000).

More advanced syntax, using a value returned from a function call:

SleepUntil("TimerDiff(" & TimerInit() & ") > 5000")

Well check the value returned from TimerDiff using the value returned from TimerInit() and stop sleeping once it's > 5000 (5 seconds).

Anyways, better to show through the example.

Example.au3

#include <String.au3>
#include <Array.au3>
#include <GUIConstants.au3>
#include <GuiEdit.au3>
#include "SleepUntil.au3"

AutoItSetOption("GUICloseOnESC", 0)
Global $sName = "Test"
Global $bBool = True
Global $iInt = -1
Global $dDouble = 0.0

Global $sMsg = "Welcome," & @CRLF & _
            "The SleepUntil function can use a function to check against a condition or just a regular conditional statement. " & _
            "I.e. $iValue = 300" & @CRLF & "A basic conditional example would be" & @CRLF & @TAB & _
            "Global $bWaiting = True" & @CRLF & @TAB & _
            'SleepUntil("$bWaiting <> $bWaiting")' & @CRLF & _
            "This is a good example of having some kind of global flag where you want to wait until the user triggers the flag to not be true" & @CRLF & @CRLF & _
            "The first set of examples will use function calls to compare against the condition value." & @CRLF & _
            "First example calls GUIGetMsg using the with no arguments and sleeps until the value returned is " & _
            "$GUI_EVENT_CLOSE" & @CRLF & @CRLF & _
            "Syntax for the function call for SleepUntil is like normal:" & @CRLF & _
            'SleepUntil("FunctionName(Argument1, Argument2, ArgumnetN) (Condition Operator) Value' & @CRLF & _
            'Example (Where function call has arguments)' & @CRLF & @TAB & _
            'Global $iTimer = TimerInit()' & @CRLF & @TAB & _
            'SleepUntil("TimerDiff(" & $iTimer & ") >= 5000")' & @CRLF & @CRLF & _
            "Example (Where no arguments are needed for the function)" & @CRLF & @TAB & _
            'SleepUntil("GUIGetMsg() = $GUI_EVENT_CLOSE")' & @CRLF & @CRLF & _
            "The first example will start once you close this window!"

Global $hMain = GUICreate("Introduction", 800, 600, 0, 0, BitOR($WS_SIZEBOX, $WS_MAXIMIZEBOX, $WS_MINIMIZEBOX))
Global $edtEdit = GUICtrlCreateEdit($sMsg, 10, 10, 775, 555, $ES_MULTILINE)
GUICtrlSetBkColor($edtEdit, 0x1F1F1F)
GUICtrlSetColor($edtEdit, 0xF1F1F1)
GUICtrlSetFont($edtEdit, 11, 400, "", "Consolas")
GUICtrlSetResizing($edtEdit, $GUI_DOCKLEFT + $GUI_DOCKRIGHT + $GUI_DOCKTOP + $GUI_DOCKBOTTOM)

GUISetState(@SW_SHOWMAXIMIZED)
_GUICtrlEdit_SetSel(GUICtrlGetHandle($edtEdit), 0, 0)

; Slep until person running this example script closes the GUI or it reaches the 30 second timeout
SleepUntil("GUIGetMsg() = $GUI_EVENT_CLOSE", 50, 30000)
GUIDelete($hMain)

MsgBox("", "Timer", "Starting the examples. The next sleep will last until 2 seconds have passed")

; Sleep until TimerDif(Timer Created) > 2000
ToolTip("Sleeping until 2 seconds has passed", 0, 0)

SleepUntil("TimerDiff(" & TimerInit() & ") >= 2000")

MsgBox("", "Timer", "2 Seconds has passed. Met condition and left sleep function")

; Sleep until the call to ConsoleWrite3Times is >= 3
ToolTip("Sleeping until the function ConsoleWrite3Times() as been called three times", 0, 0)
SleepUntil("ConsoleWrite3Times('This is a test!') >= 3", 500)

MsgBox("", "Print 3 Times", "Did ConsoleWrite 3 times. Met condition needed and left sleep function")


MsgBox("", "Next", "Next SleepUntil examples can be met by pressing the {F1} Key to trigger the conditions" & @CRLF & _
                    "Next example will sleep until $sName = InunoTaishou")

HotKeySet("{F1}", SetName)
; Sleep until user presses {F1} and changes $sName = InunoTaishou
ToolTip("$sName = " & $sName, 0, 0)
SleepUntil("$sName = 'InunoTaishou'", 100)

MsgBox("", $sName, "Name has been updated to " & $sName & ". Met condition needed and left sleep function" & @CRLF & _
                    "Next example will sleep until $bBool <> True")

; Sleep until user preses {F1} and $bBool <> True
ToolTip("$bBool = " & $bBool, 0, 0)
SleepUntil("$bBool <> " & $bBool, 100)

MsgBox("", $bBool, "Bool has been updated to " & $bBool & ". Met condition needed and left sleep function" & @CRLF & _
                    "Next example will sleep until $iInt > 0")

; Sleep until user presses {F1} and $iInt > 0
ToolTip("$iInt = " & $iInt, 0, 0)
SleepUntil("$iInt > 0", 100)

MsgBox("", $iInt, "Int has been updated to " & $iInt & ". Met condition needed and left sleep function" & @CRLF & _
                    "Next example will sleep until $dDouble = 99.99")

; Sleep until user presses {F1} and $dDouble = 99.99
ToolTip("$dDouble = " & $dDouble, 0, 0)
SleepUntil("$dDouble = 99.99", 100)

MsgBox("", $dDouble, "Double has been updated to " & $dDouble & ". Met condition needed and left sleep function" & @CRLF & _
                    "Next example will sleep until function Print is called with the msg provided")

Local $sMsgToPrint = InputBox("Message", "What message should be used for ConsoleWrite?", "This is a the default msg!")
SleepUntil("Print('" & $sMsgToPrint & "', " & InputBox("Times?", "How many times to print " & $sMsgToPrint & "?", 10) & ") = '" & $sMsgToPrint & "'")
MsgBox("", "Print", "Congrats! That's all the examples I have")

Func ConsoleWrite3Times($sMsg)
    Local Static $iPrint = 0
    $iPrint += 1
    ConsoleWrite("[" & $iPrint & "] " & $sMsg & @LF)
    Return $iPrint
EndFunc

Func Print($sMsg, $iTimes)
    If ($iTimes < 1) Then $iTimes = 1
    For $i = 1 to $iTimes
        ConsoleWrite($sMsg & @LF)
    Next
    Return $sMsg
EndFunc

Func SetName()
    $sName = "InunoTaishou"
    HotKeySet("{F1}", SetBool)
EndFunc   ;==>SetName

Func SetBool()
    $bBool = False
    HotKeySet("{F1}", SetInt)
EndFunc   ;==>SetBool

Func SetInt()
    $iInt = 100
    HotKeySet("{F1}", SetDouble)
EndFunc   ;==>SetInt

Func SetDouble()
    $dDouble = 99.99
EndFunc   ;==>SetDouble

SleepUnti.au3

#include-once
#include <String.au3>
Global Const $SLEEP_UNTIL_INVALID_EXECUTE = -100
Global Const $SLEEP_UNTIL_TIMEOUT_REACHED = -101

; #AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w- 4 -w 5 -w 6 -w- 7

; #CURRENT# =====================================================================================================================
; SleepUntil:               Sleeps until the condition statement supplied meets the requirements
; ===============================================================================================================================

; #FUNCTION# ====================================================================================================================
; Name ..........: SleepUntil
; Description ...: Sleeps until the condition supplied is met.
; Syntax ........: SleepUntil($sConditionStatement[, $iTime = 100[, $iTimeout = Default]])
; Parameters ....: $sConditionStatement     - String formatted condition statement
;                  $iTime                   - (Optional) Time (In Milliseconds) to sleep between each check of the condition
;                  $iTimeout                - (Optional) Timeout (In Milliseconds) to stop sleeping if condition not met
; Return values .: Success - Returns True when the condition is met
;                  Failure - Returns False and Sets the @Error flag
;                            -100 ($SLEEP_UNTIL_INVALID_EXECUTE): Function supplied does not exist or parameters supplied do not match
;                                                              the function called
;                            -101 ($SLEEP_UNTIL_TIMEOUT_REACHED): Timeout was reached but the condition was not met
; Author ........: InunoTaishou, jguinch for letting me know about Execute()
;                  Thanks jguinch! Greatly simplified the script
; Remarks .......: The $sConditionStatement parameter can be a simple $vVar = Value or can use the value returned from a function call
;                  to sleep.
;                  Proper syntax for a function call is a normal AutoIt function call: "MsgBox(0, 'Title', 'Message')"
; Example .......: Yes
; ===============================================================================================================================
Func SleepUntil($sConditionStatement, $iTime = 100, $iTimeout = Default)
    Local $iTimer = ($iTimeout ? TimerInit() : Null)
    While (Not Execute($sConditionStatement))
        If (@Error) Then Return SetError($SLEEP_UNTIL_INVALID_EXECUTE, 0, False)
        If ($iTimeout and TimerDiff($iTimer) >= $iTimeout) Then Return SetError($SLEEP_UNTIL_TIMEOUT_REACHED, 0, False)
        Sleep($iTime)
    WEnd
    Return True
EndFunc   ;==>SleepUntil

Edit: Did a test call to the function to make sure it's valid. checking for the 0xDEAD and 0xBEEF errors inside the while loops wasn't working since the _EvalCondition was being called right after it.

Edit: Forgot about the _ that can be used in function calls. Added the _ to the StringRegExp

Edited by InunoTaishou
typo
Posted

After looking at that same topic, I was almost inspired to do my own SleepUntil function, but figured it was hardly worth it really, as it would have just been milliseconds based. Many of us I am sure, have such things in some of our scripts/programs, as it is pretty simple to whip it up on the fly.

Your script though is something else altogether, so kudos to you for all that work and ingenuity. :thumbsup:

Thanks for sharing. :D

Make sure brain is in gear before opening mouth!
Remember, what is not said, can be just as important as what is said.

  Reveal hidden contents

I may have the Artistic Liesense ;) to disagree with you. TheSaint's Toolbox (be advised many downloads are not working due to ISP screwup with my storage)

userbar.png

Posted

Thanks, it helped kill a couple of hours lol

I kind of want to redo the syntax and make it exactly like a regular autoit conditional statement. Like

SleepUntil("TimerDiff($iTimer) >= 2000 and Not $bRunning")

And I started doing this, but it got very complex. What if the conditional statement start with a variable instead of a function? How do I parse a string like that? I tried looking into how to make your own language to see how they execute something like this, but it looks very complex and time consuming. Maybe in the future.

I tried to make it a bit forgiving in the syntax too. I did mix function call syntax (Func = TimerDiff and Func: ConsoleWrite3Times). That should work for |Args = {Arg1}| and |Args: {Arg1}| or even just doing |{Arg1}, {Arg2}| That's why I went with the Regular Expression to capture the valid function characters (_a-zA-Z0-9). And then validate the function before going into the While loop.

Posted

Updated, added a timeout. Also noticed the way I was checking if the function (and arguments) was valid wasn't actually working. Changed it by doing a one time function call before entering the while loop.

New @Error values are $SLEEP_UNTIL_INVALID_CALL (Function doesn't exist or arguments supplied are incorrect) and $SLEEP_UNTIL_TIMEOUT_REACHED (timeout reached but the condition was not met)

Posted (edited)

Updated, thanks to @jguinch for letting me know the Execute() function can take a regular AutoIt expression and evaluate it! Simplified the SleepUntil function a lot. Will also allow me a much easier way to allow multiple conditions in a statement (condition1 and contidion2 or (condition3 and condition4)). When I decide to get around to doing that.... lol

Edited by InunoTaishou

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...