UNPKG

2.67 kBPlain TextView Raw
1import * as Classes from "./classes.js";
2import { TransportClass } from "./core/clock/Transport.js";
3import { Context } from "./core/context/Context.js";
4import { ListenerClass } from "./core/context/Listener.js";
5import { DestinationClass } from "./core/context/Destination.js";
6import { FrequencyClass } from "./core/type/Frequency.js";
7import { MidiClass } from "./core/type/Midi.js";
8import { TicksClass } from "./core/type/Ticks.js";
9import { TimeClass } from "./core/type/Time.js";
10import { TransportTimeClass } from "./core/type/TransportTime.js";
11import { isDefined, isFunction } from "./core/util/TypeCheck.js";
12import { omitFromObject } from "./core/util/Defaults.js";
13import { DrawClass } from "./core/util/Draw.js";
14
15type ClassesWithoutSingletons = Omit<
16 typeof Classes,
17 "Transport" | "Destination" | "Draw"
18>;
19
20/**
21 * The exported Tone object. Contains all of the classes that default
22 * to the same context and contains a singleton Transport and Destination node.
23 */
24type ToneObject = {
25 Transport: TransportClass;
26 Destination: DestinationClass;
27 Listener: ListenerClass;
28 Draw: DrawClass;
29 context: Context;
30 now: () => number;
31 immediate: () => number;
32} & ClassesWithoutSingletons;
33
34/**
35 * Bind the TimeBaseClass to the context
36 */
37function bindTypeClass(context: Context, type) {
38 return (...args: unknown[]) => new type(context, ...args);
39}
40
41/**
42 * Return an object with all of the classes bound to the passed in context
43 * @param context The context to bind all of the nodes to
44 */
45export function fromContext(context: Context): ToneObject {
46 const classesWithContext: Partial<ClassesWithoutSingletons> = {};
47 Object.keys(
48 omitFromObject(Classes, ["Transport", "Destination", "Draw"])
49 ).map((key) => {
50 const cls = Classes[key];
51 if (isDefined(cls) && isFunction(cls.getDefaults)) {
52 classesWithContext[key] = class ToneFromContextNode extends cls {
53 get defaultContext(): Context {
54 return context;
55 }
56 };
57 } else {
58 // otherwise just copy it over
59 classesWithContext[key] = Classes[key];
60 }
61 });
62
63 const toneFromContext: ToneObject = {
64 ...(classesWithContext as ClassesWithoutSingletons),
65 now: context.now.bind(context),
66 immediate: context.immediate.bind(context),
67 Transport: context.transport,
68 Destination: context.destination,
69 Listener: context.listener,
70 Draw: context.draw,
71 context,
72 // the type functions
73 Midi: bindTypeClass(context, MidiClass),
74 Time: bindTypeClass(context, TimeClass),
75 Frequency: bindTypeClass(context, FrequencyClass),
76 Ticks: bindTypeClass(context, TicksClass),
77 TransportTime: bindTypeClass(context, TransportTimeClass),
78 };
79 // return the object
80 return toneFromContext;
81}