Hi Ray -
Oh NO you don't - I won't let you blame me for that one!

(well I guess you could, but I was not the instigator and am not responsible).
The history as I know it:
In days of yore (the era of Art), mach was essentially single threaded code internally. In those days all calls to the "code" API were synchronous - there was no other choice - that was how the APIs worked (whether by design or by accident).
One of the things Brian did (so he has told me) was to change a bunch of mach internals to be mutli threaded...
AFAIK that was where the problems with the Code call began. Suddenly the Code started returning before the code string was executed - the multi-threading changes changed the semantics for existing scripts. Instant lack of backward compatibility was the result.
What I think should have happened was that Brian should have implemented the existing code call to be sync and added a new "QueueCodeAndReturnBeforeDone" call. That would have preserved the semantics of existing scripts. For whatever reasons, Brian choose not to take that approach.
To complicate things further, after the multi threading change, there were some attempts to restore the old semantics. Some mach versions that had sync code calls and some did not - and it swapped back and forth a few times. Add to that the fact that back then there was no call to get the mach version... so you could not even check for what the semantics were on the version you found yourself running on...
All I did back then as ask for the addition of a call to get the mach version. I figured if I could get the version, at least I could code for version dependencies. (Alas, that bit of idealism on my part depends on having a good record of what changes are in each version - something that, in IMHO, is not Brian's strong suit).
After the uproar the multi threading changes caused quieted down, people started using "IsMoving" as the only sync tool available. "When the only tool you own is a hammer, all problems look like nails...."
That led to another set of changes... when people put the IsMoving in a hard loop the CPU got starved out - so we had to add sleep statements. Then Brain forced a sleep equiv internal to IsMoving... but again you could not tell when you need to use and when you do not - so people put it in and on many mach versions I suspect the scripts end up wasting time in "extra" sleeps.
Now, then, I regurgitate all this in order to set the stage for this statement:
IsMoving really is a IsMoving wait.
It is NOT a general sync method to cause a pause until mach finishes the action you requested via a CB API.
Since the advent of the multi threading change, there is NO GENERAL WAY TO CALL MACH AND RELIABLY WAIT until the API call is complete.
I too used accept the Mach urban lore that IsMoving was was a misnamed sync call, and that it was an API sync mechanism.
It seems to do no harm if used for an API that does not cause movement, as in that case there is no movement in process and so the IsMoving call just returns false and your wait loop exits quickly.
Here is how I learned that it really, truely, is only a wait for movement to stop.
I got into trouble when I tried to do this sequence:
Code("m6")
While IsMoving()
Sleep 100
wend
If ISMoving really were a sync mechanism for the Code call, the script would hang in the IsMoving loop until the M6 competes.
That is NOT what happens.
M6 is particularly nasty example - from the gcode language standpoint, a single command was called for and you do not want to go on until the M6 is over, finished and done with.
Looping on IsMoving will not accomplish that desire! You will only pause until the "current motion" is complete.
Think about how mach implements M6 as a series of calls to user scripts and the problems become more apparent. In the case of M6, there is NOT a 1:1 mapping between gcode word execution and movement. The IsMoving loop technique effectively only works when there is a 1:1 mapping between gcode word execution and movement.
Alas, not even then does it always work... The problem is that an IsMoving loop depends on a motion having been started before the code call returns to the calling script - and due to multi threaded driven timing holes inside mach that may not always happen. Most of the time it does, but not all the time.
IHMO the sad fact is that this is an area where mach is fundamentally broken and there are no tools available to the script programmer to handle this reliably. Mach's script APIs (and Mach itself) has no concept of critical resources, locks, semaphores etc.
Frankly, I think it's pure dumb luck that mach scripts work as well as they do considering the multi-threading stuff and total lack of resource locking.
Dave
Just and update to what I said about FIFO and one-shot. I'm not sure but I think this has changed at some time. I THINK you can now send multiple CODE statements without an isMoving() after each one. I THINK you can now get away with a series of CODE statements with just one while isMoving() after the last one. i.e. I THINK Mach buffers the CODE requests in order. Is it reliable? - your guess is as good as mine - which version do I think it changed in? - I don't know. I still stick an isMoving() after each one - but that's just me.
Ian
Ian,
That is correct. That change was made perhaps two years ago, back around v30-something. It was done at the request of David Bagby, to make MachStdScreen work better. AFAIK, it does work reliably.
Regards,
Ray L.