-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathweb-worker.js
130 lines (125 loc) · 4.21 KB
/
web-worker.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
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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
let tabIndex, windowIndex, isMain, numTabs, numWindows;
let bc,
regInterval,
registrationDone = false;
const PIXEL_COUNT = 4;
const FAVICON_SIZE = 16;
const MULT = FAVICON_SIZE / PIXEL_COUNT;
const TOP_TO_FAVICON = 13;
const HARDCODED_WINDOW_DIFF = 30;
let tabSingle;
let cellHorizontalSpacing = 1;
let lastPixels = null;
function intersects(fst, snd) {
// Check if two rectangles intersect by comparing their bounds
return !(
(
fst.x + fst.w < snd.x || // fst is left of snd
snd.x + snd.w < fst.x || // fst is right of snd
fst.y + fst.h < snd.y || // fst is above snd
snd.y + snd.h < fst.y
) // fst is below snd
);
}
function maybeDrawPixels({ pixels, type = "pixels-bw" }) {
if (lastPixels === null) {
lastPixels = pixels;
postMessage({ type, pixels });
} else {
const diff = pixels.filter((p, i) => p !== lastPixels[i]).length;
if (diff > 0) {
lastPixels = pixels;
postMessage({ type, pixels });
}
}
}
// For non-main tabs, we offload BroadcastChannel logic.
onmessage = function (e) {
const data = e.data;
if (data.type === "init") {
tabIndex = data.tabIndex;
windowIndex = data.windowIndex;
isMain = data.isMain;
numTabs = data.numTabs;
numWindows = data.numWindows;
bc = new BroadcastChannel("bc");
bc.addEventListener("message", (event) => {
const msg = event.data;
if (!msg) return;
else if (
msg.type === "ack" &&
msg.tabIndex === tabIndex &&
msg.windowIndex === windowIndex
) {
clearInterval(regInterval);
registrationDone = true;
postMessage({ type: "registration-ack" });
} else if (msg.type === "window-info") {
tabSingle = msg.tabSingle;
cellHorizontalSpacing = msg.cellHorizontalSpacing;
} else if (msg.type === "square-position") {
const square = msg.square;
const pixels = [];
for (let yy = 0; yy < PIXEL_COUNT; yy++) {
for (let xx = 0; xx < PIXEL_COUNT; xx++) {
const x =
tabSingle * tabIndex + (tabSingle - FAVICON_SIZE) / 2 + xx * MULT;
const y =
TOP_TO_FAVICON + HARDCODED_WINDOW_DIFF * windowIndex + yy * MULT;
let thisSquare = { x, y, w: MULT, h: MULT };
const doesIntersect = intersects(square, thisSquare);
pixels.push(doesIntersect ? 1 : 0);
}
}
maybeDrawPixels(pixels);
} else if (msg.type === "snake-position") {
const snake = msg.snake;
const myX = tabIndex;
const myY = windowIndex;
const pixels = [];
if (
snake.occupied.some((coord) => coord[0] === myX && coord[1] === myY)
) {
pixels.push(1);
} else {
pixels.push(0);
}
maybeDrawPixels({ pixels });
} else if (msg.type === "pong-position") {
const ourPaddle = msg.ourPaddle;
const ball = msg.ball;
const theirPaddle = msg.theirPaddle;
const pixels = [];
for (let yy = 0; yy < PIXEL_COUNT; yy++) {
for (let xx = 0; xx < PIXEL_COUNT; xx++) {
const x =
tabSingle * tabIndex + (tabSingle - FAVICON_SIZE) / 2 + xx * MULT;
// const y = FAVICON_SIZE * windowIndex + yy * MULT;
const y =
TOP_TO_FAVICON + HARDCODED_WINDOW_DIFF * windowIndex + yy * MULT;
let thisSquare = { x, y, w: MULT, h: MULT };
const intersectOurPaddle = intersects(ourPaddle, thisSquare);
const intersectBall = intersects(ball, thisSquare);
const intersectTheirPaddle = intersects(theirPaddle, thisSquare);
if (intersectOurPaddle) {
pixels.push(2);
} else if (intersectBall) {
pixels.push(3);
} else if (intersectTheirPaddle) {
pixels.push(4);
} else {
pixels.push(1);
}
}
}
maybeDrawPixels({ pixels, type: "pixels-color" });
}
});
regInterval = setInterval(() => {
bc.postMessage({ type: "register", tabIndex, windowIndex });
}, 1000);
} else if (data.type === "relay-to-bc") {
const message = { ...data.msg };
bc.postMessage(message);
}
};