aboutsummaryrefslogtreecommitdiffhomepage
path: root/backends/lua.md
diff options
context:
space:
mode:
Diffstat (limited to 'backends/lua.md')
-rw-r--r--backends/lua.md66
1 files changed, 49 insertions, 17 deletions
diff --git a/backends/lua.md b/backends/lua.md
index f38e189..05509b6 100644
--- a/backends/lua.md
+++ b/backends/lua.md
@@ -1,51 +1,71 @@
### The `lua` backend
-The `lua` backend provides a flexible programming environment, allowing users to route and manipulate
-events using the Lua programming language.
+The `lua` backend provides a flexible programming environment, allowing users to route, generate
+and manipulate events using the Lua scripting language.
-Every instance has it's own interpreter state which can be loaded with custom handler scripts.
+Every instance has its own interpreter state which can be loaded with custom handler scripts.
To process incoming channel events, the MIDIMonster calls corresponding Lua functions (if they exist)
-with the value (as a Lua `number` type) as parameter.
+with the value (as a Lua `number` type) as parameter. Alternatively, a designated default channel handler
+may be supplied in the configuration.
The following functions are provided within the Lua interpreter for interaction with the MIDIMonster
| Function | Usage example | Description |
|-------------------------------|-------------------------------|---------------------------------------|
| `output(string, number)` | `output("foo", 0.75)` | Output a value event to a channel |
-| `interval(function, number)` | `interval(update, 100)` | Register a function to be called periodically. Intervals are milliseconds (rounded to the nearest 10 ms) |
+| `interval(function, number)` | `interval(update, 100)` | Register a function to be called periodically. Intervals are milliseconds (rounded to the nearest 10 ms). Calling `interval` on a Lua function multiple times updates the interval. Specifying `0` as interval stops periodic calls to the function |
| `input_value(string)` | `input_value("foo")` | Get the last input value on a channel |
| `output_value(string)` | `output_value("bar")` | Get the last output value on a channel |
-
+| `input_channel()` | `print(input_channel())` | Returns the name of the input channel whose handler function is currently running or `nil` if in an `interval`'ed function (or the initial parse step) |
+| `timestamp()` | `print(timestamp())` | Returns the core timestamp for this iteration with millisecond resolution. This is not a performance timer, but intended for timeouting, etc |
+| `thread(function)` | `thread(run_show)` | Run a function as a Lua thread (see below) |
+| `sleep(number)` | `sleep(100)` | Suspend current thread for time specified in milliseconds |
Example script:
-```
+```lua
function bar(value)
- output("foo", value / 2)
+ output("foo", value / 2);
end
step = 0
function toggle()
- output("bar", step * 1.0)
+ output("bar", step * 1.0);
step = (step + 1) % 2;
end
+function run_show()
+ while(true) do
+ sleep(1000);
+ output("narf", 0);
+ sleep(1000);
+ output("narf", 1.0);
+ end
+end
+
interval(toggle, 1000)
+thread(run_show)
```
Input values range between 0.0 and 1.0, output values are clamped to the same range.
+Threads are implemented as Lua coroutines, not operating system threads. This means that
+cooperative multithreading is required, which can be achieved by calling the `sleep(number)`
+function from within a running thread. Calling that function from any other context is
+not supported.
+
#### Global configuration
The `lua` backend does not take any global configuration.
#### Instance configuration
-| Option | Example value | Default value | Description |
-|---------------|-----------------------|-----------------------|-----------------------|
-| `script` | `script.lua` | none | Lua source file (relative to configuration file)|
+| Option | Example value | Default value | Description |
+|-----------------------|-----------------------|-----------------------|-----------------------|
+| `script` | `script.lua` | none | Lua source file (relative to configuration file) |
+| `default-handler` | `handler` | none | Name of a function to be called as handler for all incoming channels (instead of the per-channel handlers) |
-A single instance may have multiple `source` options specified, which will all be read cumulatively.
+A single instance may have multiple `script` options specified, which will all be read cumulatively.
#### Channel specification
@@ -58,9 +78,21 @@ lua1.foo > lua2.bar
#### Known bugs / problems
-Using any of the interface functions (`output`, `interval`, `input_value`, `output_value`) as an
-input channel name to a Lua instance will not call any handler functions.
-Using these names as arguments to the output and value interface functions works as intended.
+Using any of the interface functions (`output`, `interval`, etc.) as an input channel name to a
+Lua instance will not call any handler functions. Using these names as arguments to the output and
+value interface functions works as intended. When using a default handler, the default handler will
+be called.
Output values will not trigger corresponding input event handlers unless the channel is mapped
-back in the MIDIMonster configuration.
+back in the MIDIMonster configuration. This is intentional.
+
+To build (and run) the `lua` backend on Windows, a compiled version of the Lua 5.3 library is required.
+For various reasons (legal, separations of concern, not wanting to ship binary data in the repository),
+the MIDIMonster project can not provide this file within this repository.
+You will need to acquire a copy of `lua53.dll`, for example by downloading it from the [luabinaries
+project](http://luabinaries.sourceforge.net/download.html).
+
+To build the `lua` backend for Windows, place `lua53.dll` in a subdirectory `libs/` in the project root
+and run `make lua.dll` inside the `backends/` directory.
+
+At runtime, Windows searches for the file in the same directory as `midimonster.exe`.