Hi Jamie,
What is local inst = mc.mcGetInstance() and why does it need to be first?
It is possible and may become fact one day, that multiple instances of Mach can run at once. This was allowed for
in the original 'design' of Mach. As a consequence there are many instructions in Mach which need to be applied
to a particular instance of Mach. As it turns out Mach as currently deployed allows only one instance, usually instance
'0' and thus if you used the variable 'inst' in any part of Mach it will probably work. The safe way is to ensure that
the proper and current instance is used....ergo mc.mcGetInstance() is used within each scope.
That explanation is tied up with your next question:
In your version, you start each section by breaking out "local *********" first, instead of all on one line. Is that required?
"Local" declares that this variable is defined within the current 'scope' which generally means within the function in
which it is declared. If you attempt to use the variable outside of that scope it will fail.
Lua is a 'self memory managed language'. If you've had any C programming experience you will know that you have
to explicitly mange memory in C, ie you have to assign memory for variables with Malloc etc. You also have to delete them
when you have finished or risk that all the memory of the PC will be clogged up with variables which are no longer required.
Lua is self managed which means that when a variable is no longer required it is automatically garbage collected. Generally
speaking this means that when a variable goes 'out of scope' it get garbage collected. Using the prefix 'local' makes it explicit
to Lua that the variable can be deleted once it goes out of scope. If a variable is not declared as 'local' it becomes a global variable
visible throughout the Lua chunk.
That has consequences. A global variable will require a specific memory location that stays constant throughout the Lua
session. Thus any time the variable is accessed the CPU has to find, resolve and read the contents of that memory address,
which may be in a different 'page' of memory and can be quite slow. A local variable is stored on a stack. Imagine you were
working a maths problem and each intermediate result you wrote down on a separate piece of paper. You then put that piece of
paper on a stack of the previous results. When you need to retrieve a particular result all you need to know is 'that result
is fourth from the top of the stack'. That means that the memory location where your result is stored goes up or down depending
on how many pieces of paper you have added but that memory is stored locally and is very fast to retrieve. Additionally when
you have finished your calculation, ie the function completes and goes out of scope the whole stack can be deleted.
The general rule is that for efficiency make all variables local, its faster and the automatic garbage collector works best.
Is "local rc" what gives you the ability to read the error code?
local hsig
local rc
hsig, rc = mc.mcSignalGetHandle(inst, mc.OSIG_OUTPUT0);
The particular API you have highlighted in your question is a kind of function. In this case the function is 'get the current
memory address that corresponds to the signal OSIG_OUTPUT0'. When the function is complete it is going to pass back to the
calling program TWO results, the first is the requested memory address, hsig, and the second is a return code. As you've already
seen that if a function fails to complete it will return a code that indicates what went wrong.
Steve is a very accomplished and experienced programmer and he consistently recommends that you should check every
return code for success. I am a very much less disciplined programmer and tend not to do so. There are specific circumstances
where I do, things like MERROR_TIMED_OUT for example.
The two results are assigned to each label from left two right. Thus the signal handle (memory address) is assigned to
hsig and the return code is assigned to rc. If you did not have rc in the lefthand list of labels the result is discarded.
I see this at the bottom of many scripts and I read about it in the Lua manual. What does this do?
if (mc.mcInEditor() == 1) then
m3();
Your macro, in this case m3() is a function. In order for this function to run its needs to be formally 'asked' to execute.
When running a Gcode file and the interpreter encouters m3() Mach will find and execute that function.
What happens though if you are still writing your function (macro) in the editor and you want to run it one step at a time
to see if its going to work? How does the function get invoked or 'asked' to execute? That is the meaning of that extra bit of
code on the bottom of each macro. If you hit <Run, single step> in the editor it can't run the function directly so it
passes to the last bit of code and asks 'Is Mach in Edit Mode', if it is then <m3()>, ie it invokes/ 'asks' the function to run.
Craig