LiveCoding#
Static façade over the engine’s embedded-CPython script API
(yse_python.h). Submit scripts with LiveCoding.run() and
observe uncaught Python errors through the LiveCoding.errors
broadcast Stream.
What live coding is#
A live-coding script is a chunk of Python source you hand to the
engine at runtime. Inside the interpreter the script drives the audio
engine through the yse Python DSL — a small module of scheduling
verbs that the embedded interpreter exposes:
yse.send— push an event into the engine immediately.yse.on— register a callback to fire on a named engine event.yse.schedule— queue an action to run at a future beat / time.yse.tick— advance the script’s logical clock by one step.yse.cancel_all— clear every pending scheduled action.yse.fresh_scope— reset the script namespace, discarding state accumulated by earlier submissions.
A script is submitted with LiveCoding.run(), which returns
immediately — the engine takes its own copy of the source and evaluates
it on its script thread. See example/demo18_live_coding.dart for an
end-to-end submit-and-pump loop.
The full Python-side DSL is owned by the upstream engine; this wrapper only marshals the source string in and the error text out. For the complete verb reference see the upstream live-coding epic, yvanvds/yse-soundengine#119.
Build-dependent behaviour#
The CPython interpreter is a compile-time option. Full functionality
requires a library built with YSE_ENABLE_PYTHON=ON;
LiveCoding.enabled reports which build you are running
against and is safe to query regardless of engine state.
On an OFF build the API stays callable — LiveCoding.run()
does not throw. Instead the engine synchronously emits the sentinel
string "YSE compiled without YSE_ENABLE_PYTHON" through
LiveCoding.errors from inside the run call itself.
Subscribe to errors before calling run if you want to observe
that sentinel.
Error-delivery model#
Uncaught Python exceptions and syntax errors do not surface from
LiveCoding.run() (which has already returned). Instead the
engine formats the traceback and delivers it on the thread that drives
System.update() — the same isolate that called
System.init(). Pump the update loop to receive queued
tracebacks, which arrive as strings on the
LiveCoding.errors broadcast stream. The OFF-build sentinel
above is the one exception: it fires synchronously during run
rather than on a later update.
LiveCoding#
class LiveCoding
Live-coding façade over the engine’s embedded-CPython script API.
The C surface (yse_python.h) is a set of stateless globals — there is no native handle — so this is a thin static façade rather than a fetched singleton. Scripts are submitted with [run] and uncaught Python errors surface through the [errors] stream.
The interpreter is only present on a YSE_ENABLE_PYTHON=ON build; query [enabled] to tell. On an OFF build [run] is still safe to call — the engine reports the missing feature through [errors] with a sentinel “compiled without” message.
Static accessors#
static bool get enabled
Compile-time feature query. True only when the library was built with YSE_ENABLE_PYTHON=ON. Safe to call regardless of engine state.
static Stream<String> get errors
Broadcast stream of formatted tracebacks from uncaught Python exceptions and syntax errors. The first subscription installs the engine error callback; the bridge is torn down when the last subscriber cancels (or the engine closes).
Unlike [Log.messages], the traceback string is owned by the engine and valid only for the duration of the call — there is no free function. A NativeCallable.listener would copy the pointer and read it later, by which point it dangles. So this uses NativeCallable.isolateLocal: the closure runs synchronously inside the C call and copies the string with toDartString() before returning. Safe because the engine fires this callback on the thread that drives yse_system_update() — the main isolate.
Static methods#
static void run(String src)
Submit a UTF-8 [src] script for evaluation on the engine’s script thread. Returns immediately; the engine takes its own copy, so the marshalled buffer is freed on return. Uncaught errors arrive later through [errors] (during [System].`update()`).
static Stream<BusFrame> bus(String prefix)
Prefix tap on the global named bus.
The bus is no longer live-coding specific: use [Bus.tap] (or [Bus.subscribe] for one exact address, [Bus.publish] to send).
Host bus access#
Publishing to, subscribing to and tapping the engine’s global named bus — the
plane a script’s yse.send / yse.on talk over — lives on its own page:
see Bus. LiveCoding.bus remains as a deprecated forwarder to
Bus.tap().