@msb235/blits 0.14.0 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +154 -0
- package/README.md +3 -3
- package/dist/ahead.d.ts +26 -0
- package/dist/ahead.js +264 -0
- package/dist/around.d.ts +11 -0
- package/dist/around.js +32 -0
- package/dist/bare.js +15 -7
- package/dist/blank.d.ts +10 -0
- package/dist/blank.js +26 -0
- package/dist/blend.d.ts +2 -1
- package/dist/blend.js +1 -6
- package/dist/bound.d.ts +70 -0
- package/dist/bound.js +351 -0
- package/dist/chain.d.ts +2 -1
- package/dist/chain.js +7 -5
- package/dist/changes.d.ts +24 -0
- package/dist/changes.js +189 -0
- package/dist/channels.d.ts +39 -13
- package/dist/channels.js +14 -5
- package/dist/color.d.ts +12 -10
- package/dist/color.js +25 -25
- package/dist/columns.js +7 -3
- package/dist/contribution.d.ts +30 -0
- package/dist/contribution.js +374 -0
- package/dist/copyout.d.ts +10 -0
- package/dist/copyout.js +69 -24
- package/dist/crowd.d.ts +8 -2
- package/dist/crowd.js +4 -5
- package/dist/cue.d.ts +8 -1
- package/dist/cue.js +39 -13
- package/dist/cut.d.ts +8 -0
- package/dist/cut.js +4 -0
- package/dist/drop.d.ts +9 -0
- package/dist/drop.js +84 -0
- package/dist/due.d.ts +24 -5
- package/dist/due.js +113 -33
- package/dist/easing.d.ts +4 -4
- package/dist/easing.js +3 -3
- package/dist/everyone.d.ts +3 -2
- package/dist/everyone.js +3 -3
- package/dist/fade.d.ts +2 -1
- package/dist/fade.js +2 -1
- package/dist/fill.d.ts +3 -2
- package/dist/fill.js +51 -19
- package/dist/fit.d.ts +44 -26
- package/dist/fit.js +10 -9
- package/dist/fold.d.ts +4 -37
- package/dist/fold.js +5 -513
- package/dist/gather.d.ts +12 -7
- package/dist/gather.js +179 -44
- package/dist/gone.js +2 -2
- package/dist/grid.d.ts +47 -0
- package/dist/grid.js +247 -0
- package/dist/handle.d.ts +2 -0
- package/dist/handle.js +14 -8
- package/dist/held.d.ts +2 -1
- package/dist/history.d.ts +6 -5
- package/dist/history.js +7 -9
- package/dist/hosts.js +9 -15
- package/dist/index.d.ts +5 -4
- package/dist/keyfill.d.ts +1 -1
- package/dist/keyfill.js +5 -3
- package/dist/keyrows.d.ts +12 -0
- package/dist/keyrows.js +99 -12
- package/dist/lane.d.ts +36 -6
- package/dist/lane.js +32 -1
- package/dist/lanes.d.ts +23 -8
- package/dist/lanes.js +29 -8
- package/dist/leavings.d.ts +2 -2
- package/dist/leavings.js +1 -1
- package/dist/lives.d.ts +47 -0
- package/dist/lives.js +180 -0
- package/dist/meet.d.ts +2 -2
- package/dist/meet.js +90 -4
- package/dist/mixer.d.ts +54 -36
- package/dist/mixer.js +53 -171
- package/dist/motion.d.ts +14 -118
- package/dist/motion.js +16 -8
- package/dist/motions.d.ts +62 -155
- package/dist/motions.js +56 -370
- package/dist/moved.d.ts +1 -1
- package/dist/moved.js +16 -7
- package/dist/named.d.ts +0 -1
- package/dist/named.js +20 -2
- package/dist/numbers.d.ts +2 -0
- package/dist/numbers.js +4 -0
- package/dist/owed.d.ts +2 -0
- package/dist/owed.js +4 -0
- package/dist/pack.d.ts +2 -1
- package/dist/pack.js +2 -3
- package/dist/patch.d.ts +7 -3
- package/dist/patch.js +6 -2
- package/dist/places.d.ts +53 -0
- package/dist/places.js +171 -0
- package/dist/plot.d.ts +12 -0
- package/dist/plot.js +52 -0
- package/dist/project.d.ts +4 -4
- package/dist/project.js +9 -212
- package/dist/pull.js +11 -8
- package/dist/qualify.js +84 -21
- package/dist/reading.d.ts +6 -0
- package/dist/reading.js +5 -0
- package/dist/record.d.ts +5 -1
- package/dist/record.js +3 -2
- package/dist/relink.d.ts +1 -1
- package/dist/restored.d.ts +2 -2
- package/dist/restored.js +1 -1
- package/dist/rests.d.ts +9 -0
- package/dist/rests.js +76 -0
- package/dist/revive.d.ts +3 -2
- package/dist/revive.js +2 -2
- package/dist/{locus.d.ts → role.d.ts} +10 -9
- package/dist/{locus.js → role.js} +3 -3
- package/dist/roles.d.ts +10 -0
- package/dist/roles.js +158 -0
- package/dist/roster.js +3 -3
- package/dist/rotation.d.ts +1 -1
- package/dist/rotation.js +1 -1
- package/dist/rows.js +1 -1
- package/dist/sample.d.ts +2 -2
- package/dist/sample.js +33 -7
- package/dist/seek.js +5 -5
- package/dist/setting.d.ts +27 -0
- package/dist/setting.js +55 -0
- package/dist/shared.d.ts +1 -1
- package/dist/shared.js +1 -1
- package/dist/signals.d.ts +64 -32
- package/dist/signals.js +20 -18
- package/dist/stack.d.ts +5 -5
- package/dist/stack.js +5 -5
- package/dist/standing.d.ts +2 -1
- package/dist/standing.js +3 -2
- package/dist/store.d.ts +9 -0
- package/dist/store.js +24 -0
- package/dist/strays.d.ts +2 -1
- package/dist/strays.js +20 -13
- package/dist/stretch.d.ts +112 -0
- package/dist/stretch.js +9 -0
- package/dist/subject.d.ts +142 -0
- package/dist/subject.js +1 -0
- package/dist/tape.d.ts +9 -5
- package/dist/tape.js +5 -1
- package/dist/then.d.ts +9 -0
- package/dist/then.js +57 -0
- package/dist/ticker.d.ts +4 -4
- package/dist/transport.d.ts +0 -8
- package/dist/transport.js +0 -4
- package/dist/turns.d.ts +4 -3
- package/dist/turns.js +4 -3
- package/dist/types/arc.d.ts +12 -11
- package/dist/types/channel.d.ts +12 -8
- package/dist/types/history.d.ts +35 -19
- package/dist/types/mix.d.ts +222 -163
- package/dist/types/motion.d.ts +151 -0
- package/dist/types/motion.js +1 -0
- package/dist/types/patch.d.ts +67 -34
- package/dist/types/place.d.ts +51 -36
- package/dist/types/transport.d.ts +20 -18
- package/dist/types/voice.d.ts +136 -70
- package/dist/types/watch.d.ts +88 -40
- package/dist/types.d.ts +1 -0
- package/dist/voice.d.ts +7 -143
- package/dist/voice.js +28 -79
- package/dist/warn.d.ts +2 -0
- package/dist/warn.js +1 -1
- package/dist/watch.d.ts +2 -2
- package/dist/watch.js +5 -3
- package/dist/wave.d.ts +4 -3
- package/dist/wave.js +3 -2
- package/dist/weigh.d.ts +7 -1
- package/dist/weigh.js +27 -0
- package/docs/schema.html +212 -34
- package/package.json +2 -2
package/dist/mixer.d.ts
CHANGED
|
@@ -1,31 +1,40 @@
|
|
|
1
1
|
import { type Arc } from './arcs.js';
|
|
2
|
+
import { around } from './around.js';
|
|
2
3
|
import { blended, laneRead, shareKept } from './blend.js';
|
|
3
4
|
import type { Book } from './book.js';
|
|
4
5
|
import { aims, chain, linkable, relink } from './chain.js';
|
|
5
6
|
import { type LerpInto } from './channels.js';
|
|
6
7
|
import type { Column } from './columns.js';
|
|
8
|
+
import { baseFor, contribution, isRest, keyed, read, slopeFor, tick } from './contribution.js';
|
|
7
9
|
import { DepartedIndex } from './departed.js';
|
|
8
|
-
import
|
|
10
|
+
import { drop, forgetIn, recordDrop, releaseIn } from './drop.js';
|
|
11
|
+
import { DueQueue } from './due.js';
|
|
9
12
|
import { parting } from './fade.js';
|
|
10
|
-
import { apply,
|
|
13
|
+
import { apply, clamp, fold, foldDetour, folded, foldSharers, foldWith, type Key, linked, owedBy, passes, shared } from './fold.js';
|
|
11
14
|
import { GoneIndex } from './gone.js';
|
|
12
15
|
import type { HandleHost } from './handle.js';
|
|
13
16
|
import { held, shownOf, sinceOf, unreachedOf } from './held.js';
|
|
14
17
|
import { Lanes } from './lanes.js';
|
|
15
|
-
import {
|
|
16
|
-
import type { MotionOwner, Motions } from './motions.js';
|
|
18
|
+
import type { Motions } from './motions.js';
|
|
17
19
|
import type { Pace } from './pace.js';
|
|
18
20
|
import { Keys } from './paging.js';
|
|
21
|
+
import type { Places } from './places.js';
|
|
22
|
+
import { moved, place, plot, put } from './plot.js';
|
|
19
23
|
import { keep } from './pull.js';
|
|
20
24
|
import { Steps } from './relink.js';
|
|
25
|
+
import { atRest, restful, rests, restsKey, restsLaned, still } from './rests.js';
|
|
21
26
|
import { Outs } from './revive.js';
|
|
27
|
+
import { foldRole, type RoleScratch } from './role.js';
|
|
28
|
+
import { foldRoles } from './roles.js';
|
|
22
29
|
import { ScoreIndex } from './scored.js';
|
|
23
30
|
import { Fitting } from './spans.js';
|
|
24
31
|
import { Store } from './store.js';
|
|
32
|
+
import type { MotionOwner } from './stretch.js';
|
|
33
|
+
import type { Subject } from './subject.js';
|
|
25
34
|
import { type Announced, Transport } from './transport.js';
|
|
26
35
|
import type { ArcHandle, ArcSpec, BlendMember, Booker, BookOptions, Channel, Columns, Engine, Handle, Kit, Marked, Mix, MixOptions, OwnerSpec, Patch, Projection, Sent, Signal, SpanHandle, SpanSpec, Tape, VoiceSpec } from './types.js';
|
|
27
|
-
import { type
|
|
28
|
-
import { base, capped, fadeOf, horizonFor, ownedBy, ownerBase, prime, weigh, weighOwned } from './weigh.js';
|
|
36
|
+
import { type Voice } from './voice.js';
|
|
37
|
+
import { base, capped, fadeOf, horizonFor, ownedBy, ownerBase, prime, primeLaned, weigh, weighOwned } from './weigh.js';
|
|
29
38
|
/**
|
|
30
39
|
* What a mix takes where its options say nothing. Not exported from the package: the suite turns
|
|
31
40
|
* `lanes` off to run every test on the general path, which is what makes each one an equivalence check.
|
|
@@ -67,7 +76,7 @@ export declare class Mixer<I, O> implements Mix<I, O> {
|
|
|
67
76
|
fields: Record<string, unknown>;
|
|
68
77
|
} | undefined;
|
|
69
78
|
/** Each subject's last two poses and when they were probed, for `from: 'current'`. */
|
|
70
|
-
|
|
79
|
+
lastPoses: Store<I, {
|
|
71
80
|
pose: O;
|
|
72
81
|
at: number;
|
|
73
82
|
prev: O | undefined;
|
|
@@ -91,7 +100,7 @@ export declare class Mixer<I, O> implements Mix<I, O> {
|
|
|
91
100
|
/** The pose `pull` folds a subject into where it cannot read straight from the lanes. */
|
|
92
101
|
scratch: O | undefined;
|
|
93
102
|
/** Live voices by the earliest mix time `moveTo` would change each, a binary heap. */
|
|
94
|
-
due:
|
|
103
|
+
due: DueQueue<I, O>;
|
|
95
104
|
/** Voices retired since `moveTo` last pruned them, in the order they retired. */
|
|
96
105
|
retired: Voice<I, O>[];
|
|
97
106
|
/** Visit every voice each sync, as before the due queue; for tests that compare the two. */
|
|
@@ -135,6 +144,8 @@ export declare class Mixer<I, O> implements Mix<I, O> {
|
|
|
135
144
|
*/
|
|
136
145
|
chains: Store<I, Subject<unknown>>;
|
|
137
146
|
version: number;
|
|
147
|
+
/** The positions `plot` gave, which a voice's `within` reads: see `bound.ts`. */
|
|
148
|
+
places: Places<I> | null;
|
|
138
149
|
/** What `prime` reads its clock, voice time and pass from: see `Primed`. */
|
|
139
150
|
readonly primed: Float64Array<ArrayBuffer>;
|
|
140
151
|
readonly steps: Steps<Voice<I, O>, I>;
|
|
@@ -166,8 +177,10 @@ export declare class Mixer<I, O> implements Mix<I, O> {
|
|
|
166
177
|
unshared: boolean;
|
|
167
178
|
/** 0 where a fold is a walk of the chain: see `detour` in `everyone.ts`. */
|
|
168
179
|
detours: number;
|
|
169
|
-
/** How many voices in the list carry a
|
|
170
|
-
|
|
180
|
+
/** How many voices in the list carry a role; with none, a fold allocates nothing. */
|
|
181
|
+
roleVoices: number;
|
|
182
|
+
/** The tags the mix's options declare roles. */
|
|
183
|
+
readonly roleTags: readonly string[] | undefined;
|
|
171
184
|
/** What every motion patch it plays asks for its voice's time, holding this mix weakly. */
|
|
172
185
|
owner: MotionOwner | null;
|
|
173
186
|
/** How many voices in the list are anchored, so a sync with none skips placing them. */
|
|
@@ -191,9 +204,9 @@ export declare class Mixer<I, O> implements Mix<I, O> {
|
|
|
191
204
|
readonly lerpsInto: (LerpInto | undefined)[];
|
|
192
205
|
/** By slot, a stock scalar channel's arithmetic, which a fold applies without calling the channel. */
|
|
193
206
|
readonly scalars: ('sum' | 'mul' | 'max' | undefined)[];
|
|
194
|
-
/** What a fold with a
|
|
195
|
-
readonly
|
|
196
|
-
|
|
207
|
+
/** What a fold with a role in play gathers into, one per depth of folds under way. */
|
|
208
|
+
readonly roleScratch: RoleScratch<I, O>[];
|
|
209
|
+
roleDepth: number;
|
|
197
210
|
readonly slotOf: Map<string, number>;
|
|
198
211
|
lanes: Lanes<I, O> | null;
|
|
199
212
|
handles: HandleHost<I, O> | null;
|
|
@@ -209,6 +222,7 @@ export declare class Mixer<I, O> implements Mix<I, O> {
|
|
|
209
222
|
keys: Keys | null;
|
|
210
223
|
/** With a history store, the voices it paged out whose handles are still held; null without one. */
|
|
211
224
|
outs: Outs | null;
|
|
225
|
+
readonly pose: () => O;
|
|
212
226
|
constructor(kit: Kit<O>, opts: MixOptions,
|
|
213
227
|
/** The lanes an entry was built with; null in one that leaves them out. */
|
|
214
228
|
lanesOf: typeof Lanes | null);
|
|
@@ -237,7 +251,7 @@ export declare class Mixer<I, O> implements Mix<I, O> {
|
|
|
237
251
|
off: number;
|
|
238
252
|
};
|
|
239
253
|
cue(spec: VoiceSpec<I, O>): Handle<I>;
|
|
240
|
-
blend(members: readonly (Patch<I, O, unknown> | BlendMember<I, O>)[], by: Signal<I>, spec?: Omit<VoiceSpec<I, O>, 'patch' | 'weight' | 'locus'>): Handle<I>[];
|
|
254
|
+
blend(members: readonly (Patch<I, O, unknown> | BlendMember<I, O>)[], by: Signal<I>, spec?: Omit<VoiceSpec<I, O>, 'patch' | 'weight' | 'role' | 'locus' | 'within'>): Handle<I>[];
|
|
241
255
|
owns(spec: OwnerSpec<I>): Handle<I>;
|
|
242
256
|
span(spec: SpanSpec<I>): SpanHandle<I>;
|
|
243
257
|
arc(spec: ArcSpec<I, O>): ArcHandle<I>;
|
|
@@ -260,27 +274,17 @@ export declare class Mixer<I, O> implements Mix<I, O> {
|
|
|
260
274
|
/** Throws for a mix taken off its transport. */
|
|
261
275
|
attached(): void;
|
|
262
276
|
marks(from: number, to: number): Marked[];
|
|
263
|
-
atRest(subject: I): boolean;
|
|
264
|
-
rests(pose: O): boolean;
|
|
265
277
|
rebase(): void;
|
|
266
278
|
voices(tag?: string): Handle<I>[];
|
|
267
279
|
get live(): boolean;
|
|
268
280
|
get inert(): boolean;
|
|
269
|
-
private restful;
|
|
270
281
|
get rate(): number;
|
|
271
282
|
set rate(r: number);
|
|
272
283
|
ramp(rate: number, over: number): void;
|
|
273
|
-
/** Whether a voice will change no pose from `now` on, short of a change made to it. */
|
|
274
|
-
still(voice: Voice<I, O>, now: number): boolean;
|
|
275
284
|
close(): void;
|
|
276
285
|
mute(opts?: {
|
|
277
286
|
over?: number;
|
|
278
287
|
}): void;
|
|
279
|
-
drop(subject: I): void;
|
|
280
|
-
/** Lets `voice` go of a dropped subject. Methods rather than closures, so a drop makes neither. */
|
|
281
|
-
private forgetIn;
|
|
282
|
-
private releaseIn;
|
|
283
|
-
private recordDrop;
|
|
284
288
|
touch(subject?: I): void;
|
|
285
289
|
drain<E = unknown>(tag?: string): Sent<I, E>[];
|
|
286
290
|
/** Voices whose stop 0 is mid-computation, so a fold for one cannot re-enter itself. */
|
|
@@ -292,15 +296,13 @@ export declare class Mixer<I, O> implements Mix<I, O> {
|
|
|
292
296
|
*/
|
|
293
297
|
restStamps: Store<I, number> | null;
|
|
294
298
|
/** What a probe's record of rest is good for: moved by a new frame, version, relink, or stir. */
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
299
|
+
restsEpoch: number;
|
|
300
|
+
restsFrame: number;
|
|
301
|
+
restsVersion: number;
|
|
302
|
+
restsRelinks: number;
|
|
303
|
+
restsStirs: number;
|
|
300
304
|
/** The pose `atRest` folds into where no probe this frame answers. */
|
|
301
|
-
|
|
302
|
-
private restsLaned;
|
|
303
|
-
private restsKey;
|
|
305
|
+
restScratch: O | undefined;
|
|
304
306
|
}
|
|
305
307
|
declare const methods: {
|
|
306
308
|
fold: typeof fold;
|
|
@@ -308,7 +310,7 @@ declare const methods: {
|
|
|
308
310
|
linked: typeof linked;
|
|
309
311
|
foldWith: typeof foldWith;
|
|
310
312
|
owedBy: typeof owedBy;
|
|
311
|
-
|
|
313
|
+
foldRoles: typeof foldRoles;
|
|
312
314
|
foldDetour: typeof foldDetour;
|
|
313
315
|
foldSharers: typeof foldSharers;
|
|
314
316
|
shared: typeof shared;
|
|
@@ -323,6 +325,7 @@ declare const methods: {
|
|
|
323
325
|
baseFor: typeof baseFor;
|
|
324
326
|
slopeFor: typeof slopeFor;
|
|
325
327
|
prime: typeof prime;
|
|
328
|
+
primeLaned: typeof primeLaned;
|
|
326
329
|
capped: typeof capped;
|
|
327
330
|
horizonFor: typeof horizonFor;
|
|
328
331
|
weigh: typeof weigh;
|
|
@@ -344,7 +347,22 @@ declare const methods: {
|
|
|
344
347
|
sinceOf: typeof sinceOf;
|
|
345
348
|
shownOf: typeof shownOf;
|
|
346
349
|
keep: typeof keep;
|
|
347
|
-
|
|
350
|
+
foldRole: typeof foldRole;
|
|
351
|
+
atRest: typeof atRest;
|
|
352
|
+
rests: typeof rests;
|
|
353
|
+
restful: typeof restful;
|
|
354
|
+
still: typeof still;
|
|
355
|
+
restsLaned: typeof restsLaned;
|
|
356
|
+
restsKey: typeof restsKey;
|
|
357
|
+
plot: typeof plot;
|
|
358
|
+
place: typeof place;
|
|
359
|
+
moved: typeof moved;
|
|
360
|
+
put: typeof put;
|
|
361
|
+
around: typeof around;
|
|
362
|
+
drop: typeof drop;
|
|
363
|
+
forgetIn: typeof forgetIn;
|
|
364
|
+
releaseIn: typeof releaseIn;
|
|
365
|
+
recordDrop: typeof recordDrop;
|
|
348
366
|
};
|
|
349
367
|
type Methods = typeof methods;
|
|
350
368
|
export interface Mixer<I, O> extends Methods {
|
|
@@ -352,13 +370,13 @@ export interface Mixer<I, O> extends Methods {
|
|
|
352
370
|
/** Makes a mix the host asked for, with the registry's history where it names none, and lists it there. */
|
|
353
371
|
export declare function made<I, O, H>(kit: Kit<O>, opts: MixOptions<H>, lanes: typeof Lanes | null): Mix<I, O, H>;
|
|
354
372
|
/**
|
|
355
|
-
* The
|
|
373
|
+
* The engine that ships, running every form on the CPU. It probes per subject on demand.
|
|
356
374
|
*
|
|
357
375
|
* @category engine
|
|
358
376
|
*/
|
|
359
377
|
export declare const mixer: Engine;
|
|
360
378
|
/**
|
|
361
|
-
* Makes a mix over a kit
|
|
379
|
+
* Makes a mix over a kit. It runs on the engine the options name, or the stock one.
|
|
362
380
|
*
|
|
363
381
|
* @category mix
|
|
364
382
|
*/
|
package/dist/mixer.js
CHANGED
|
@@ -1,35 +1,42 @@
|
|
|
1
1
|
import { cueArc } from './arcs.js';
|
|
2
|
+
import { around } from './around.js';
|
|
3
|
+
import { blanks } from './blank.js';
|
|
2
4
|
import { blended, blendOf, laneRead, shareKept } from './blend.js';
|
|
3
|
-
import { aims, chain,
|
|
5
|
+
import { aims, chain, linkable, relink } from './chain.js';
|
|
4
6
|
import { lerpInto, STOCK_BAND, scalarOp } from './channels.js';
|
|
5
|
-
import {
|
|
7
|
+
import { baseFor, contribution, isRest, keyed, read, slopeFor, tick } from './contribution.js';
|
|
8
|
+
import { cue, roleTags } from './cue.js';
|
|
6
9
|
import { DepartedIndex } from './departed.js';
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
+
import { drop, forgetIn, recordDrop, releaseIn } from './drop.js';
|
|
11
|
+
import { DueQueue } from './due.js';
|
|
12
|
+
import { beginFade, parting } from './fade.js';
|
|
13
|
+
import { apply, clamp, fold, foldDetour, folded, foldSharers, foldWith, linked, owedBy, passes, shared, } from './fold.js';
|
|
14
|
+
import { GoneIndex } from './gone.js';
|
|
10
15
|
import { held, shownOf, sinceOf, unreachedOf } from './held.js';
|
|
11
|
-
import { releasing } from './history.js';
|
|
12
16
|
import { book, laneHost } from './hosts.js';
|
|
13
17
|
import { Lanes } from './lanes.js';
|
|
14
|
-
import { foldLocus } from './locus.js';
|
|
15
18
|
import { listed } from './marks.js';
|
|
16
19
|
import { nextFrame } from './move.js';
|
|
17
20
|
import { ownerPatch } from './owner.js';
|
|
18
21
|
import { Keys } from './paging.js';
|
|
22
|
+
import { moved, place, plot, put } from './plot.js';
|
|
19
23
|
import { projectAll } from './project.js';
|
|
20
24
|
import { keep, pull } from './pull.js';
|
|
21
25
|
import { Steps } from './relink.js';
|
|
26
|
+
import { atRest, restful, rests, restsKey, restsLaned, still } from './rests.js';
|
|
22
27
|
import { Outs } from './revive.js';
|
|
28
|
+
import { foldRole } from './role.js';
|
|
29
|
+
import { foldRoles } from './roles.js';
|
|
23
30
|
import { ScoreIndex } from './scored.js';
|
|
24
31
|
import { seek } from './seek.js';
|
|
25
32
|
import { Fitting, refit } from './spans.js';
|
|
26
|
-
import {
|
|
27
|
-
import { record
|
|
33
|
+
import { Store } from './store.js';
|
|
34
|
+
import { record } from './tape.js';
|
|
28
35
|
import { touch } from './touch.js';
|
|
29
36
|
import { announce, Transport } from './transport.js';
|
|
30
37
|
import { none } from './voice.js';
|
|
31
38
|
import { gave, historyFor, register, unregister } from './watch.js';
|
|
32
|
-
import { base, capped, fadeOf, horizonFor, ownedBy, ownerBase, prime, weigh, weighOwned, } from './weigh.js';
|
|
39
|
+
import { base, capped, fadeOf, horizonFor, ownedBy, ownerBase, prime, primeLaned, weigh, weighOwned, } from './weigh.js';
|
|
33
40
|
/**
|
|
34
41
|
* What a mix takes where its options say nothing. Not exported from the package: the suite turns
|
|
35
42
|
* `lanes` off to run every test on the general path, which is what makes each one an equivalence check.
|
|
@@ -63,7 +70,7 @@ export class Mixer {
|
|
|
63
70
|
hostLog = [];
|
|
64
71
|
hostThen;
|
|
65
72
|
/** Each subject's last two poses and when they were probed, for `from: 'current'`. */
|
|
66
|
-
|
|
73
|
+
lastPoses = new Store();
|
|
67
74
|
/** The clock this mix plays on, which also holds its tape and the marks announced on it. */
|
|
68
75
|
transport;
|
|
69
76
|
/** Its place among the mixes on its transport, in the order they joined. */
|
|
@@ -82,7 +89,7 @@ export class Mixer {
|
|
|
82
89
|
/** The pose `pull` folds a subject into where it cannot read straight from the lanes. */
|
|
83
90
|
scratch;
|
|
84
91
|
/** Live voices by the earliest mix time `moveTo` would change each, a binary heap. */
|
|
85
|
-
due =
|
|
92
|
+
due = new DueQueue();
|
|
86
93
|
/** Voices retired since `moveTo` last pruned them, in the order they retired. */
|
|
87
94
|
retired = [];
|
|
88
95
|
/** Visit every voice each sync, as before the due queue; for tests that compare the two. */
|
|
@@ -151,6 +158,8 @@ export class Mixer {
|
|
|
151
158
|
*/
|
|
152
159
|
chains = new Store();
|
|
153
160
|
version = 0;
|
|
161
|
+
/** The positions `plot` gave, which a voice's `within` reads: see `bound.ts`. */
|
|
162
|
+
places = null;
|
|
154
163
|
/** What `prime` reads its clock, voice time and pass from: see `Primed`. */
|
|
155
164
|
primed = new Float64Array(3 /* Primed.SIZE */);
|
|
156
165
|
steps = new Steps();
|
|
@@ -182,8 +191,10 @@ export class Mixer {
|
|
|
182
191
|
unshared = false;
|
|
183
192
|
/** 0 where a fold is a walk of the chain: see `detour` in `everyone.ts`. */
|
|
184
193
|
detours = 0;
|
|
185
|
-
/** How many voices in the list carry a
|
|
186
|
-
|
|
194
|
+
/** How many voices in the list carry a role; with none, a fold allocates nothing. */
|
|
195
|
+
roleVoices = 0;
|
|
196
|
+
/** The tags the mix's options declare roles. */
|
|
197
|
+
roleTags;
|
|
187
198
|
/** What every motion patch it plays asks for its voice's time, holding this mix weakly. */
|
|
188
199
|
owner = null;
|
|
189
200
|
/** How many voices in the list are anchored, so a sync with none skips placing them. */
|
|
@@ -218,9 +229,9 @@ export class Mixer {
|
|
|
218
229
|
lerpsInto;
|
|
219
230
|
/** By slot, a stock scalar channel's arithmetic, which a fold applies without calling the channel. */
|
|
220
231
|
scalars;
|
|
221
|
-
/** What a fold with a
|
|
222
|
-
|
|
223
|
-
|
|
232
|
+
/** What a fold with a role in play gathers into, one per depth of folds under way. */
|
|
233
|
+
roleScratch = [];
|
|
234
|
+
roleDepth = 0;
|
|
224
235
|
slotOf = new Map();
|
|
225
236
|
lanes;
|
|
226
237
|
handles = null;
|
|
@@ -236,6 +247,7 @@ export class Mixer {
|
|
|
236
247
|
keys = null;
|
|
237
248
|
/** With a history store, the voices it paged out whose handles are still held; null without one. */
|
|
238
249
|
outs = null;
|
|
250
|
+
pose;
|
|
239
251
|
constructor(kit, opts,
|
|
240
252
|
/** The lanes an entry was built with; null in one that leaves them out. */
|
|
241
253
|
lanesOf) {
|
|
@@ -246,6 +258,7 @@ export class Mixer {
|
|
|
246
258
|
this.channels = this.names.map((k) => kit[k]);
|
|
247
259
|
this.bounded = this.channels.flatMap((c, i) => (c.bounds ? [i] : []));
|
|
248
260
|
this.lerpsInto = this.channels.map((c) => lerpInto(c));
|
|
261
|
+
this.pose = blanks(this.names, this.channels);
|
|
249
262
|
this.scalars = this.channels.map((c) => scalarOp(c));
|
|
250
263
|
this.names.forEach((k, i) => {
|
|
251
264
|
this.slotOf.set(k, i);
|
|
@@ -255,6 +268,7 @@ export class Mixer {
|
|
|
255
268
|
this.lanes =
|
|
256
269
|
lanesOf !== null && (opts.lanes ?? defaults.lanes) ? new lanesOf(laneHost(this)) : null;
|
|
257
270
|
this.name = opts.name;
|
|
271
|
+
this.roleTags = roleTags(opts);
|
|
258
272
|
const shared = opts.transport;
|
|
259
273
|
if (shared !== undefined) {
|
|
260
274
|
if (opts.history !== undefined)
|
|
@@ -345,14 +359,14 @@ export class Mixer {
|
|
|
345
359
|
return cue(this, spec);
|
|
346
360
|
}
|
|
347
361
|
blend(members, by, spec = {}) {
|
|
348
|
-
const
|
|
362
|
+
const role = `blend:${this.nextId}`;
|
|
349
363
|
const of = blendOf(by, members.length - 1);
|
|
350
364
|
return members.map((member, i) => {
|
|
351
365
|
const own = {
|
|
352
366
|
...spec,
|
|
353
367
|
patch: member,
|
|
354
368
|
weight: by,
|
|
355
|
-
|
|
369
|
+
role,
|
|
356
370
|
};
|
|
357
371
|
if ('patch' in member) {
|
|
358
372
|
own.patch = member.patch;
|
|
@@ -433,38 +447,6 @@ export class Mixer {
|
|
|
433
447
|
marks(from, to) {
|
|
434
448
|
return listed(this, from, to).map(({ order: _, ...m }) => m);
|
|
435
449
|
}
|
|
436
|
-
atRest(subject) {
|
|
437
|
-
this.restStamps ??= new Store();
|
|
438
|
-
const head = this.linked(subject);
|
|
439
|
-
const laned = this.linkedLaned;
|
|
440
|
-
const lanes = this.lanes;
|
|
441
|
-
// Every voice on lanes and nothing to clamp: the pose a fold would make is the lanes' values.
|
|
442
|
-
if (laned && this.restsLaned()) {
|
|
443
|
-
const slot = head.slot;
|
|
444
|
-
if (!lanes.owes(slot))
|
|
445
|
-
return lanes.rests(slot);
|
|
446
|
-
}
|
|
447
|
-
// A probe this frame answers for the pose it gave the host.
|
|
448
|
-
const since = (this.restStamps.get(subject) ?? Number.NaN) - 2 * this.restsKey();
|
|
449
|
-
if (since >= 0)
|
|
450
|
-
return since === 1;
|
|
451
|
-
this.restScratch ??= {};
|
|
452
|
-
const pose = this.foldWith(subject, this.restScratch, head, laned, true);
|
|
453
|
-
return this.rests((this.bounded.length === 0 ? pose : this.clamp(pose)));
|
|
454
|
-
}
|
|
455
|
-
rests(pose) {
|
|
456
|
-
for (let i = 0; i < this.names.length; i++) {
|
|
457
|
-
const channel = this.channels[i];
|
|
458
|
-
const value = pose[this.names[i]];
|
|
459
|
-
if (channel.rest === undefined) {
|
|
460
|
-
if (value !== undefined)
|
|
461
|
-
return false;
|
|
462
|
-
}
|
|
463
|
-
else if (!near(value, channel.rest))
|
|
464
|
-
return false;
|
|
465
|
-
}
|
|
466
|
-
return true;
|
|
467
|
-
}
|
|
468
450
|
rebase() {
|
|
469
451
|
this.own('rebase').rebase();
|
|
470
452
|
}
|
|
@@ -486,16 +468,6 @@ export class Mixer {
|
|
|
486
468
|
this.asleep = true;
|
|
487
469
|
return inert;
|
|
488
470
|
}
|
|
489
|
-
restful() {
|
|
490
|
-
// Standing still, a voice changes no pose but by its weight signal, or by an anchor or start
|
|
491
|
-
// that host time may yet reach.
|
|
492
|
-
if (this.pace?.stopped(this.u))
|
|
493
|
-
return this.cued.every((v) => v.state === 'done' ||
|
|
494
|
-
(v.state !== 'pending' &&
|
|
495
|
-
typeof v.spec.weight !== 'function' &&
|
|
496
|
-
v.spec.anchor === undefined));
|
|
497
|
-
return this.cued.every((v) => this.still(v, this.now));
|
|
498
|
-
}
|
|
499
471
|
get rate() {
|
|
500
472
|
return this.transport.rate;
|
|
501
473
|
}
|
|
@@ -505,22 +477,6 @@ export class Mixer {
|
|
|
505
477
|
ramp(rate, over) {
|
|
506
478
|
this.own('ramp').ramp(rate, over);
|
|
507
479
|
}
|
|
508
|
-
/** Whether a voice will change no pose from `now` on, short of a change made to it. */
|
|
509
|
-
still(voice, now) {
|
|
510
|
-
if (voice.state === 'done')
|
|
511
|
-
return true;
|
|
512
|
-
if (voice.state !== 'frozen' && voice.state !== 'live')
|
|
513
|
-
return false;
|
|
514
|
-
if (typeof voice.spec.weight === 'function' || voice.parts !== null)
|
|
515
|
-
return false;
|
|
516
|
-
const fadeIn = this.reducedNow ? 0 : (voice.fade.in ?? 0);
|
|
517
|
-
if (fadeIn > 0 && now - this.sinceOf(voice, voice.latest) < fadeIn)
|
|
518
|
-
return false;
|
|
519
|
-
if (voice.state === 'frozen' || voice.holding !== null)
|
|
520
|
-
return true;
|
|
521
|
-
const motion = voice.motion;
|
|
522
|
-
return motion !== undefined && voice.elapsedAt(now) >= voice.latest && motion.landed();
|
|
523
|
-
}
|
|
524
480
|
close() {
|
|
525
481
|
unregister(this);
|
|
526
482
|
}
|
|
@@ -531,80 +487,6 @@ export class Mixer {
|
|
|
531
487
|
}
|
|
532
488
|
record(this, 'mute', (stage) => stage.mix(this)?.mute(opts));
|
|
533
489
|
}
|
|
534
|
-
drop(subject) {
|
|
535
|
-
this.frame = nextFrame();
|
|
536
|
-
const head = headOf(this, subject);
|
|
537
|
-
// Nothing that kept this head, such as `pull`'s remembered list, may take it as current again.
|
|
538
|
-
if (head !== undefined)
|
|
539
|
-
unlink(this, head);
|
|
540
|
-
// A number a seek carried over is released even where its chain is not linked since.
|
|
541
|
-
const slot = this.chains.get(subject)?.slot ?? -1;
|
|
542
|
-
if (slot >= 0 && this.lanes !== null)
|
|
543
|
-
this.lanes.release(slot);
|
|
544
|
-
// A read ahead's copy reads the live mix's poses, and so hides one where the mix deletes it.
|
|
545
|
-
if (this.projecting && !(this.pose instanceof Masked))
|
|
546
|
-
this.pose = new Masked(this.pose);
|
|
547
|
-
this.pose.delete(subject);
|
|
548
|
-
this.restStamps?.delete(subject);
|
|
549
|
-
this.chains.delete(subject);
|
|
550
|
-
this.stir();
|
|
551
|
-
// A record of it is only in a voice over every subject, one naming it, or one gone; a ramp out
|
|
552
|
-
// of a voice that does not name it is in `parters`, and a patch's own state in `motions`.
|
|
553
|
-
const kept = releasing(this);
|
|
554
|
-
for (const voice of this.general)
|
|
555
|
-
this.forgetIn(voice, subject, kept);
|
|
556
|
-
const named = this.named.get(subject);
|
|
557
|
-
if (named !== undefined)
|
|
558
|
-
for (const voice of [...named])
|
|
559
|
-
this.forgetIn(voice, subject, kept);
|
|
560
|
-
const gone = goneIndex(this);
|
|
561
|
-
for (const voice of gone.general)
|
|
562
|
-
this.forgetIn(voice, subject, kept);
|
|
563
|
-
const goneNaming = gone.named.get(subject);
|
|
564
|
-
if (goneNaming !== undefined)
|
|
565
|
-
for (const voice of goneNaming)
|
|
566
|
-
this.forgetIn(voice, subject, kept);
|
|
567
|
-
if (this.owners !== null)
|
|
568
|
-
for (const voice of this.owners)
|
|
569
|
-
this.forgetIn(voice, subject, kept);
|
|
570
|
-
for (const voice of this.parters) {
|
|
571
|
-
this.forgetIn(voice, subject, kept);
|
|
572
|
-
if (voice.parts?.size === 0)
|
|
573
|
-
voice.parts = null;
|
|
574
|
-
if (voice.parted?.size === 0)
|
|
575
|
-
voice.parted = null;
|
|
576
|
-
if (voice.parts === null && voice.parted === null)
|
|
577
|
-
this.parters.delete(voice);
|
|
578
|
-
}
|
|
579
|
-
const strays = this.strays.get(subject);
|
|
580
|
-
if (strays !== undefined)
|
|
581
|
-
for (const motion of strays)
|
|
582
|
-
this.releaseIn(motion, subject, kept);
|
|
583
|
-
this.strays.delete(subject);
|
|
584
|
-
for (const motion of this.strayAll)
|
|
585
|
-
this.releaseIn(motion, subject, kept);
|
|
586
|
-
this.recordDrop(subject);
|
|
587
|
-
}
|
|
588
|
-
/** Lets `voice` go of a dropped subject. Methods rather than closures, so a drop makes neither. */
|
|
589
|
-
forgetIn(voice, subject, kept) {
|
|
590
|
-
leaveVoice(this, voice, subject);
|
|
591
|
-
voice.subjects.delete(subject);
|
|
592
|
-
if (voice.motion !== undefined)
|
|
593
|
-
this.releaseIn(voice.motion, subject, kept);
|
|
594
|
-
voice.parts?.delete(subject);
|
|
595
|
-
voice.parted?.delete(subject);
|
|
596
|
-
voice.blend?.of.reads.delete(subject);
|
|
597
|
-
}
|
|
598
|
-
// A motion patch's state is the live mix's alone: a read ahead cannot start a subject afresh in it.
|
|
599
|
-
releaseIn(motion, subject, kept) {
|
|
600
|
-
if (!this.projecting)
|
|
601
|
-
motion.release(subject, kept[0], kept[1], kept[2]);
|
|
602
|
-
else if (motion.holds(subject))
|
|
603
|
-
unplayable('a drop of a subject a motion patch holds');
|
|
604
|
-
}
|
|
605
|
-
recordDrop(subject) {
|
|
606
|
-
record(this, 'drop', (stage) => stage.mix(this)?.drop(subject));
|
|
607
|
-
}
|
|
608
490
|
touch(subject) {
|
|
609
491
|
this.attached();
|
|
610
492
|
touch(this, subject);
|
|
@@ -641,22 +523,6 @@ export class Mixer {
|
|
|
641
523
|
restsStirs = -1;
|
|
642
524
|
/** The pose `atRest` folds into where no probe this frame answers. */
|
|
643
525
|
restScratch;
|
|
644
|
-
restsLaned() {
|
|
645
|
-
return this.lanes.whole && this.bounded.length === 0;
|
|
646
|
-
}
|
|
647
|
-
restsKey() {
|
|
648
|
-
if (this.frame !== this.restsFrame ||
|
|
649
|
-
this.version !== this.restsVersion ||
|
|
650
|
-
this.relinks !== this.restsRelinks ||
|
|
651
|
-
this.stirs !== this.restsStirs) {
|
|
652
|
-
this.restsEpoch++;
|
|
653
|
-
this.restsFrame = this.frame;
|
|
654
|
-
this.restsVersion = this.version;
|
|
655
|
-
this.restsRelinks = this.relinks;
|
|
656
|
-
this.restsStirs = this.stirs;
|
|
657
|
-
}
|
|
658
|
-
return this.restsEpoch;
|
|
659
|
-
}
|
|
660
526
|
}
|
|
661
527
|
// The probe's hot path is methods, installed here from the modules that own them: as functions
|
|
662
528
|
// called directly they made probes and fills up to 9% slower (bench/ab.sh on teitou, 2026-10-05).
|
|
@@ -666,7 +532,7 @@ const methods = {
|
|
|
666
532
|
linked,
|
|
667
533
|
foldWith,
|
|
668
534
|
owedBy,
|
|
669
|
-
|
|
535
|
+
foldRoles,
|
|
670
536
|
foldDetour,
|
|
671
537
|
foldSharers,
|
|
672
538
|
shared,
|
|
@@ -681,6 +547,7 @@ const methods = {
|
|
|
681
547
|
baseFor,
|
|
682
548
|
slopeFor,
|
|
683
549
|
prime,
|
|
550
|
+
primeLaned,
|
|
684
551
|
capped,
|
|
685
552
|
horizonFor,
|
|
686
553
|
weigh,
|
|
@@ -702,7 +569,22 @@ const methods = {
|
|
|
702
569
|
sinceOf,
|
|
703
570
|
shownOf,
|
|
704
571
|
keep,
|
|
705
|
-
|
|
572
|
+
foldRole,
|
|
573
|
+
atRest,
|
|
574
|
+
rests,
|
|
575
|
+
restful,
|
|
576
|
+
still,
|
|
577
|
+
restsLaned,
|
|
578
|
+
restsKey,
|
|
579
|
+
plot,
|
|
580
|
+
place,
|
|
581
|
+
moved,
|
|
582
|
+
put,
|
|
583
|
+
around,
|
|
584
|
+
drop,
|
|
585
|
+
forgetIn,
|
|
586
|
+
releaseIn,
|
|
587
|
+
recordDrop,
|
|
706
588
|
};
|
|
707
589
|
for (const [name, value] of Object.entries(methods))
|
|
708
590
|
Object.defineProperty(Mixer.prototype, name, { value, writable: true, configurable: true });
|
|
@@ -724,7 +606,7 @@ export function made(kit, opts, lanes) {
|
|
|
724
606
|
return m;
|
|
725
607
|
}
|
|
726
608
|
/**
|
|
727
|
-
* The
|
|
609
|
+
* The engine that ships, running every form on the CPU. It probes per subject on demand.
|
|
728
610
|
*
|
|
729
611
|
* @category engine
|
|
730
612
|
*/
|
|
@@ -736,7 +618,7 @@ export const mixer = {
|
|
|
736
618
|
},
|
|
737
619
|
};
|
|
738
620
|
/**
|
|
739
|
-
* Makes a mix over a kit
|
|
621
|
+
* Makes a mix over a kit. It runs on the engine the options name, or the stock one.
|
|
740
622
|
*
|
|
741
623
|
* @category mix
|
|
742
624
|
*/
|