generated from Labyricorn/labyricorn-project-template
47 lines
1.5 KiB
JavaScript
47 lines
1.5 KiB
JavaScript
/**
|
|
* XZBT Control Bus
|
|
*
|
|
* XZBTControlBus is a small registry of named, settable console targets
|
|
* (ranges, toggles and triggers). Anything that wants to drive the console
|
|
* from outside the DOM — contract adapter, hotkeys, future transports —
|
|
* talks to the bus rather than reaching into app.js internals.
|
|
*
|
|
* MIDI NOTE: Web MIDI control belonged to standalone SciFi-XZBT until
|
|
* Step 3.5. External MIDI integration will be handled by XZBT-NGN, which
|
|
* will send canonical contract commands (set / invoke) to this exhibit.
|
|
* The control bus itself is transport-agnostic and is intentionally kept here.
|
|
*/
|
|
|
|
class XZBTControlBus {
|
|
constructor() {
|
|
this.targets = new Map();
|
|
this.listeners = new Set();
|
|
}
|
|
register(id, spec) {
|
|
this.targets.set(id, { id, ...spec });
|
|
}
|
|
set(id, value, source = 'external') {
|
|
const t = this.targets.get(id);
|
|
if (!t) return false;
|
|
let v = value;
|
|
if (t.type === 'range') {
|
|
v = Math.max(t.min, Math.min(t.max, Number(value)));
|
|
if (t.step) v = Math.round(v / t.step) * t.step;
|
|
}
|
|
if (t.apply) t.apply(v, source);
|
|
this.listeners.forEach(fn => fn({ id, value: v, source, target: t }));
|
|
return true;
|
|
}
|
|
trigger(id, source = 'external') {
|
|
const t = this.targets.get(id);
|
|
if (!t) return false;
|
|
if (t.apply) t.apply(true, source);
|
|
this.listeners.forEach(fn => fn({ id, value: true, source, target: t }));
|
|
return true;
|
|
}
|
|
list() {
|
|
return [...this.targets.values()];
|
|
}
|
|
}
|
|
window.XZBTControlBus = XZBTControlBus;
|