public/scripts/worker.js
var socket;
var sessionID;
var joint;
var connected = false;
function send(cmd, msg) {
socket.send(JSON.stringify([cmd, msg]));
}
function onOpen() {
postMessage({"cmd": "connected"});
}
function onClose(evt) {
postMessage({"cmd": "disconnected"});
}
function onChat(handle, text, showNotification) {
postMessage({"cmd": "chat", "handle": handle, "text": text, "showNotification": showNotification});
}
function onStart(msg, newSessionID) {
joint = msg;
sessionID = newSessionID;
msg.chat.forEach((msg) => {
onChat(msg[0], msg[1], false);
});
}
function onJoin(handle, joinSessionID, showNotification) {
if (joinSessionID === sessionID) {
showNotification = false;
}
postMessage({"cmd": "join", "sessionID": joinSessionID, "handle": handle, "showNotification": showNotification});
}
function onNick(handle, nickSessionID) {
postMessage({"cmd": "nick", "sessionID": nickSessionID, "handle": handle, "showNotification": (nickSessionID !== sessionID)});
}
function onPart(sessionID) {
postMessage({"cmd": "part", "sessionID": sessionID});
}
function onDraw(blocks) {
var outputBlocks = new Array();
var index;
blocks.forEach((block) => {
index = block >> 16;
outputBlocks.push([index, block & 0xffff, index % joint.columns, Math.floor(index / joint.columns)]);
});
postMessage({"cmd": "draw", "blocks": outputBlocks});
}
function onMessage(evt) {
var data = evt.data;
if (typeof(data) === "object") {
var fr = new FileReader();
fr.addEventListener("load", (evt) => {
postMessage({"cmd": "imageData", "data": evt.target.result, "columns": joint.columns, "rows": joint.rows, "iceColours": joint.iceColours, "letterSpacing": joint.letterSpacing});
connected = true;
});
fr.readAsArrayBuffer(data);
} else {
data = JSON.parse(data);
switch(data[0]) {
case "start":
sessionID = data[2];
var userList = data[3];
Object.keys(userList).forEach((userSessionID) => {
onJoin(userList[userSessionID], userSessionID, false);
});
onStart(data[1], data[2]);
break;
case "join":
onJoin(data[1], data[2], true);
break;
case "nick":
onNick(data[1], data[2]);
break;
case "draw":
onDraw(data[1]);
break;
case "part":
onPart(data[1]);
break;
case "chat":
onChat(data[1], data[2], true);
break;
default:
break;
}
}
}
function removeDuplicates(blocks) {
var indexes = [];
var index;
blocks = blocks.reverse();
blocks = blocks.filter((block) => {
index = block >> 16;
if (indexes.lastIndexOf(index) === -1) {
indexes.push(index);
return true;
}
return false;
});
return blocks.reverse();
}
self.onmessage = function (msg) {
var data = msg.data;
switch(data.cmd) {
case "connect":
socket = new WebSocket(data.url);
socket.addEventListener("open", onOpen);
socket.addEventListener("message", onMessage);
socket.addEventListener("close", onClose);
break;
case "join":
send("join", data.handle);
break;
case "nick":
send("nick", data.handle);
break;
case "chat":
send("chat", data.text);
break;
case "draw":
send("draw", removeDuplicates(data.blocks));
break;
default:
break;
}
};