Know what condition was fulfilled in "Pause Until any of the conditions true"?

So I have a final confirmation step I need to do which can be done from inputs from 3 different sources.

but the way the confirm is done depends on what condition was fulfilled.

eg. If a variable condition is fulfilled then an extra step needs to be done.
however if the image true condition is fulfilled, then the extra step has to be avoided.
(the extra step should not occur when image fulfilled condition continues the macro)


Thanks in anticipation

Any reason something like this wouldn't work?


You could also go the other way too:


@gglick has given you a good solution.
However, I would recommend a slight adjustment:

  1. Never use a KM variable name of "VarName", since this is the default name provided by many KM Actions, and your use of it could easily be confused with it being set in another Action or Macro.
    • I recommend always naming your KM variables so that the name is a brief indicator of its contents.
    • For example, of the KM Variable is supposed to contain the name of an application, I'd name it "AppName".
    • Actually, I'd go one step further and name it "Local__AppName" IF it does NOT need to be used in any other Macro, or subsequent execution of this Macro. This forces the variable to be a "Local" variable. For more info, see KM Variable Types.
  2. You should initialize the value of "VarName" PRIOR to the "Pause Until" Action, so you know exactly what to expect in the later "IF/THEN" Action
    • I would typically Set "VarName" to something like "[NONE]" so there is no doubt as to its value prior to the "Pause Until"

That's a good solution, but I am worried what if the 2 things happen in quick succession, suppose "Found image condition" continues the macro but because the processes are happening so fast, the variable changes in the next step (then the variable if then action block will add the action to a scenario where it was the image condition pathway that should've gone through)
Basically the next process depends on whether it was the image that was found or whether the variable changed. (If image is found, then the variable if action block shouldn't run)

I think I should've mentioned that both conditions will become true. It's just that I want to macro to proceed depending on whichever one is faster.

As part of the Then part of the found images condition (i.e., in the case that image is found), set a variable as a switch to a value of 1, and have that value for the switch prevent the processing of the second If...Then (i.e., include 'if switch<>1' in the conditions for the second If). At the very end, simply reset the switch to 0. Alternatively, you can include an Abort This Macro action at the end of the first conditional's Then statements.

Actions are atomic. Which means that no other action, even in an asynchronous macro, can execute while an action is running. (The obvious exception are actions which contain other actions.) There is a way to make groups of sequential actions atomic, and that's by using semaphores around each place that you need to be atomic.

In this case one of the two actions you are testing for is an internal KM variable. The other condition you are testing for is an external condition (an image find) which can occur completely independently of the KM Engine.

One way you can guarantee which action occurs first is to ensure that each time you assign a value to the variable, (in any macro) protect that assignment with a semaphore.

If the two conditions you were testing for were both outside of KM, then you could never know which one occurs first (even if KM let you know which condition occurred first) because even KM wouldn't really know. However in this case one of the two conditions is a KM variable which is within your control thus a 100% solution is possible using semaphores.

This is not true. While a condition is being evaluated, other actions in other macros can still be running. While an action is waiting for results or otherwise just waiting, other actions in other macros can be running.

There is basically no solution to this - there is no way to guarantee that one condition is checked before the other.

The best you could do would be to check each condition in a loop. Something like:

  • While calculation 1 execute:
    • if condition 1
      • Set variable “Condition” to 1
      • Break From Loop
    • if condition 2
      • Set variable “Condition” to 2
      • Break From Loop

But Condition 2 could become true right after the condition 2 test, and then condition 1 could become true, and then the loop could repeat.

At some point you have to accept that the two events have happened at more or less the same time.

Being wrong is sad. I was wrong. I'm sorry. Here's what I based my statement on. I asked Peter the following questions and got his answer below. (Aug 4, 2017)

• Question: is the Set Variable to Calculation action (or any single action) “atomic", or can two macros running asynchronously be running two calculations at the same time?

It is atomic.

The Set Variable to Calculation action is atomic because it is basically a trivial action. It evaluates the calculation, which must return immediately, and sets the variable. It is all done “instantly” as far as Keyboard Maestro is concerned.

But many other actions are not instant. An easy test is to see if there is a Set Timeout option on the action (shown by the clock symbol in the gear menu). If there is, then the action definitely is not atomic. But even if there is not, that is no guarantee that other actions cannot run at the same time - it just means I have decided that the maximum time for the action is fixed and small, and so a timeout is not helpful. For example, even an action like Type a Keystroke is not atomic in this sense, since it will press the key and release the key and potentially delay during or after, and during that delay other macros can run.

That's very illuminating and makes perfect sense. It gives me a lot of insight into how KM works. I read too much into the word atomic, sorry again. And thanks.