Author Topic: How to check for {CMDSEGMENT:segment} NOT SET in a conditional block  (Read 2874 times)

Dee

  • Guest
Hi,

I'm new to VoiceAttack, using it for basic control of my computer in order to reduce RSI. So far it's already making a huge difference with just a couple dozen commands. Many thanks to the developer Gary for this brilliant app!

I'm hoping someone can help with the following.

I am creating a command that will navigate from word to word in text by pressing Ctrl+Right/Left [num] times.

Here's my voice command:

Code: [Select]
word [right; left] [; 2; 3]
Here are the commands:

Code: [Select]
Write '[Blue] CMDSEGMENT has been set to: {TXT:'{CMDSEGMENT:2}'}' to log
Begin Text Compare : [{CMDSEGMENT:2}] Has Not Been Set
    Write '[Blue] Not set!' to log
    Set small int (condition) [num] value to 1
Else
    Write '[Blue] Set!' to log
    Set small int (condition) [num] value to the converted value of {CMDSEGMENT:2}
End Condition
Write '[Blue] num = {SMALL:num}' to log

Here's the result.

If I say "word right", the log says:

Code: [Select]
Recognized : 'word right'
CMDSEGMENT has been set to: Not set
Set!
Small integer token could not be converted : {CMDSEGMENT:2}
num = Not set

If I say "word right 2", the log says:

Code: [Select]
Recognized : 'word right 2'
CMDSEGMENT has been set to: Not set
Set!
num = 2

Thanks :)

Pfeil

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 4759
  • RTFM
Re: How to check for {CMDSEGMENT:segment} NOT SET in a conditional block
« Reply #1 on: April 26, 2018, 12:11:15 PM »
Tokens are not variables, so that comparator cannot work; Tokens also always return text(so technically the result is never NULL, which would be the internal value that VoiceAttack renders as "Not Set").

You have to compare literal text instead:
Code: [Select]
Begin Condition : [{CMDSEGMENT:2}] Equals '' OR [{CMDSEGMENT:2}] Equals 'Not Set'
End Condition

{CMDSEGMENT:} will return ""(blank) if a segment is not spoken, or "Not Set" if the index points to a nonexistent segment, which can happen if multiple phrase options are used for a command.

E.G. "this is one [option;] with three segments;This one only has one segment", Using "{CMDSEGMENT:1}" with the former would either return ""(blank) or "option", using it with the latter instead would always result in "Not Set", because there is no second segment.

Dee

  • Guest
Re: How to check for {CMDSEGMENT:segment} NOT SET in a conditional block
« Reply #2 on: April 26, 2018, 01:18:12 PM »
Hi Pfeil,

Thank you very much for that helpful explanation.

Now I'm getting a different error:

Code: [Select]
Begin Text Compare : [{CMDSEGMENT:2}] Equals ''
    Set small int (condition) [num] value to 1
Else
    Set small int (condition) [num] value to the converted value of {CMDSEGMENT:2}
End Condition
Write '[Blue] num = {SMALL:num}' to log
Begin Text Compare : [{CMDSEGMENT:1}] Equals 'right'
    Start Loop : Repeat [num] Times
        Press Left Ctrl+Right keys and hold for 0.01 seconds and release
    End Loop
End Condition

Here's the log:

Code: [Select]
Recognized : 'word right'
num = 1
Unable to resolve for loop context: num.  Exiting command.

Am I referencing the variable incorrectly?

Pfeil

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 4759
  • RTFM
Re: How to check for {CMDSEGMENT:segment} NOT SET in a conditional block
« Reply #3 on: April 27, 2018, 04:10:55 AM »
For loops take an integer value, not a small.

As a general rule, you should probably always use integer; Gary intends to deprecate small, which offers no real advantages over int in the context of VoiceAttack.

Dee

  • Guest
Re: How to check for {CMDSEGMENT:segment} NOT SET in a conditional block
« Reply #4 on: April 27, 2018, 06:25:55 AM »
Thank you, that did the trick :)