-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathbit-channel-broadcaster.js
62 lines (52 loc) · 1.9 KB
/
bit-channel-broadcaster.js
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
import { MessageEncoder, BitDataView, toBinaryString } from "./binutils.js";
export class BitChannelBroadcaster extends EventTarget {
#pressureGeneratorFn;
constructor(pressureGeneratorFn) {
super();
this.#pressureGeneratorFn = pressureGeneratorFn;
}
async sendMessage(msg, calibration) {
const enc = new MessageEncoder();
const bits = new BitDataView(enc.encode(msg).buffer);
const timeout = delay => new Promise(resolve => setTimeout(resolve, delay));
while (true) {
let i = 0;
let lastDwordIndex = 0;
for (let bit of bits) {
let byteIndex = Math.floor(i++ / 8);
let dwordIndex = byteIndex % 4;
this.dispatchEvent(new CustomEvent("bitsent", { detail: { value: bit } }));
let byte = bits.getUint8(byteIndex);
let chkByte = bits.getUint8(byteIndex + 1);
if (dwordIndex !== lastDwordIndex) {
if (dwordIndex === 0) {
let pos = byte - 128;
this.dispatchEvent(new CustomEvent("datachange", {
detail: {
type: "position",
value: pos,
data: new Uint8Array([byte, chkByte])
}
}));
} else if (dwordIndex === 2) {
const dec = new TextDecoder("utf-8");
const ch = dec.decode(bits.buffer.slice(byteIndex, byteIndex + 1));
this.dispatchEvent(new CustomEvent("datachange", {
detail: {
type: "character",
value: ch,
data: new Uint8Array([byte, chkByte])
}
}));
}
}
lastDwordIndex = dwordIndex;
this.#pressureGeneratorFn(bit ? calibration.one : calibration.zero);
await timeout(calibration.delay);
console.log("Sending 'reset'");
this.#pressureGeneratorFn(calibration.reset);
await timeout(2 * calibration.delay);
}
}
}
};