Author Topic: Trying to get a couple of commands dealing with timed actions working correctly.  (Read 2768 times)

iceblast

  • Sr. Member
  • ****
  • Posts: 372
Is there a way, to have a command know how long you held a button down?

I want a way to use the same button for a set of commands.

1. Hit the button, and command runs instantly.

2. If the button is held for say 1 second, a different command will run instead.

I also need a command that's like a toggle switch.

Hit the button, and the command hits Pause which turns it ON, and after 30 secs, it hits Pause again, which turns it OFF. But I also want to hit Pause before the 30 secs is up to manual turn it off, which would also kill the 30 secs timer. I can't seem to do this without is screwing it up at some point, causing it to get stuck ON, which I then have to manual turn OFF the program.

I've been struggling with these 2 things for a long time, and I thought I would ask for help. :)


Rhaedas

  • Jr. Member
  • **
  • Posts: 72
They both should be easy to do using flag variables.

The first one would set a flag for true on the first press of the button or key. Then you have a short loop of say .5 secs, then go back with a conditional statement to check for the state of that same button/key. If it's not down, you trigger the first command, if it is, then the second. You can adjust the loop or even add another to make sure the button is still being held down for the second.

For the other one, set the flag to true, then have the first countdown loop check for that flag status each time around. If you press the key before 30 seconds, that sets it back to false (I like to use Not Set as false, so I don't have to initialize each time). In the loop if it finds the flag is false before time is up, it exits/kills the command.

Pfeil

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 4762
  • RTFM
For the first command, is the intention for the second branch of the command to run after the key is released?

If so, this could work:
Code: [Select]
Set date [~startTime] to [~startTime] plus [1] seconds
Start Loop While :  Keyboard Key 'A' Is Pressed
End Loop
Begin Date Compare : [~startTime] Is Greater Than Current Date/Time
    Write '[Blue] A' to log
Else
    Write '[Blue] B' to log
End Condition
The loop will idle the command as long as the key is held down(make sure it's set to the same keypress/button that triggers the command).

Once you release the key, the condition will check whether approximately one second(approximate because there is always a slight delay between pressing the physical key initially and VoiceAttack triggering the command) has elapsed, and if it has, execute branch B.

Otherwise, if the key has been held down less than a second(ish), it will execute branch A.


If the second branch is supposed to run *while* the key is still pressed, a modification can be made to the first example to accommodate this:
Code: [Select]
Set date [~startTime] to [~startTime] plus [1] seconds
Start Loop While : (Keyboard Key 'A' Is Pressed AND [~startTime] Is Greater Than Current Date/Time)
End Loop
Begin Date Compare : [~startTime] Is Greater Than Current Date/Time
    Write '[Blue] A' to log
Else
    Write '[Blue] B' to log
End Condition
If the key is held down longer than one second, the idler loop will end, and the command will execute.

The conditional will still determine whether the key has been held down longer than one second, which it always will have if the loop ended because the key was held down long enough.



For the second command, I'll assume "Pause" refers to the Pause/Break keyboard key:

Code: [Select]
Begin Boolean Compare : [>holdingPause] Equals True
    Set Boolean [>holdingPause] to False
End Condition - Exit when condition met
Set date [~startTime] to [~startTime] plus [30] seconds
Set Boolean [>holdingPause] to True
Press Pause key and hold for 0,06 seconds and release
Start Loop While : ([~startTime] Is Greater Than Current Date/Time AND [>holdingPause] Equals True)
End Loop
Press Pause key and hold for 0,06 seconds and release
Set Boolean [>holdingPause] to False

When the command starts, the boolean is set to True, the "Pause" key is pressed and released, and the timer starts.

If you trigger the command a second time before the timer elapses, the second instance will set the boolean to false and exit the command without starting another loop.

Because the loop checks whether it remains True each time it comes around, the first instance will at that point end its loop and press the "Pause" key again.


Now, because the variable must be available to all running instances of the command, I chose to make it profile-scoped, meaning it does get discarded once you change profiles(as the command would also be terminated automatically at this point).

But, it also means you need to change the name of that variable if you choose to copy the logic to another command.
Otherwise triggering either command while the other is running would just stop the running command.

iceblast

  • Sr. Member
  • ****
  • Posts: 372
I tried and tried and tried to get the date/time to work, but it's like it's not counting the seconds at all, so the answer is always the same. So, I made my own thing.

Code: [Select]
Set small int (condition) [Seconds] value to 0
Set Text [SITE] to [C:\Running AHK scripts\primary program.txt]
Start Loop While :  Keyboard Key 'F21' Is Pressed
    Set small int (condition) [Seconds] value as incremented by 1
    Write '[Blue] {SMALL:Seconds}' to log
    Pause 0.1 seconds
    Begin Small Integer Compare : [Seconds] Is Greater Than 3
        Play sound, '{VA_SOUNDS}\318276__jalastram__retro-game-sounds-sfx-69.wav'
        Pause 1 second
    End Condition
End Loop
Begin Small Integer Compare : [Seconds] Is Less Than 3
    Display window '{TXT:SITE}' as [Show]
    Pause 0.2 seconds
    Begin Condition : [{ACTIVEWINDOWTITLE}] Does Not Equal '{TXT:SITE}' OR [{ACTIVEWINDOWPROCESSNAME}] Equals '{TXT:SITE}'
        Press Left Win+8 keys and hold for 0.1 seconds and release
    End Condition
    Write '[Blue] {TXT:SITE}' to log
Else
    DISABLED - Change window '[Active Window]' title to, 'Primary Window'
    Set Text [Site] to '{ACTIVEWINDOWTITLE}'
    Write (overwrite), '{TXT:SITE}' to file 'C:\Running AHK scripts\primary program.txt'
    Write '[Blue] {TXT:SITE}' to log
End Condition

This will allow me to hit the button and the command is triggered instantly, or if I hold it longer than 0.3 seconds it will trigger a second command, and play a sound when I've held it long enough. Seems to work really good.

Now, I just need to figure out my 30 second one.

iceblast

  • Sr. Member
  • ****
  • Posts: 372
Pfeil, yours was very simple, and short, mine is nuts haha

Here's the code for my 30 second one. Just a bit bigger than yours.

Code: [Select]
Set small int (condition) [Ticks] value to 0
Set small int (condition) [Off] value to 0
Write '[Blue] {SMALL:Dragon}' to log
Set small int (condition) [set] value to 0
Begin Device State Check :  Keyboard Key 'Pause' Is Pressed
    Start Loop While :  Keyboard Key 'Pause' Is Pressed
        Set small int (condition) [set] value as incremented by 1
        Pause 0.1 seconds
        Begin Small Integer Compare : [set] Is Greater Than 3
            Play sound, '{VA_SOUNDS}\318276__jalastram__retro-game-sounds-sfx-69.wav'
            Pause 1 second
        End Condition
    End Condition
End Loop
Begin Small Integer Compare : [set] Is Greater Than 3
    Set small int (condition) [Dragon] value to 0
End Condition - Exit when condition met
Begin Small Integer Compare : [Dragon] Equals 1
    Set small int (condition) [Off] value to 1
    Write '[Blue] {SMALL:Dragon}' to log
End Condition
Begin Small Integer Compare : [Dragon] Equals 0
    Set small int (condition) [Dragon] value as incremented by 1
    Press Pause key and hold for 0.1 seconds and release
    Start Loop : Repeat 30 Times
        Set small int (condition) [Ticks] value as incremented by 1
        Write '[Blue] {SMALL:Ticks}' to log
        Pause 1 second
        Begin Small Integer Compare : [Off] Equals 1
            Press Pause key and hold for 0.1 seconds and release
            Set small int (condition) [Dragon] value to 0
            Loop Break
        End Condition - Exit when condition met
    End Loop
End Condition
Press Pause key and hold for 0.1 seconds and release