-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathconductorRecorderRegistry.js
More file actions
71 lines (63 loc) · 2.08 KB
/
conductorRecorderRegistry.js
File metadata and controls
71 lines (63 loc) · 2.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
// src/conductor/conductorRecorderRegistry.js - Sub-registry for beat recorders.
// Recorders receive a context object each beat and perform side-effects
// (recording snapshots, updating internal state).
moduleLifecycle.declare({
name: 'conductorRecorderRegistry',
subsystem: 'conductor',
deps: ['validator'],
provides: ['conductorRecorderRegistry'],
init: (deps) => {
const V = deps.validator.create('conductorRecorderRegistry');
/**
* @typedef {{
* absTime: number,
* compositeIntensity: number,
* currentDensity: number,
* harmonicRhythm: number,
* layer: string
* }} RecorderContext
*/
/** @type {Array<{ name: string, fn: (ctx: RecorderContext) => void }>} */
const recorders = [];
/** @param {string} name */
function conductorRecorderRegistryAssertNoDup(name) {
if (recorders.some(e => e.name === name)) {
throw new Error(`conductorRecorderRegistry.registerRecorder: duplicate name "${name}"`);
}
}
/**
* Register a recorder that runs each beat.
* @param {string} name
* @param {(ctx: RecorderContext) => void} fn
*/
function registerRecorder(name, fn) {
V.assertNonEmptyString(name, 'name');
conductorRecorderRegistryAssertNoDup(name);
V.requireType(fn, 'function', 'fn');
recorders.push({ name, fn });
}
/**
* Run all recorders with the given context.
* @param {RecorderContext} ctx
*/
function runRecorders(ctx) {
// L2 pass only runs conductorSignalBridge (needs per-layer refresh).
// All other recorders skip L2 to prevent double-counting from
// polyrhythmic layer asymmetry.
const l2Only = ctx && ctx.layer === 'L2';
for (let i = 0; i < recorders.length; i++) {
if (l2Only && recorders[i].name !== 'conductorSignalBridge') continue;
recorders[i].fn(ctx);
}
}
/** @returns {string[]} raw entry names (not colon-normalized) */
function getNames() {
return recorders.map(e => e.name);
}
/** @returns {number} */
function getCount() {
return recorders.length;
}
return { registerRecorder, runRecorders, getNames, getCount };
},
});