Breaking a loop... in the wrong place?

Get help with using AutoHotkey and its commands and hotkeys
Rivvnik
Posts: 3
Joined: 04 Sep 2018, 17:55

Breaking a loop... in the wrong place?

29 May 2019, 11:14

So, in my program, I have a loop set up that waits for various button-presses and does different actions depending on the buttons pressed, kind of like having a bunch of hotkeys in one. For one of said buttons, it starts another loop.

My goal is to separate these nested loops into discrete functions and have them bounce off each other. While the first loop is running and checking for a specific key, the moment it detects a keypress, I want it to break, and go to the next loop. Once that loop detects a keypress, it breaks and bounces back to the original loop.

I often work with Python 3 and the asyncio module, so I'm used to asynchronous task execution. In Python, the code below would go to the function, and while that function is executing, the while loop will break.

Code: Select all

while True:
    go_to_this_function(parameter)
    break
As AHK is not asynchronous, I'm not sure how I can go about doing something similar. Code like that above, but in AHK, would run the function, then upon its completion, would break the loop. My goal is to close the loop once it redirects to a different function, so that only a small loop is running at a time, rather than a massive loop containing like 30 other loops. This is what my code looks like right now:

Code: Select all

Loop
{
    if (GetKeyState("1", "P")) {
        Loop
        {
            if (GetKeyState("a", "P")) {
                <some tasks>
            } else if (GetKeyState("b", "P")) {
                <some other tasks>
            }
        }
    } else if (GetKeyState("2", "P")) {
        Loop
        {
            if (GetKeyState("a", "P")) {
                <even more tasks>
            } else if (GetKeyState("b", "P")) {
                <an absurd number of tasks>
            }
        }
    }
}
My goal is to have something that looks like this, although the code below does not work:

Code: Select all

main_loop() {
    Loop
    {
        if (GetKeyState("1", "P")) {
            second_loop()
            break
        } else if (GetKeyState("2", "P")) {
            third_loop()
            break
        }
    }
}

second_loop() {
    Loop
    {
        if (GetKeyState("a", "P")) { ; go back to main loop
            main_loop()
            break
        } else if (GetKeyState("b", "P")) { ; go to third loop
            third_loop()
            break
        }
    }
}

third_loop() {
    Loop
    {
        if (GetKeyState("a", "P")) { ; do some random tasks
            <random tasks>
            break
        } else if (GetKeyState("b", "P")) { ; go back to main loop
            main_loop()
            break
        }
    }
}
Any help or insight would mean the world to me. I'm open to any ideas, even if they require totally reworking the logic.
User avatar
Delta Pythagorean
Posts: 464
Joined: 13 Feb 2017, 13:44
GitHub: DelPyth
Location: Somewhere in the US

Re: Breaking a loop... in the wrong place?

29 May 2019, 20:57

The break command is not necessary for Loops, it's only if you want to break said loop and continue on with your code as shown here:

Code: Select all

Loop, 10
{
	X := SomeCodePassedToX()
	If (X == 10)
		Break		; Breaks the loop and continues on after the loop if X is 10
	Else
		Continue		; Otherwise, continue until it does
}
MsgBox, I only show after the loop!
eight04
Posts: 5
Joined: 24 May 2019, 04:18
GitHub: eight04

Re: Breaking a loop... in the wrong place?

30 May 2019, 23:00

Sounds like you just need to maintain a state:

Code: Select all

1::
2::
a::
b::
phaseTransformer() {
  ; state transformer
  static currentPhase := ""
  if (phaseTransformer_shouldTransform(currentPhase, A_ThisHotkey)) {
    currentPhase .= A_ThisHotkey
  }
  
  ; run task according to the current state
  if (currentPhase == "1a") {
    MsgBox, <some tasks>
    currentPhase := ""
  } else if (currentPhase == "1b") {
    MsgBox, <some other tasks>
    currentPhase := ""
  } else if (currentPhase == "2a") {
    MsgBox, <even more tasks>
    currentPhase := ""
  } else if (currentPhase == "2b") {
    MsgBox, <an absurd number of tasks>
    currentPhase := ""
  }
}

phaseTransformer_shouldTransform(phase, newPhase) {
  if (!phase && inList("1,2", newPhase))
    return true
  if (StrLen(phase) == 1 && inList("a,b", newPhase))
    return true
  return false
}

inList(list_, token) {
  if token in %list_%
    return true
  return false
}


Return to “Ask For Help”

Who is online

Users browsing this forum: aifritz, Google [Bot], Odlanir, Portwolf, Rohwedder and 166 guests