Code: Select all
loop 10
{
soundbeep 1000
Sleep 1000
sounbeep 1000
Sleep 1000
}
Code: Select all
loop 10
{
soundbeep 1000
Sleep 1000
sounbeep 1000
Sleep 1000
}
Thank you. From what is stated in the threads, it seems that there is no standard method to terminate the execution of a loop in a simple way with a hotkey. An If command has to be used inside the loop to check a certain condition all the time.mikeyww wrote: ↑04 Aug 2021, 10:21You could add conditional statements that check a variable that the hotkey sets. Another option is Reload.
Ideas:
https://www.autohotkey.com/boards/viewtopic.php?f=76&t=82813
https://www.autohotkey.com/boards/viewtopic.php?p=250076#p250076
Code: Select all
F1::LoopUntilHotkeyIsPressed("LoopBody_Test", "F2", maxLoops:=4)
LoopBody_Test(){
SoundBeep, 500
sleep 100
SoundBeep, 800
sleep 500
}
LoopUntilHotkeyIsPressed(loopBody, terminationKey, maxLoopCount:=""){
loop := new HotkeyTerminatedLoop(loopBody, terminationKey, maxLoopCount)
loop.Start()
}
class HotkeyTerminatedLoop{
__New(loopBody, terminationKey, maxLoopCount:=""){
this.loopBody := IsObject(loopBody) ? loopBody : Func(loopBody)
this.terminationKey := terminationKey
this.maxLoopCount := maxLoopCount
if (!IsObject(this.loopBody))
msgbox % "Error: Invalid func was passed for loop body"
}
Start(){
this.isBroken := false
this.ToggleBreakHotkey("on")
Loop {
if (this.isBroken || (this.maxLoopCount && A_Index > this.maxLoopCount))
break
this.loopBody.Call()
}
this.ToggleBreakHotkey("off")
}
Break(){
this.isBroken := true
}
ToggleBreakHotkey(mode:="on"){
fnLoopBreaker := ObjBindMethod(this, "Break")
Hotkey, % this.terminationKey, % fnLoopBreaker, % mode
}
}
Yes, I can see that there seems to be no easy way to terminate a loop without having to write much code or to reload the entire script. The variables in the script will be reset if the script is reloaded. So adding IF statements within the loop may be the only option which involves few lines of code.WatsonEnterprises wrote: ↑07 Aug 2021, 03:12Here's something funny.Pass your loop body as a function, and it'll check the termination condition before each iteration of it.Code: Select all
F1::LoopUntilHotkeyIsPressed("LoopBody_Test", "F2", maxLoops:=4) LoopBody_Test(){ SoundBeep, 500 sleep 100 SoundBeep, 800 sleep 500 } LoopUntilHotkeyIsPressed(loopBody, terminationKey, maxLoopCount:=""){ loop := new HotkeyTerminatedLoop(loopBody, terminationKey, maxLoopCount) loop.Start() } class HotkeyTerminatedLoop{ __New(loopBody, terminationKey, maxLoopCount:=""){ this.loopBody := IsObject(loopBody) ? loopBody : Func(loopBody) this.terminationKey := terminationKey this.maxLoopCount := maxLoopCount if (!IsObject(this.loopBody)) msgbox % "Error: Invalid func was passed for loop body" } Start(){ this.isBroken := false this.ToggleBreakHotkey("on") Loop { if (this.isBroken || (this.maxLoopCount && A_Index > this.maxLoopCount)) break this.loopBody.Call() } this.ToggleBreakHotkey("off") } Break(){ this.isBroken := true } ToggleBreakHotkey(mode:="on"){ fnLoopBreaker := ObjBindMethod(this, "Break") Hotkey, % this.terminationKey, % fnLoopBreaker, % mode } }
If you want to terminate halfway into an iteration (like you mention in the OP), then mikey's suggestion of Reload/ExitApp seems like your best option aside from putting an if statement after every line. If you don't want to reload your whole script, you could run your loop separately as a second smaller script.