Hi,
I am not 100% confident in what you mean. We do have a signal library, but I don't believe this implementation was in Mach4. It was added with the CommonGUIModule inside of MachPro.
The main implementation is in CommonGUIModule:
SIG_LIBRARY_INST[_inst]: common, per-Mach-instance handlers.
MACHINE_TYPE_SIG_LIBRARY_INST[_inst]: machine-specific handlers, such as mill, plasma, grinder, or height-control behavior.
SCREEN_SIG_LIBRARY_INST[_inst]: screen-specific handlers for multi-instance screens.
SCREEN_SIG_LIBRARY: legacy/global screen handlers used by older screen versions.
Each table is keyed by a Mach signal ID. The value is a Lua callback:
SIG_LIBRARY_INST[_inst][signalId] = function(sig_state)
-- Handle the signal transition
endWhen Mach reports a signal transition, CommonSignalScript() converts the state to a Boolean and calls _CommonSignalScript(). That function dispatches the event through the layers above, then runs the generic SignalScript hooks:
CommonSignalScript
- SignalScript callback
- SIG_LIBRARY_INST[instance][signal]
- MACHINE_TYPE_SIG_LIBRARY_INST[instance][signal]
- SCREEN_SIG_LIBRARY_INST[instance][signal]
- SCREEN_SIG_LIBRARY[signal]
- SignalScript hooks
The common table is rebuilt by UpdateSignalLibraryArray() in CommonGUIModule. It registers handlers for:
- Axis positive and negative limit status signals
- Axis homed signals
- Toolpath mouse down/up
- Motion-inhibit interlock input
- Machine enabled/disabled state
- Spindle-brake output lookup
It also stores the resolved spindle-brake signal ID in SIG_LIBRARY_INST[_inst].SpindleBrakeOutput and SIGNAL_LIB_ARRAY.SpindleBrakeOutput.
The rebuild entry point is CommonUpdateSignalLibraryArray() in CommonGUIModule. It:
- Calls the active screen/module’s UpdateSignalLibraryArray(), if present.
- Reads auxiliary-output button mappings from the profile.
- Enables or disables the corresponding auxiliary screen buttons.
- Runs the UpdateSignalLibrary hooks, allowing machine-specific modules to register more callbacks.
The screen-specific tables are populated separately. For example:
- V2 screens build SCREEN_SIG_LIBRARY_INST[_inst] in CommonScreenV02.
- Mill and plasma modules populate MACHINE_TYPE_SIG_LIBRARY_INST for tool-changer signals in MillGUIModule.lua and PlasmaGUIModule.
- Height controllers add their own signal handlers in HeightControllers
This Lua “library” sits above the actual Mach signal subsystem. The actual signal objects are handled by the C++/Mach API layer using functions such as mcSignalGetHandle, mcSignalGetNextHandle, mcSignalGetInfo, mcSignalGetState, and mcSignalMap. The API documentation explicitly distinguishes signals from physical I/O: signals can be mapped to I/O, but the signal abstraction does not depend on a particular I/O device.
| Table | Scope | Purpose |
| SIG_LIBRARY_INST | Per Mach instance | Common machine behavior |
| MACHINE_TYPE_SIG_LIBRARY_INST | Per Mach instance | Machine-specific behavior, such as mill, plasma, grinder, or height control |
| SCREEN_SIG_LIBRARY_INST | Per Mach instance | Screen-specific behavior |
| SCREEN_SIG_LIBRARY | Global/legacy | Older single-instance screen handlers |
Each table uses a signal ID as its key and a Lua function as its value:
SIG_LIBRARY_INST[instanceIndex][signalId] = function(signalState)
-- React to the signal transition
endsignalState is normalized to a Boolean before dispatch.
Dispatch sequence
When Mach detects a signal transition, the following path is used:
- CommonSignalScript()
- _CommonSignalScript()
- module SignalScript()
- SIG_LIBRARY_INST[instance][signal]
- MACHINE_TYPE_SIG_LIBRARY_INST[instance][signal]
- SCREEN_SIG_LIBRARY_INST[instance][signal]
- SCREEN_SIG_LIBRARY[signal]
- SignalScript hooks
The dispatcher does not stop after the first matching table. A signal can therefore have common, machine-specific, and screen-specific behavior.
Building the common library
CommonGUIModule.UpdateSignalLibraryArray() registers the standard handlers, including:
- Positive and negative axis-limit status signals
- Axis-homed signals
- Toolpath mouse events
- Motion-inhibit interlock input
- Machine enable and disable signals
- Spindle-brake output lookup
The wrapper, CommonGUIModule.CommonUpdateSignalLibraryArray(), also:
- Calls a machine module’s UpdateSignalLibraryArray(), if implemented
- Reads auxiliary output-button assignments from the Mach profile
- Updates auxiliary-button enabled states
- Runs the UpdateSignalLibrary hooks
nstance indexing
The tables are indexed by the untagged instance index:
local instanceIndex = w.GetUTI(inst)Handlers registered for one instance should remain associated with that instance. This matters in multi-instance configurations because the same signal number may have different mappings or machine behavior in different instances.
Registration example
A machine module can register a handler for an OEM-mapped signal like this:
local signalInfo = w.GetOEMParamIOSigObject(
"TC_ToolReleaseButtonInput",
instanceIndex
)
if signalInfo ~= nil and signalInfo["type"] == "Input Signal" then
MACHINE_TYPE_SIG_LIBRARY_INST[instanceIndex][signalInfo["sigid"]] =
function(signalState)
m.ToolReleaseButtonInputChanged(signalState, 1)
end
endThe mill and plasma implementations follow this pattern in MillGUIModule and PlasmaGUIModule.
Use Case: Tool Release Button
A useful example is a tool changer with a physical tool-release button.
Requirement
When the operator presses or releases the tool-release input:
- The machine-specific tool-changer logic should run.
- The handler should use the signal mapping configured for the current instance.
- Multiple spindles or indexed tool-release inputs should be supported.
Registration
During signal-library setup, the machine module resolves the OEM parameter to its actual signal ID and registers a callback:
local signalInfo = w.GetOEMParamIOSigObject(
"TC_ToolReleaseButtonInput",
instanceIndex
)
if signalInfo ~= nil and signalInfo["type"] == "Input Signal" then
MACHINE_TYPE_SIG_LIBRARY_INST[instanceIndex][signalInfo["sigid"]] =
function(signalState)
m.ToolReleaseButtonInputChanged(signalState, 1)
end
endFor a second spindle, the module can resolve a parameter such as:
TC_ToolReleaseButtonInput2and register a callback that passes spindle index 2.
Runtime behavior
When the physical input changes:
Mach updates the underlying signal.
Mach invokes CommonSignalScript.
The signal ID is used to look up the callback in MACHINE_TYPE_SIG_LIBRARY_INST.
The callback invokes:
- Mach updates the underlying signal.
- Mach invokes CommonSignalScript.
- The signal ID is used to look up the callback in MACHINE_TYPE_SIG_LIBRARY_INST.
[li]The callback invokes:
[/li][/list]
[code]m.ToolReleaseButtonInputChanged(signalState, spindleIndex)[/code]
[/li]
- The tool-changer module performs the configured action.
This keeps the machine module independent of the physical I/O device. The module only needs to know the logical OEM parameter and the resolved Mach signal ID.
Another Use Case: Machine Enable State
The common library registers mc.OSIG_MACHINE_ENABLED for every instance. Its callback updates the cached enable state and starts the appropriate enable or disable sequence.
The handler also performs special startup protection because Mach can emit an initial disabled state while signal synchronization is taking place. That logic is in CommonGUIModule.lua.
This is a good example of behavior that belongs in SIG_LIBRARY_INST rather than a machine-specific table because every screen and machine type needs consistent machine-enable behavior.
When to use each layer:
Use SIG_LIBRARY_INST when:
- The behavior is common to all machine types.
- It is instance-specific.
- It concerns limits, homing, machine enable, or core GUI behavior.
Use MACHINE_TYPE_SIG_LIBRARY_INST when:
- The behavior belongs to a machine family.
- The signal is related to a tool changer, plasma THC, grinder, or similar subsystem.
- The same machine module may register different signals per instance.
Use SCREEN_SIG_LIBRARY_INST[ when:
- The callback updates controls belonging to a particular screen.
- The screen supports multiple Mach instances.
Use SCREEN_SIG_LIBRARY when:
- The behavior is legacy/global screen behavior.
- The callback is intentionally not instance-specific.
Use SCREEN_SIG_LIBRARY only for legacy/global screen behavior where the callback is intentionally not instance-specific.
Relationship to the Lua Signal Library
The Lua signal library described earlier operates above this lower-level signal/I/O layer:
Physical hardware or simulated device
- HMCIO I/O handle
- mcSignalMap()
- HMCSIG logical signal
- CommonSignalScript()
- Lua signal-library callback
For example, a tool-release button may be physically connected to an input device. The device is mapped to a logical signal. The GUI layer then registers a Lua callback keyed by that signal ID:
MACHINE_TYPE_SIG_LIBRARY_INST[instanceIndex][signalId] =
function(signalState)
m.ToolReleaseButtonInputChanged(signalState, spindleIndex)
endThe callback does not need to know whether the signal came from:
- A simulator
- A motion controller
- An Ethernet I/O device
- A PCI or USB device
- Another plugin
I hope this info dump can help solve your questions?
Something else that will be beneficial if you wish to do any custom development for MachPro:
https://support.machmotion.com/docs/current/dir_f2541a3b18981391fa76fac5599e978a.htmlThis is some of our code documentation.
I would highly recommend using the wrapper modules functions instead of the core mach API's as we have built in error handling for most of these functions. You should be able to invoke the wrapper module from anywhere with "w."