aboutsummaryrefslogtreecommitdiffhomepage
path: root/backends/python.md
diff options
context:
space:
mode:
authorcbdev <cb@cbcdn.com>2020-04-27 22:50:47 +0200
committercbdev <cb@cbcdn.com>2020-04-27 22:50:47 +0200
commit1d8ed32bf769bc99095cd32ec166e681437607f0 (patch)
treebc94fd3a0245e91c15659916fc1c3591c7fb44b7 /backends/python.md
parentd4714dfdd5c6e2d165d1ad9327fdce69a1b2b85b (diff)
parentc0bb55ff08faf2f89af947090d1c9bc412927d9f (diff)
downloadmidimonster-1d8ed32bf769bc99095cd32ec166e681437607f0.tar.gz
midimonster-1d8ed32bf769bc99095cd32ec166e681437607f0.tar.bz2
midimonster-1d8ed32bf769bc99095cd32ec166e681437607f0.zip
Merge branch 'master' into debian/master
Diffstat (limited to 'backends/python.md')
-rw-r--r--backends/python.md27
1 files changed, 20 insertions, 7 deletions
diff --git a/backends/python.md b/backends/python.md
index f06e504..a78d972 100644
--- a/backends/python.md
+++ b/backends/python.md
@@ -6,6 +6,7 @@ to route, generate and manipulate channel events using the Python 3 scripting la
Every instance has its own interpreter, which can be loaded with multiple Python modules.
These modules may contain member functions accepting a single `float` parameter, which can
then be used as target channels. For each incoming event, the handler function is called.
+Channels in the global scope may be assigned a default handler function.
Python modules may also register `socket` objects (and an associated callback function) with
the MIDIMonster core, which will then alert the module when there is data ready to be read.
@@ -16,13 +17,17 @@ The `midimonster` module provides the following functions:
| Function | Usage example | Description |
|-------------------------------|---------------------------------------|-----------------------------------------------|
-| `output(string, float)` | `midimonster.output("foo", 0.75)` | Output a value event to a channel |
-| `inputvalue(string)` | `midimonster.inputvalue("foo")` | Get the last input value on a channel |
-| `outputvalue(string)` | `midimonster.outputvalue("bar")` | Get the last output value on a channel |
+| `output(string, float)` | `midimonster.output("foo", 0.75)` | Output a value event to a channel on this instance |
+| `inputvalue(string)` | `midimonster.inputvalue("foo")` | Get the last input value on a channel of this instance |
+| `outputvalue(string)` | `midimonster.outputvalue("bar")` | Get the last output value on a channel of this instance |
| `current()` | `print(midimonster.current())` | Returns the name of the input channel whose handler function is currently running or `None` if the interpreter was called from another context |
| `timestamp()` | `print(midimonster.timestamp())` | Get the internal core timestamp (in milliseconds) |
| `interval(function, long)` | `midimonster.interval(toggle, 100)` | Register a function to be called periodically. Interval is specified in milliseconds (accurate to 10msec). Calling `interval` with the same function again updates the interval. Specifying the interval as `0` cancels the interval |
-| `manage(function, socket)` | `midimonster.manage(handler, socket)`| Register a (connected/listening) socket to the MIDIMonster core. Calls `function(socket)` when the socket is ready to read. Calling this method with `None` as the function argument unregisters the socket. A socket may only have one associated handler |
+| `manage(function, socket)` | `midimonster.manage(handler, socket)` | Register a (connected/listening) socket to the MIDIMonster core. Calls `function(socket)` when the socket is ready to read. Calling this method with `None` as the function argument unregisters the socket. A socket may only have one associated handler |
+| `cleanup_handler(function)` | `midimonster.cleanup_handler(save_all)`| Register a function to be called when the instance is destroyed (on MIDIMonster shutdown). One cleanup handler can be registered per instance. Calling this function when the instance already has a cleanup handler registered replaces the handler, returning the old one. |
+
+When a channel handler executes, calling `midimonster.inputvalue()` for that exact channel returns the previous value,
+while the argument to the handler is the current value. The stored value is updated after the handler finishes executing.
Example Python module:
```python
@@ -47,12 +52,16 @@ def socket_handler(sock):
def ping():
print(midimonster.timestamp())
+def save_positions():
+ # Store some data to disk
+
# Register an interval
midimonster.interval(ping, 1000)
# Create and register a client socket (add error handling as you like)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("localhost", 8990))
midimonster.manage(socket_handler, s)
+midimonster.cleanup_handler(save_positions)
```
Input values range between 0.0 and 1.0, output values are clamped to the same range.
@@ -67,9 +76,10 @@ The `python` backend does not take any global configuration.
#### Instance configuration
-| Option | Example value | Default value | Description |
-|---------------|-----------------------|-----------------------|-----------------------------------------------|
-| `module` | `my_handlers.py` | none | (Path to) Python module source file, relative to configuration file location |
+| Option | Example value | Default value | Description |
+|-----------------------|-----------------------|-----------------------|-----------------------------------------------|
+| `module` | `my_handlers.py` | none | (Path to) Python module source file, relative to configuration file location |
+| `default-handler` | `mu_handlers.default` | none | Function to be called as handler for all top-level channels (not belonging to a module) |
A single instance may have multiple `module` options specified. This will make all handlers available within their
module namespaces (see the section on channel specification).
@@ -90,6 +100,9 @@ py1.out1 > py2.module.handler
Output values will not trigger corresponding input event handlers unless the channel is mapped
back in the MIDIMonster configuration. This is intentional.
+Output events generated from cleanup handlers called during shutdown will not be routed, as the core
+routing facility has already shut down at this point. There are no plans to change this behaviour.
+
Importing a Python module named `midimonster` is probably a bad idea and thus unsupported.
The MIDIMonster is, at its core, single-threaded. Do not try to use Python's `threading`