Author Topic: Variable looping (loop blocks) - how to break the loop?  (Read 12787 times)

0 Members and 1 Guest are viewing this topic.

marcusvdt

  • Sr. Member
  • ****
  • Posts: 152
  • Karma: 6
  • Researching
    • View Profile
Variable looping (loop blocks) - how to break the loop?
« on: August 20, 2015, 04:57:37 PM »
Hi!

I'm creating a command group for Chrome (in fact I used the one that is posted in gems as a base).
I want to have a more consistent treatment as to launching the browser and making sure it is in focus before I start sending commands to it. So I've modified the launch command as below.
Instead of launching the default browser, which creates dependencies of external manual actions (ie I would need to manually set Chrome as my default browser), I wanted to launch the Chrome executable. But then I wanted to confirm it is opened before I go ahead sending the commands for it to browse to a web site.
I supposed the loop block would fit perfectly for my needs since I could keep looping until Chrome is in focus and then follow the remaining actions (check the commands attached for more details).
As per the wiki, loops blocks can't have logic blocks inside, so I thought I could have an event that would trigger a command that would set j variable to a value greater than the one set in the loop, hence breaking the loop block.

On my tests I can't get the above to work, probably because more than one characteristics of how the logic blocks have been designed. I'm not questioning this, or asking to change anything, but perhaps some of you guys can suggest a way of doing the consistency I'm trying to do.

So could you please take a look on that and eventually suggest something else that would achieve the same result?

Thanks in advance.

Code: [Select]
<?xml version="1.0" encoding="utf-16"?>
<!--VoxCommando 2.2.0.7-->
<command id="678" name="open url with payload" enabled="true" alwaysOn="False" confirm="False" requiredConfidence="0" loop="False" loopDelay="0" loopMax="0" description="">
  <if ifBlockDisabled="False" ifNot="True">
    <ifType>ProcessRunning</ifType>
    <ifParams>chrome&amp;&amp;</ifParams>
    <then>
      <action>
        <cmdType>Launch.RawParam</cmdType>
        <params>
          <param>{Path.PFx86}\Google\Chrome\Application\chrome.exe</param>
        </params>
        <cmdRepeat>1</cmdRepeat>
      </action>
      <action>
        <cmdType>TTS.SpeakSync</cmdType>
        <params>
          <param>Opening Chrome</param>
        </params>
        <cmdRepeat>1</cmdRepeat>
      </action>
    </then>
    <else />
  </if>
  <loop>
    <loopParams>
      <from>1</from>
      <to>30</to>
    </loopParams>
    <loopActions>
      <action>
        <cmdType>OSD.ShowText</cmdType>
        <params>
          <param>Waiting for Chrome: {j}/30 seconds</param>
          <param>1000</param>
          <param>1</param>
        </params>
        <cmdRepeat>1</cmdRepeat>
      </action>
      <action>
        <cmdType>VC.Pause</cmdType>
        <params>
          <param>500</param>
        </params>
        <cmdRepeat>1</cmdRepeat>
      </action>
      <action>
        <cmdType>Window.Focus</cmdType>
        <params>
          <param>chrome</param>
        </params>
        <cmdRepeat>1</cmdRepeat>
      </action>
      <action>
        <cmdType>VC.Pause</cmdType>
        <params>
          <param>500</param>
        </params>
        <cmdRepeat>1</cmdRepeat>
      </action>
    </loopActions>
  </loop>
  <if ifBlockDisabled="False" ifNot="False">
    <ifType>ProcessRunning</ifType>
    <ifParams>chrome&amp;&amp;</ifParams>
    <then>
      <action>
        <cmdType>Window.Focus</cmdType>
        <params>
          <param>chrome</param>
        </params>
        <cmdRepeat>1</cmdRepeat>
      </action>
      <action>
        <cmdType>VC.Pause</cmdType>
        <params>
          <param>5</param>
        </params>
        <cmdRepeat>1</cmdRepeat>
      </action>
      <action>
        <cmdType>SendKeys</cmdType>
        <params>
          <param>^l</param>
        </params>
        <cmdRepeat>1</cmdRepeat>
      </action>
      <action>
        <cmdType>VC.Pause</cmdType>
        <params>
          <param>5</param>
        </params>
        <cmdRepeat>1</cmdRepeat>
      </action>
      <action>
        <cmdType>DxInput.Type</cmdType>
        <params>
          <param>{1}{RETURN}</param>
        </params>
        <cmdRepeat>1</cmdRepeat>
      </action>
      <action>
        <cmdType>OSD.ShowText</cmdType>
        <params>
          <param>{1}</param>
        </params>
        <cmdRepeat>1</cmdRepeat>
      </action>
      <action>
        <cmdType>TTS.Speak</cmdType>
        <params>
          <param>Browsing to {PF.1}</param>
        </params>
        <cmdRepeat>1</cmdRepeat>
      </action>
    </then>
    <else>
      <action>
        <cmdType>TTS.Speak</cmdType>
        <params>
          <param>I couldn't open Chrome</param>
        </params>
        <cmdRepeat>1</cmdRepeat>
      </action>
      <action>
        <cmdType>OSD.ShowText</cmdType>
        <params>
          <param>I couldn't open Chrome</param>
          <param>2000</param>
          <param>1</param>
        </params>
        <cmdRepeat>1</cmdRepeat>
      </action>
    </else>
  </if>
  <phrase>open site</phrase>
  <payloadFromXML phraseOnly="False" use2partPhrase="False" phraseConnector="by" Phrase2wildcard="anyone" optional="False">payloads\url.xml</payloadFromXML>
</command>


marcusvdt

  • Sr. Member
  • ****
  • Posts: 152
  • Karma: 6
  • Researching
    • View Profile
Re: Variable looping (loop blocks) - how to break the loop?
« Reply #1 on: August 20, 2015, 04:58:25 PM »
This is the command that I expected to set j variable to a value that would break the loop block above. Unfortunatelly the event appears only after the loop block has finished.
Code: [Select]
<?xml version="1.0" encoding="utf-16"?>
<!--VoxCommando 2.2.0.7-->
<command id="702" name="Chrome já em foco" enabled="true" alwaysOn="False" confirm="False" requiredConfidence="0" loop="False" loopDelay="0" loopMax="0" description="This should stop the loop on the other command.">
  <action>
    <cmdType>Results.SetVar</cmdType>
    <params>
      <param>j</param>
      <param>31</param>
    </params>
    <cmdRepeat>1</cmdRepeat>
  </action>
  <event>Focused.chrome</event>
</command>


marcusvdt

  • Sr. Member
  • ****
  • Posts: 152
  • Karma: 6
  • Researching
    • View Profile
Re: Variable looping (loop blocks) - how to break the loop?
« Reply #2 on: August 20, 2015, 04:59:33 PM »
Output. I'm confused with the sequence the things appear in the log. Chrome was already opened and in focus since loop iteration 3, but then lost the focus and in the end of the macro it was not in focus anymore. The event Focused.chrome appeared only near the end of the sequence.

PegLegTV

  • $upporter
  • Sr. Member
  • *****
  • Posts: 497
  • Karma: 43
    • View Profile
Re: Variable looping (loop blocks) - how to break the loop?
« Reply #3 on: August 20, 2015, 05:52:20 PM »
Quote
This is the command that I expected to set j variable to a value that would break the loop block above. Unfortunatelly the event appears only after the loop block has finished.

with program variables such as {j} {i} {#M} and so on, can not be set, at least not in a way that I know of, when your are using
Code: [Select]
Results.SetVar j 30 then in order to use that variable you would have to call it using {Var.j} which the looping block can not see,

heres your command with OSD showing what I mean,
Code: [Select]
<?xml version="1.0" encoding="utf-16"?>
<!--VoxCommando 2.2.0.7-->
<command id="702" name="Chrome já em foco" enabled="true" alwaysOn="False" confirm="False" requiredConfidence="0" loop="False" loopDelay="0" loopMax="0" description="This should stop the loop on the other command.">
  <action>
    <cmdType>Results.SetVar</cmdType>
    <params>
      <param>j</param>
      <param>31</param>
    </params>
    <cmdRepeat>1</cmdRepeat>
  </action>
  <action>
    <cmdType>OSD.ShowText</cmdType>
    <params>
      <param>program variable j = {j}</param>
    </params>
    <cmdRepeat>1</cmdRepeat>
  </action>
  <action>
    <cmdType>OSD.AddText</cmdType>
    <params>
      <param>Results.SetVar variable j = {Var.j}</param>
    </params>
    <cmdRepeat>1</cmdRepeat>
  </action>
  <event>Focused.chrome</event>
</command>


looking at your first command, it seems to just count down for 30 seconds before moving on, it sounds like your are trying to get it to stop counting down once the window is focused correct?

Kalle

  • $upporter
  • Hero Member
  • *****
  • Posts: 2320
  • Karma: 47
    • View Profile
Re: Variable looping (loop blocks) - how to break the loop?
« Reply #4 on: August 20, 2015, 07:39:56 PM »
wow, hard stuff to open a website  ::bugeyes


Why did you not use the command line parameter with the launch action?

eample code:

Code: [Select]
<?xml version="1.0" encoding="utf-16"?>
<!--VoxCommando 2.1.5.1-->
<command id="688" name="open url with payload" enabled="true" alwaysOn="False" confirm="False" requiredConfidence="0" loop="False" loopDelay="0" loopMax="0" description="">
  <action>
    <cmdType>Launch.RawParam</cmdType>
    <params>
      <param>{Path.PFx86}\AppData\Local\Google\Chrome\Application\chrome.exe</param>
      <param>{1}</param>
    </params>
    <cmdRepeat>1</cmdRepeat>
  </action>
  <action>
    <cmdType>TTS.Speak</cmdType>
    <params>
      <param>opening {PF.1}</param>
    </params>
    <cmdRepeat>1</cmdRepeat>
  </action>
  <action>
    <cmdType>OSD.ShowText</cmdType>
    <params>
      <param>opening {PF.1}</param>
    </params>
    <cmdRepeat>1</cmdRepeat>
  </action>
  <phrase>open site</phrase>
  <payloadFromXML phraseOnly="False" use2partPhrase="False" phraseConnector="by" Phrase2wildcard="anyone" optional="False">payloads\url.xml</payloadFromXML>
</command>


I think this is even better  ;)
« Last Edit: August 20, 2015, 07:42:00 PM by Kalle »
***********  get excited and make things  **********

marcusvdt

  • Sr. Member
  • ****
  • Posts: 152
  • Karma: 6
  • Researching
    • View Profile
Re: Variable looping (loop blocks) - how to break the loop?
« Reply #5 on: August 21, 2015, 12:04:31 AM »
wow, hard stuff to open a website  ::bugeyes


Why did you not use the command line parameter with the launch action?

eample code:

Code: [Select]
<?xml version="1.0" encoding="utf-16"?>
<!--VoxCommando 2.1.5.1-->
<command id="688" name="open url with payload" enabled="true" alwaysOn="False" confirm="False" requiredConfidence="0" loop="False" loopDelay="0" loopMax="0" description="">
  <action>
    <cmdType>Launch.RawParam</cmdType>
    <params>
      <param>{Path.PFx86}\AppData\Local\Google\Chrome\Application\chrome.exe</param>
      <param>{1}</param>
    </params>
    <cmdRepeat>1</cmdRepeat>
  </action>
  <action>
    <cmdType>TTS.Speak</cmdType>
    <params>
      <param>opening {PF.1}</param>
    </params>
    <cmdRepeat>1</cmdRepeat>
  </action>
  <action>
    <cmdType>OSD.ShowText</cmdType>
    <params>
      <param>opening {PF.1}</param>
    </params>
    <cmdRepeat>1</cmdRepeat>
  </action>
  <phrase>open site</phrase>
  <payloadFromXML phraseOnly="False" use2partPhrase="False" phraseConnector="by" Phrase2wildcard="anyone" optional="False">payloads\url.xml</payloadFromXML>
</command>


I think this is even better  ;)
thanks, yes that's better,  but still does not guarantee that chrome is in focus. If another software takes the focus from chrome,  then the remaining actions could be sent to another window. In some cases I'll be using the same type of commands for things not so simple as opening a Web page, hence the reason for developing a method in which I can trust to make sure what is the window I'm sending the keyboard actions to.  By the way, the window.focus action did not work for chrome anyway (using windows 8.1 and latest version of Chrome).
I'd like to avoid having to use an external script for this purpose.

marcusvdt

  • Sr. Member
  • ****
  • Posts: 152
  • Karma: 6
  • Researching
    • View Profile
Re: Variable looping (loop blocks) - how to break the loop?
« Reply #6 on: August 21, 2015, 12:19:42 AM »
with program variables such as {j} {i} {#M} and so on, can not be set, at least not in a way that I know of, when your are using
Code: [Select]
Results.SetVar j 30 then in order to use that variable you would have to call it using {Var.j} which the looping block can not see,

heres your command with OSD showing what I mean,
Code: [Select]
<?xml version="1.0" encoding="utf-16"?>
<!--VoxCommando 2.2.0.7-->
<command id="702" name="Chrome já em foco" enabled="true" alwaysOn="False" confirm="False" requiredConfidence="0" loop="False" loopDelay="0" loopMax="0" description="This should stop the loop on the other command.">
  <action>
    <cmdType>Results.SetVar</cmdType>
    <params>
      <param>j</param>
      <param>31</param>
    </params>
    <cmdRepeat>1</cmdRepeat>
  </action>
  <action>
    <cmdType>OSD.ShowText</cmdType>
    <params>
      <param>program variable j = {j}</param>
    </params>
    <cmdRepeat>1</cmdRepeat>
  </action>
  <action>
    <cmdType>OSD.AddText</cmdType>
    <params>
      <param>Results.SetVar variable j = {Var.j}</param>
    </params>
    <cmdRepeat>1</cmdRepeat>
  </action>
  <event>Focused.chrome</event>
</command>
I guess I can not assign a value to the j variable that is used on the for loop enen if I try to do that inside the loop. It seems I can only read it. Will test it tomorrow, but if I'm right,  then I don't see any way of breaking the loop.

Quote
looking at your first command, it seems to just count down for 30 seconds before moving on, it sounds like your are trying to get it to stop counting down once the window is focused correct?
yes, exactly. As per what I see on the log, it can't be done since an event never gets registered while the loop is running. Instead, I guess any events that occur while the loop is running will be queued and processed only after the loop finishes.

I think I will have to try something else tomorrow.

Thanks.

PegLegTV

  • $upporter
  • Sr. Member
  • *****
  • Posts: 497
  • Karma: 43
    • View Profile
Re: Variable looping (loop blocks) - how to break the loop?
« Reply #7 on: August 21, 2015, 01:06:48 AM »
maybe you can create your own loop by using VC.SetEventTimer with a 3s wait, and then have another command check focus of chrome

IF Focused then send the actions,
IF Not then trigger VC.SetEventTimer,

I would be carefull doing to short of a wait as it can cause VC to get stuck in a loop,  :bigno

Simple Example:
Code: [Select]
<?xml version="1.0" encoding="utf-16"?>
<!--VoxCommando 2.2.0.7-->
<commandGroup open="True" name="Chrome focus" enabled="True" prefix="" priority="0" requiredProcess="" description="">
  <command id="734" name="make sure chrome is open then execute me" enabled="true" alwaysOn="False" confirm="False" requiredConfidence="0" loop="False" loopDelay="0" loopMax="0" description="">
    <action>
      <cmdType>VC.SetEventTimer</cmdType>
      <params>
        <param>3s</param>
        <param>Chrome Test</param>
      </params>
      <cmdRepeat>1</cmdRepeat>
    </action>
  </command>
  <command id="742" name="Chrome focus test" enabled="true" alwaysOn="False" confirm="False" requiredConfidence="0" loop="False" loopDelay="0" loopMax="0" description="">
    <if ifBlockDisabled="False" ifNot="False">
      <ifType>ProgramFocused</ifType>
      <ifParams>chrome&amp;&amp;</ifParams>
      <then>
        <action>
          <cmdType>OSD.ShowText</cmdType>
          <params>
            <param>Chrome is now Focused</param>
          </params>
          <cmdRepeat>1</cmdRepeat>
        </action>
      </then>
      <else>
        <action>
          <cmdType>Window.Focus</cmdType>
          <params>
            <param>chrome</param>
          </params>
          <cmdRepeat>1</cmdRepeat>
        </action>
        <action>
          <cmdType>VC.SetEventTimer</cmdType>
          <params>
            <param>3s</param>
            <param>Chrome Test</param>
          </params>
          <cmdRepeat>1</cmdRepeat>
        </action>
      </else>
    </if>
    <event>Chrome Test</event>
  </command>
</commandGroup>

Quote
By the way, the window.focus action did not work for chrome anyway (using windows 8.1 and latest version of Chrome).
I'd like to avoid having to use an external script for this purpose.

I tested Window.Focus chrome (all lower case letters) on windows 8.1 and it worked for me every time, I did notice that using kalle's method for me focused Chrome every time, however it does open a new tab when I open another URL, not sure if that would cause problems with what you are doing


« Last Edit: December 29, 2015, 12:55:20 AM by PegLegTV »

Kalle

  • $upporter
  • Hero Member
  • *****
  • Posts: 2320
  • Karma: 47
    • View Profile
Re: Variable looping (loop blocks) - how to break the loop?
« Reply #8 on: August 21, 2015, 05:49:25 AM »
I can confirm, my method focused Chrome every time.
***********  get excited and make things  **********

marcusvdt

  • Sr. Member
  • ****
  • Posts: 152
  • Karma: 6
  • Researching
    • View Profile
Re: Variable looping (loop blocks) - how to break the loop?
« Reply #9 on: August 21, 2015, 10:51:44 AM »
Thanks guys!
I ended up with a command that can be used for confirming any program is in focus. You pass the the process name and the max # of loops in payloads. Now works like a charm!
For automating critical applications it is essential that the focus is reinforced and confirmed at every command. Windows applications sometime get the focus (ie anti virus update dialog pops up in the screen), so confirming the focus before sending commands to a window is desirable.

Thanks for the ideas! This is exactly the help that I was looking for! You rock big time!


Code: [Select]
<?xml version="1.0" encoding="utf-16"?>
<!--VoxCommando 2.2.0.7-->
<groupCollection open="True" name="Share">
  <commandGroup open="True" name="Launch Chrome" enabled="True" prefix="" priority="0" requiredProcess="" description="">
    <command id="733" name="open url with payload" enabled="true" alwaysOn="False" confirm="False" requiredConfidence="0" loop="False" loopDelay="0" loopMax="0" description="">
      <if ifBlockDisabled="False" ifNot="True">
        <ifType>ProcessRunning</ifType>
        <ifParams>chrome&amp;&amp;</ifParams>
        <then>
          <action>
            <cmdType>Launch.RawParam</cmdType>
            <params>
              <param>{Path.PFx86}\Google\Chrome\Application\chrome.exe</param>
              <param>{1}</param>
            </params>
            <cmdRepeat>1</cmdRepeat>
          </action>
          <action>
            <cmdType>TTS.SpeakSync</cmdType>
            <params>
              <param>Launching Chrome</param>
            </params>
            <cmdRepeat>1</cmdRepeat>
          </action>
          <action>
            <cmdType>VC.Pause</cmdType>
            <params>
              <param>500</param>
            </params>
            <cmdRepeat>1</cmdRepeat>
          </action>
        </then>
        <else />
      </if>
      <if ifBlockDisabled="False" ifNot="False">
        <ifType>ProcessRunning</ifType>
        <ifParams>chrome&amp;&amp;</ifParams>
        <then>
          <action>
            <cmdType>Results.SetVar</cmdType>
            <params>
              <param>loopsfocus</param>
              <param>0</param>
            </params>
            <cmdRepeat>1</cmdRepeat>
          </action>
          <action>
            <cmdType>VC.SetEventTimer</cmdType>
            <params>
              <param>2s</param>
              <param>FocusTest</param>
              <param>chrome</param>
              <param>10</param>
            </params>
            <cmdRepeat>1</cmdRepeat>
          </action>
          <action>
            <cmdType>OSD.ShowText</cmdType>
            <params>
              <param>{1}</param>
            </params>
            <cmdRepeat>1</cmdRepeat>
          </action>
          <action>
            <cmdType>TTS.Speak</cmdType>
            <params>
              <param>Browsing to {PF.1}</param>
            </params>
            <cmdRepeat>1</cmdRepeat>
          </action>
        </then>
        <else>
          <action>
            <cmdType>TTS.Speak</cmdType>
            <params>
              <param>I couldn't open Chrome</param>
            </params>
            <cmdRepeat>1</cmdRepeat>
          </action>
          <action>
            <cmdType>OSD.ShowText</cmdType>
            <params>
              <param>I couldn't open Chrome</param>
              <param>2000</param>
              <param>1</param>
            </params>
            <cmdRepeat>1</cmdRepeat>
          </action>
        </else>
      </if>
      <phrase>abrir site</phrase>
      <payloadFromXML phraseOnly="False" use2partPhrase="False" phraseConnector="by" Phrase2wildcard="anyone" optional="False">payloads\url.xml</payloadFromXML>
    </command>
  </commandGroup>
  <commandGroup open="True" name="Generic focus confirmation" enabled="True" prefix="" priority="0" requiredProcess="" description="">
    <command id="761" name="{1} focus test" enabled="true" alwaysOn="False" confirm="False" requiredConfidence="0" loop="False" loopDelay="0" loopMax="0" description="">
      <if ifBlockDisabled="False" ifNot="False">
        <ifType>(A)Contains(B)</ifType>
        <ifParams>{1}&amp;&amp;{1</ifParams>
        <then>
          <action>
            <cmdType>OSD.ShowText</cmdType>
            <params>
              <param>Can't check focus. Wrong use of my logics!</param>
            </params>
            <cmdRepeat>1</cmdRepeat>
          </action>
          <action>
            <cmdType>VC.StopMacro</cmdType>
            <params />
            <cmdRepeat>1</cmdRepeat>
          </action>
        </then>
        <else />
      </if>
      <if ifBlockDisabled="False" ifNot="False">
        <ifType>(A)Contains(B)</ifType>
        <ifParams>{2}&amp;&amp;{2</ifParams>
        <then>
          <action>
            <cmdType>OSD.ShowText</cmdType>
            <params>
              <param>Can't check focus. Wrong use of my logics!</param>
            </params>
            <cmdRepeat>1</cmdRepeat>
          </action>
          <action>
            <cmdType>VC.StopMacro</cmdType>
            <params />
            <cmdRepeat>1</cmdRepeat>
          </action>
        </then>
        <else />
      </if>
      <if ifBlockDisabled="False" ifNot="False">
        <ifType>ProgramFocused</ifType>
        <ifParams>{1}&amp;&amp;</ifParams>
        <then>
          <action>
            <cmdType>VC.StopEventTimer</cmdType>
            <params>
              <param>FocusTest</param>
            </params>
            <cmdRepeat>1</cmdRepeat>
          </action>
          <action>
            <cmdType>OSD.ShowText</cmdType>
            <params>
              <param>{1} is now focused</param>
            </params>
            <cmdRepeat>1</cmdRepeat>
          </action>
          <action>
            <cmdType>VC.TriggerEvent</cmdType>
            <params>
              <param>FocusConfirmed</param>
              <param>{1}</param>
            </params>
            <cmdRepeat>1</cmdRepeat>
          </action>
          <action>
            <cmdType>VC.StopMacro</cmdType>
            <params />
            <cmdRepeat>1</cmdRepeat>
          </action>
        </then>
        <else>
          <action>
            <cmdType>Window.Focus</cmdType>
            <params>
              <param>{1}</param>
            </params>
            <cmdRepeat>1</cmdRepeat>
          </action>
          <action>
            <cmdType>VC.StopEventTimer</cmdType>
            <params>
              <param>FocusTest</param>
            </params>
            <cmdRepeat>1</cmdRepeat>
          </action>
          <action>
            <cmdType>VC.SetEventTimer</cmdType>
            <params>
              <param>2s</param>
              <param>FocusTest</param>
              <param>{1}</param>
              <param>{2}</param>
            </params>
            <cmdRepeat>1</cmdRepeat>
          </action>
          <action>
            <cmdType>PY.ExecString</cmdType>
            <params>
              <param>result={Var.loopsfocus}+1</param>
            </params>
            <cmdRepeat>1</cmdRepeat>
          </action>
          <action>
            <cmdType>Results.SetVar</cmdType>
            <params>
              <param>loopsfocus</param>
              <param>{LastResult}</param>
            </params>
            <cmdRepeat>1</cmdRepeat>
          </action>
        </else>
      </if>
      <if ifBlockDisabled="False" ifNot="True">
        <ifType>(A)&lt;(B)</ifType>
        <ifParams>{Var.loopsfocus}&amp;&amp;{2}</ifParams>
        <then>
          <action>
            <cmdType>VC.StopEventTimer</cmdType>
            <params>
              <param>FocusTest</param>
            </params>
            <cmdRepeat>1</cmdRepeat>
          </action>
          <action>
            <cmdType>TTS.Speak</cmdType>
            <params>
              <param>I couldn't get {1} in focus, so stopping here.</param>
            </params>
            <cmdRepeat>1</cmdRepeat>
          </action>
        </then>
        <else />
      </if>
      <event>FocusTest</event>
    </command>
  </commandGroup>
</groupCollection>

jitterjames

  • Administrator
  • Hero Member
  • *****
  • Posts: 7714
  • Karma: 116
    • View Profile
    • VoxCommando
Re: Variable looping (loop blocks) - how to break the loop?
« Reply #10 on: August 21, 2015, 05:42:48 PM »
I've never had a need for such a command but I'm glad you found something that works for you. 
I can suggest one very minor improvement you could make to improve flexibility.

You are using {2} to pass a counter with your event and stopping after 20 iterations.

Instead of starting at 1, incrementing by 1 each time and stopping at 20, you could start by passing the maximum number of times you want to repeat, decrementing by 1 each time and stopping at 0.  That way you could initiate the events using different max repeats for different programs that you are trying to focus.  I don't know if this helps you or not, but maybe...

marcusvdt

  • Sr. Member
  • ****
  • Posts: 152
  • Karma: 6
  • Researching
    • View Profile
Re: Variable looping (loop blocks) - how to break the loop?
« Reply #11 on: August 21, 2015, 05:54:44 PM »
Thanks for the tip James. That is what it does. I pass the name of the process and the max number of loops that it can do. The max number of loops reflects half the delay between each loop, in seconds.
If the desired window gets in focus before the max loops has occurred, then I tell the user the program is in focus. If the max number of loops is achieved,  then a timeout has occured and the user is told.
hopefully we are talking the same thing,  but I am increasing the var while you thought about decreasing it?

jitterjames

  • Administrator
  • Hero Member
  • *****
  • Posts: 7714
  • Karma: 116
    • View Profile
    • VoxCommando
Re: Variable looping (loop blocks) - how to break the loop?
« Reply #12 on: August 21, 2015, 06:23:53 PM »
I see now what you are doing.  I did not realise you were creating a variable as well.

What I was proposing would still be better though for two reasons.

1 - no variable is needed.
2 - as a result, you don't need to worry about two of these commands executing at the same time and interfering with each other because of a shared global variable.

marcusvdt

  • Sr. Member
  • ****
  • Posts: 152
  • Karma: 6
  • Researching
    • View Profile
Re: Variable looping (loop blocks) - how to break the loop?
« Reply #13 on: August 21, 2015, 06:56:32 PM »
Yeah, I like the idea of not having the need for the variable. I was already considering an eventual situation where two of the same command would cause problems with that variable. Would you mind posting an example of what you proposed?
I'm not in the computer now, but I will be testing this as soon as possible.

Thanks.

jitterjames

  • Administrator
  • Hero Member
  • *****
  • Posts: 7714
  • Karma: 116
    • View Profile
    • VoxCommando
Re: Variable looping (loop blocks) - how to break the loop?
« Reply #14 on: August 21, 2015, 10:08:23 PM »
OK.  I think you could have figured this out quite easily yourself but here it is anyway. It has been a while since I wrote a command in VC so I enjoyed it. :D

This is just the command that is triggered by the event.  You should not need to modify the other command.

Code: [Select]
<?xml version="1.0" encoding="utf-16"?>
<!--VoxCommando 2.2.0.7-->
<command id="761" name="{1} focus test" enabled="true" alwaysOn="False" confirm="False" requiredConfidence="0" loop="False" loopDelay="0" loopMax="0" description="">
  <if ifBlockDisabled="False" ifNot="False">
    <ifType>(A)Contains(B)</ifType>
    <ifParams>{1}{2}&amp;&amp;{</ifParams>
    <then>
      <action>
        <cmdType>OSD.ShowText</cmdType>
        <params>
          <param>Can't check focus. Wrong use of my logics!</param>
        </params>
        <cmdRepeat>1</cmdRepeat>
      </action>
      <action>
        <cmdType>VC.StopMacro</cmdType>
        <params />
        <cmdRepeat>1</cmdRepeat>
      </action>
    </then>
    <else />
  </if>
  <if ifBlockDisabled="False" ifNot="False">
    <ifType>ProgramFocused</ifType>
    <ifParams>{1}&amp;&amp;</ifParams>
    <then>
      <action>
        <cmdType>OSD.ShowText</cmdType>
        <params>
          <param>{1} is now focused</param>
        </params>
        <cmdRepeat>1</cmdRepeat>
      </action>
      <action>
        <cmdType>VC.TriggerEvent</cmdType>
        <params>
          <param>FocusConfirmed</param>
          <param>{1}</param>
        </params>
        <cmdRepeat>1</cmdRepeat>
      </action>
      <action>
        <cmdType>VC.StopMacro</cmdType>
        <params />
        <cmdRepeat>1</cmdRepeat>
      </action>
    </then>
    <else>
      <action>
        <cmdType>Window.Focus</cmdType>
        <params>
          <param>{1}</param>
        </params>
        <cmdRepeat>1</cmdRepeat>
      </action>
      <action>
        <cmdType>PY.ExecString</cmdType>
        <params>
          <param>result={2}-1</param>
        </params>
        <cmdRepeat>1</cmdRepeat>
      </action>
    </else>
  </if>
  <if ifBlockDisabled="False" ifNot="False">
    <ifType>(A)&lt;(B)</ifType>
    <ifParams>{LastResult}&amp;&amp;1</ifParams>
    <then>
      <action>
        <cmdType>TTS.Speak</cmdType>
        <params>
          <param>I couldn't get {1} in focus, so stopping here.</param>
        </params>
        <cmdRepeat>1</cmdRepeat>
      </action>
    </then>
    <else>
      <action>
        <cmdType>VC.SetEventTimer</cmdType>
        <params>
          <param>2s</param>
          <param>FocusTest</param>
          <param>{1}</param>
          <param>{LastResult}</param>
        </params>
        <cmdRepeat>1</cmdRepeat>
      </action>
    </else>
  </if>
  <event>FocusTest</event>
</command>