From 9718e10c7f4151cea895f515c785c14e0021d967 Mon Sep 17 00:00:00 2001 From: cbdev Date: Wed, 18 Mar 2020 22:36:35 +0100 Subject: Implement default channel handlers for Lua/Python --- backends/python.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'backends/python.md') diff --git a/backends/python.md b/backends/python.md index f06e504..6852a79 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. @@ -67,9 +68,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). -- cgit v1.2.3 From 253125ea28925e5207c375987ac36468327bed66 Mon Sep 17 00:00:00 2001 From: cbdev Date: Fri, 27 Mar 2020 21:40:45 +0100 Subject: Implement python cleanup handlers --- backends/python.md | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'backends/python.md') diff --git a/backends/python.md b/backends/python.md index 6852a79..ab0fb38 100644 --- a/backends/python.md +++ b/backends/python.md @@ -17,13 +17,14 @@ 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. | Example Python module: ```python @@ -48,12 +49,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. @@ -92,6 +97,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` -- cgit v1.2.3 From f692715444c6ddeb47bf87b53acf46798785290a Mon Sep 17 00:00:00 2001 From: cbdev Date: Mon, 27 Apr 2020 20:54:02 +0200 Subject: Allow access to previous value in python handlers --- backends/python.md | 3 +++ 1 file changed, 3 insertions(+) (limited to 'backends/python.md') diff --git a/backends/python.md b/backends/python.md index ab0fb38..a78d972 100644 --- a/backends/python.md +++ b/backends/python.md @@ -26,6 +26,9 @@ The `midimonster` module provides the following functions: | `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 import socket -- cgit v1.2.3