generated from stagas/ts
/
plugs-and-cables.ts
89 lines (77 loc) · 2.08 KB
/
plugs-and-cables.ts
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
import { dispatch, EventHandler } from 'event-toolkit'
import { cheapRandomId } from 'everyday-utils'
export enum PlugKind {
Input = 'input',
Output = 'output',
}
export class Plug<P extends PlugKind = any, C extends string = any> extends EventTarget {
static Output = PlugKind.Output as const
static Input = PlugKind.Input as const
plugKind!: P
cableKind!: C
cables = new Map<Cable, Plug<(P extends PlugKind.Output ? PlugKind.Input : PlugKind.Output), C>>()
declare onconnect: EventHandler<Plug, CustomEvent<{ cable: Cable; plug: Plug }>>
declare ondisconnect: EventHandler<Plug, CustomEvent<{ cable: Cable; plug: Plug }>>
constructor(
plug: Plug<P, C>,
)
constructor(
plugKind: P | Plug<P, C>,
cableKind: C,
)
constructor(
plugKind: P | Plug<P, C>,
cableKind?: C,
) {
super()
if (typeof plugKind === 'object') {
Object.assign(this, plugKind)
} else {
this.plugKind = plugKind
this.cableKind = cableKind!
}
}
connect(this: Plug, other: Plug, cable = new Cable()) {
this.cables.set(cable, other)
other.cables.set(cable, this)
dispatch(this, 'connect', { cable, plug: other })
dispatch(other, 'connect', { cable, plug: this })
return cable
}
disconnect(this: Plug, cable: Cable) {
const other = this.cables.get(cable)
if (!other) {
throw new Error('Cable not connected')
}
this.cables.delete(cable)
other.cables.delete(cable)
dispatch(this, 'disconnect', { cable, plug: other })
dispatch(other, 'disconnect', { cable, plug: this })
return cable
}
}
export class Cable {
id = cheapRandomId()
outputCh!: number
inputCh!: number
constructor(
cable: Cable,
)
constructor(
outputCh?: number,
inputCh?: number,
)
constructor(
outputCh: Cable | number = 0,
inputCh = 0,
) {
if (typeof outputCh === 'object') {
Object.assign(this, outputCh)
} else {
this.outputCh = outputCh as number
this.inputCh = inputCh
}
}
}
// const output = new Plug(Plug.Output, 'audio')
// const input = new Plug(Plug.Input, 'audio')