Organize code in namespaces

This commit is contained in:
Unrud 2022-02-22 21:53:16 +01:00
parent 9432869bce
commit 190b2763bd

View file

@ -56,23 +56,10 @@ var KEY_RETURN = 17;
var ws = null; var ws = null;
var config = null; var config = null;
var touchMoved = false; var util = (function() {
var touchStart = 0; var util = {};
var touchLastEnd = 0;
var touchReleasedCount = 0;
var ongoingTouches = [];
var moveXSum = 0;
var moveYSum = 0;
var scrollXSum = 0;
var scrollYSum = 0;
var dragging = false;
var draggingTimeout = null;
var scrollFinish = false;
var scrolling = false;
var mouseButtons = 0;
var updateTimeoutActive = false;
function fullscreenEnabled() { util.fullscreenEnabled = function() {
return (document.fullscreenEnabled || return (document.fullscreenEnabled ||
document.webkitFullscreenEnabled || document.webkitFullscreenEnabled ||
document.mozFullScreenEnabled || document.mozFullScreenEnabled ||
@ -80,7 +67,7 @@ function fullscreenEnabled() {
false); false);
} }
function requestFullscreen(element, options) { util.requestFullscreen = function(element, options) {
if (element.requestFullscreen) { if (element.requestFullscreen) {
element.requestFullscreen(options); element.requestFullscreen(options);
} else if (element.webkitRequestFullscreen) { } else if (element.webkitRequestFullscreen) {
@ -92,7 +79,7 @@ function requestFullscreen(element, options) {
} }
} }
function exitFullscreen() { util.exitFullscreen = function() {
if (document.exitFullscreen) { if (document.exitFullscreen) {
document.exitFullscreen(); document.exitFullscreen();
} else if (document.webkitExitFullscreen) { } else if (document.webkitExitFullscreen) {
@ -104,7 +91,7 @@ function exitFullscreen() {
} }
} }
function fullscreenElement() { util.fullscreenElement = function() {
return (document.fullscreenElement || return (document.fullscreenElement ||
document.webkitFullscreenElement || document.webkitFullscreenElement ||
document.mozFullScreenElement || document.mozFullScreenElement ||
@ -112,7 +99,7 @@ function fullscreenElement() {
null); null);
} }
function addFullscreenchangeEventListener(listener) { util.addFullscreenchangeEventListener = function(listener) {
if ("onfullscreenchange" in document) { if ("onfullscreenchange" in document) {
document.addEventListener("fullscreenchange", listener); document.addEventListener("fullscreenchange", listener);
} else if ("onwebkitfullscreenchange" in document) { } else if ("onwebkitfullscreenchange" in document) {
@ -120,7 +107,7 @@ function addFullscreenchangeEventListener(listener) {
} }
} }
function requestPointerLock(element) { util.requestPointerLock = function(element) {
if (element.requestPointerLock) { if (element.requestPointerLock) {
element.requestPointerLock(); element.requestPointerLock();
} else if (element.mozRequestPointerLock) { } else if (element.mozRequestPointerLock) {
@ -128,7 +115,7 @@ function requestPointerLock(element) {
} }
} }
function exitPointerLock() { util.exitPointerLock = function() {
if (document.exitPointerLock) { if (document.exitPointerLock) {
document.exitPointerLock(); document.exitPointerLock();
} else if (document.mozExitPointerLock) { } else if (document.mozExitPointerLock) {
@ -136,13 +123,13 @@ function exitPointerLock() {
} }
} }
function pointerLockElement() { util.pointerLockElement = function() {
return (document.pointerLockElement || return (document.pointerLockElement ||
document.mozPointerLockElement || document.mozPointerLockElement ||
null); null);
} }
function addPointerlockchangeEventListener(listener) { util.addPointerlockchangeEventListener = function(listener) {
if ("onpointerlockchange" in document) { if ("onpointerlockchange" in document) {
document.addEventListener("pointerlockchange", listener); document.addEventListener("pointerlockchange", listener);
} else if ("onmozpointerlockchange" in document) { } else if ("onmozpointerlockchange" in document) {
@ -150,6 +137,93 @@ function addPointerlockchangeEventListener(listener) {
} }
} }
return util;
})();
var controller = (function() {
var controller = {};
var moveXSum = 0;
var moveYSum = 0;
var scrollHSum = 0;
var scrollVSum = 0;
var scrolling = false;
var scrollFinish = false;
var updateTimoueActive = false;
function startUpdate(fromTimeout) {
if (updateTimoueActive && !fromTimeout) {
return;
}
var finished = true;
var xInt = Math.trunc(moveXSum);
var yInt = Math.trunc(moveYSum);
if (xInt != 0 || yInt != 0) {
ws.send("m" + xInt + ";" + yInt);
moveXSum -= xInt;
moveYSum -= yInt;
finished = false;
}
var hInt = Math.trunc(scrollHSum);
var vInt = Math.trunc(scrollVSum);
if (hInt != 0 || vInt != 0) {
ws.send((scrollFinish ? "S" : "s") + hInt + ";" + vInt);
scrollHSum -= hInt;
scrollVSum -= vInt;
scrolling = !scrollFinish;
scrollFinish = false;
finished = false;
} else if (scrollFinish && scrolling) {
ws.send("S");
scrolling = false;
scrollFinish = false;
}
updateTimoueActive = !finished && config.updateRate > 0
if (updateTimoueActive) {
setTimeout(startUpdate, 1000/config.updateRate, true);
}
}
controller.pointerMove = function(deltaX, deltaY) {
moveXSum += deltaX;
moveYSum += deltaY;
startUpdate();
}
controller.pointerScroll = function(deltaHorizontal, deltaVertical, finish) {
scrollHSum += deltaHorizontal;
scrollVSum += deltaVertical;
scrollFinish |= finish;
startUpdate();
}
controller.pointerButton = function(button, press) {
ws.send("b" + button + ";" + (press ? 1 : 0));
}
controller.keyboardKey = function(key) {
ws.send("k" + key);
}
controller.keyboardText = function(text) {
ws.send("t" + text);
}
return controller;
})();
var touchpad = (function() {
var touchpad = {};
var moved = false;
var startTimeStamp = 0;
var lastEndTimeStamp = 0;
var releasedCount = 0;
var ongoingTouches = [];
var dragging = false;
var draggingTimeout = null;
function copyTouch(touch, timeStamp) { function copyTouch(touch, timeStamp) {
return { return {
identifier: touch.identifier, identifier: touch.identifier,
@ -170,7 +244,7 @@ function ongoingTouchIndexById(idToFind) {
return -1; return -1;
} }
function calculatePointerAccelerationMult(speed) { function calculateAccelerationMult(speed) {
for (var i = 0; i < POINTER_ACCELERATION.length; i += 1) { for (var i = 0; i < POINTER_ACCELERATION.length; i += 1) {
var s2 = POINTER_ACCELERATION[i][0]; var s2 = POINTER_ACCELERATION[i][0];
var a2 = POINTER_ACCELERATION[i][1]; var a2 = POINTER_ACCELERATION[i][1];
@ -192,61 +266,14 @@ function calculatePointerAccelerationMult(speed) {
function onDraggingTimeout() { function onDraggingTimeout() {
draggingTimeout = null; draggingTimeout = null;
ws.send("b" + POINTER_BUTTON_LEFT + ";0"); controller.pointerButton(POINTER_BUTTON_LEFT, false)
} }
function startUpdate(fromTimeout) { touchpad.handleTouchstart = function(evt) {
if (updateTimeoutActive && !fromTimeout) {
return;
}
var updateFinished = true;
var xInt, yInt;
xInt = Math.trunc(moveXSum);
yInt = Math.trunc(moveYSum);
if (xInt != 0 || yInt != 0) {
ws.send("m" + xInt + ";" + yInt);
moveXSum -= xInt;
moveYSum -= yInt;
updateFinished = false;
}
xInt = Math.trunc(scrollXSum);
yInt = Math.trunc(scrollYSum);
if (xInt != 0 || yInt != 0) {
ws.send((scrollFinish ? "S" : "s") + xInt + ";" + yInt);
scrollXSum -= xInt;
scrollYSum -= yInt;
scrolling = !scrollFinish;
scrollFinish = false;
updateFinished = false;
} else if (scrollFinish && scrolling) {
ws.send("S");
scrolling = false;
scrollFinish = false;
}
updateTimeoutActive = !updateFinished && config.updateRate > 0
if (updateTimeoutActive) {
setTimeout(startUpdate, 1000/config.updateRate, true);
}
}
function updateMove(x, y) {
moveXSum += x;
moveYSum += y;
startUpdate();
}
function updateScroll(x, y, finish) {
scrollXSum += x;
scrollYSum += y;
scrollFinish |= finish;
startUpdate();
}
function handleTouchstart(evt) {
// Might get called multiple times for the same touches // Might get called multiple times for the same touches
if (ongoingTouches.length == 0) { if (ongoingTouches.length == 0) {
touchStart = evt.timeStamp; startTimeStamp = evt.timeStamp;
touchMoved = false; moved = false;
} }
var touches = evt.changedTouches; var touches = evt.changedTouches;
for (var i = 0; i < touches.length; i += 1) { for (var i = 0; i < touches.length; i += 1) {
@ -261,17 +288,17 @@ function handleTouchstart(evt) {
} else { } else {
ongoingTouches[idx] = touch; ongoingTouches[idx] = touch;
} }
touchLastEnd = 0; lastEndTimeStamp = 0;
if (draggingTimeout != null) { if (draggingTimeout != null) {
clearTimeout(draggingTimeout); clearTimeout(draggingTimeout);
draggingTimeout = null; draggingTimeout = null;
dragging = true; dragging = true;
} }
updateScroll(0, 0, true); controller.pointerScroll(0, 0, true);
} }
} }
function handleTouchend(evt) { touchpad.handleTouchend = touchpad.handleTouchcancel = function(evt) {
var touches = evt.changedTouches; var touches = evt.changedTouches;
for (var i = 0; i < touches.length; i += 1) { for (var i = 0; i < touches.length; i += 1) {
var idx = ongoingTouchIndexById(touches[i].identifier); var idx = ongoingTouchIndexById(touches[i].identifier);
@ -280,39 +307,39 @@ function handleTouchend(evt) {
} }
evt.preventDefault(); evt.preventDefault();
ongoingTouches.splice(idx, 1); ongoingTouches.splice(idx, 1);
touchReleasedCount += 1; releasedCount += 1;
touchLastEnd = evt.timeStamp; lastEndTimeStamp = evt.timeStamp;
updateScroll(0, 0, true); controller.pointerScroll(0, 0, true);
} }
if (touchReleasedCount > TOUCH_MOVE_THRESHOLD.length) { if (releasedCount > TOUCH_MOVE_THRESHOLD.length) {
touchMoved = true; moved = true;
} }
if (ongoingTouches.length == 0 && touchReleasedCount >= 1) { if (ongoingTouches.length == 0 && releasedCount >= 1) {
if (dragging) { if (dragging) {
dragging = false; dragging = false;
ws.send("b" + POINTER_BUTTON_LEFT + ";0"); controller.pointerButton(POINTER_BUTTON_LEFT, false)
} }
if (!touchMoved && evt.timeStamp - touchStart < TOUCH_TIMEOUT) { if (!moved && evt.timeStamp - startTimeStamp < TOUCH_TIMEOUT) {
var button = 0; var button = 0;
if (touchReleasedCount == 1) { if (releasedCount == 1) {
button = POINTER_BUTTON_LEFT; button = POINTER_BUTTON_LEFT;
} else if (touchReleasedCount == 2) { } else if (releasedCount == 2) {
button = POINTER_BUTTON_RIGHT; button = POINTER_BUTTON_RIGHT;
} else if (touchReleasedCount == 3) { } else if (releasedCount == 3) {
button = POINTER_BUTTON_MIDDLE; button = POINTER_BUTTON_MIDDLE;
} }
ws.send("b" + button + ";1"); controller.pointerButton(button, true)
if (button == POINTER_BUTTON_LEFT) { if (button == POINTER_BUTTON_LEFT) {
draggingTimeout = setTimeout(onDraggingTimeout, TOUCH_TIMEOUT); draggingTimeout = setTimeout(onDraggingTimeout, TOUCH_TIMEOUT);
} else { } else {
ws.send("b" + button + ";0"); controller.pointerButton(button, false)
} }
} }
touchReleasedCount = 0; releasedCount = 0;
} }
} }
function handleTouchmove(evt) { touchpad.handleTouchmove = function(evt) {
var sumX = 0; var sumX = 0;
var sumY = 0; var sumY = 0;
var touches = evt.changedTouches; var touches = evt.changedTouches;
@ -322,34 +349,40 @@ function handleTouchmove(evt) {
continue; continue;
} }
evt.preventDefault(); evt.preventDefault();
if (!touchMoved) { if (!moved) {
var dist = Math.sqrt(Math.pow(touches[i].pageX - ongoingTouches[idx].pageXStart, 2) + var dist = Math.sqrt(Math.pow(touches[i].pageX - ongoingTouches[idx].pageXStart, 2) +
Math.pow(touches[i].pageY - ongoingTouches[idx].pageYStart, 2)); Math.pow(touches[i].pageY - ongoingTouches[idx].pageYStart, 2));
if (ongoingTouches.length > TOUCH_MOVE_THRESHOLD.length || if (ongoingTouches.length > TOUCH_MOVE_THRESHOLD.length ||
dist > TOUCH_MOVE_THRESHOLD[ongoingTouches.length - 1] || dist > TOUCH_MOVE_THRESHOLD[ongoingTouches.length - 1] ||
evt.timeStamp - touchStart >= TOUCH_TIMEOUT) { evt.timeStamp - startTimeStamp >= TOUCH_TIMEOUT) {
touchMoved = true; moved = true;
} }
} }
var dx = touches[i].pageX - ongoingTouches[idx].pageX; var dx = touches[i].pageX - ongoingTouches[idx].pageX;
var dy = touches[i].pageY - ongoingTouches[idx].pageY; var dy = touches[i].pageY - ongoingTouches[idx].pageY;
var timeDelta = evt.timeStamp - ongoingTouches[idx].timeStamp; var timeDelta = evt.timeStamp - ongoingTouches[idx].timeStamp;
sumX += dx * calculatePointerAccelerationMult(Math.abs(dx) / timeDelta * 1000); sumX += dx * calculateAccelerationMult(Math.abs(dx) / timeDelta * 1000);
sumY += dy * calculatePointerAccelerationMult(Math.abs(dy) / timeDelta * 1000); sumY += dy * calculateAccelerationMult(Math.abs(dy) / timeDelta * 1000);
ongoingTouches[idx].pageX = touches[i].pageX; ongoingTouches[idx].pageX = touches[i].pageX;
ongoingTouches[idx].pageY = touches[i].pageY; ongoingTouches[idx].pageY = touches[i].pageY;
ongoingTouches[idx].timeStamp = evt.timeStamp; ongoingTouches[idx].timeStamp = evt.timeStamp;
} }
if (touchMoved && evt.timeStamp - touchLastEnd >= TOUCH_TIMEOUT) { if (moved && evt.timeStamp - lastEndTimeStamp >= TOUCH_TIMEOUT) {
if (ongoingTouches.length == 1 || dragging) { if (ongoingTouches.length == 1 || dragging) {
updateMove(sumX*config.moveSpeed, sumY*config.moveSpeed); controller.pointerMove(sumX*config.moveSpeed, sumY*config.moveSpeed);
} else if (ongoingTouches.length == 2) { } else if (ongoingTouches.length == 2) {
updateScroll(-sumX*config.scrollSpeed, -sumY*config.scrollSpeed, false); controller.pointerScroll(-sumX*config.scrollSpeed, -sumY*config.scrollSpeed, false);
} }
} }
} }
function handleKeydown(evt) { return touchpad;
})();
var keyboard = (function() {
var keyboard = {};
keyboard.handleKeydown = function(evt) {
if (evt.ctrlKey || evt.altKey || evt.isComposing) { if (evt.ctrlKey || evt.altKey || evt.isComposing) {
return; return;
} }
@ -378,44 +411,51 @@ function handleKeydown(evt) {
if (key != null) { if (key != null) {
if (!evt.shiftKey) { if (!evt.shiftKey) {
evt.preventDefault(); evt.preventDefault();
ws.send("k" + key); controller.keyboardKey(key);
} }
} else if (evt.key.length == 1) { } else if (evt.key.length == 1) {
evt.preventDefault(); evt.preventDefault();
ws.send("t" + evt.key); controller.keyboardText(evt.key);
} }
} }
function updateMouseButtons(buttons) { return keyboard;
})();
var mouse = (function() {
var mouse = {};
var buttons = 0;
function updateButtons(newButtons) {
for (var button = 0; button < 3; button += 1) { for (var button = 0; button < 3; button += 1) {
var flag = 1 << button; var flag = 1 << button;
if ((buttons&flag) != (mouseButtons&flag)) { if ((newButtons&flag) != (buttons&flag)) {
ws.send("b" + button + ";" + (buttons&flag ? 1 : 0)); controller.pointerButton(button, newButtons&flag)
} }
} }
mouseButtons = buttons; buttons = newButtons;
} }
function handleMousedown(evt) { mouse.handleMousedown = mouse.handleMouseup = function(evt) {
updateMouseButtons(evt.buttons); updateButtons(evt.buttons);
} }
function handleMouseup(evt) { mouse.handleMousemove = function(evt) {
updateMouseButtons(evt.buttons); controller.pointerMove(evt.movementX*config.mouseMoveSpeed, evt.movementY*config.mouseMoveSpeed);
} }
function handleMousemove(evt) { mouse.handleWheel = function(evt) {
updateMove(evt.movementX*config.mouseMoveSpeed, evt.movementY*config.mouseMoveSpeed);
}
function handleWheel(evt) {
if (evt.deltaMode == WheelEvent.DOM_DELTA_PIXEL) { if (evt.deltaMode == WheelEvent.DOM_DELTA_PIXEL) {
updateScroll(evt.deltaX*config.mouseScrollSpeed, evt.deltaY*config.mouseScrollSpeed, true); controller.pointerScroll(evt.deltaX*config.mouseScrollSpeed, evt.deltaY*config.mouseScrollSpeed, true);
} else if (evt.deltaMode == WheelEvent.DOM_DELTA_LINE) { } else if (evt.deltaMode == WheelEvent.DOM_DELTA_LINE) {
updateScroll(evt.deltaX*20*config.mouseScrollSpeed, evt.deltaY*20*config.mouseScrollSpeed, true); controller.pointerScroll(evt.deltaX*20*config.mouseScrollSpeed, evt.deltaY*20*config.mouseScrollSpeed, true);
} }
} }
return mouse;
})();
function challengeResponse(message) { function challengeResponse(message) {
var shaObj = new jsSHA("SHA-256", "TEXT"); var shaObj = new jsSHA("SHA-256", "TEXT");
shaObj.setHMACKey(message, "TEXT"); shaObj.setHMACKey(message, "TEXT");
@ -445,11 +485,11 @@ window.addEventListener("load", function() {
function showScene(scene) { function showScene(scene) {
activeScene = scene; activeScene = scene;
if (fullscreenElement() && !scene.classList.contains("fullscreen")) { if (util.fullscreenElement() && !scene.classList.contains("fullscreen")) {
exitFullscreen(); util.exitFullscreen();
} }
if (pointerLockElement() && activeScene != mouseScene) { if (util.pointerLockElement() && activeScene != mouseScene) {
exitPointerLock(); util.exitPointerLock();
} }
keyboardTextarea.value = ""; keyboardTextarea.value = "";
scenes.forEach(function(otherScene) { scenes.forEach(function(otherScene) {
@ -496,7 +536,7 @@ window.addEventListener("load", function() {
function updateUI() { function updateUI() {
if (!ready) { if (!ready) {
showScene(closed ? closedScene : openingScene); showScene(closed ? closedScene : openingScene);
} else if (pointerLockElement()) { } else if (util.pointerLockElement()) {
showScene(mouseScene); showScene(mouseScene);
} else if ((history.state || "").split(":")[0] == "keys") { } else if ((history.state || "").split(":")[0] == "keys") {
showKeys(history.state.substr("keys:".length)); showKeys(history.state.substr("keys:".length));
@ -543,15 +583,17 @@ window.addEventListener("load", function() {
document.getElementById("keyboardbutton").addEventListener("click", function() { document.getElementById("keyboardbutton").addEventListener("click", function() {
showKeyboard(); showKeyboard();
}); });
addFullscreenchangeEventListener(updateUI); util.addFullscreenchangeEventListener(function() {
if (!fullscreenEnabled()) { updateUI();
});
if (!util.fullscreenEnabled()) {
fullscreenbutton.classList.add("hidden"); fullscreenbutton.classList.add("hidden");
} }
fullscreenbutton.addEventListener("click", function() { fullscreenbutton.addEventListener("click", function() {
if (fullscreenElement()) { if (util.fullscreenElement()) {
exitFullscreen(); util.exitFullscreen();
} else { } else {
requestFullscreen(document.documentElement, {navigationUI: "hide"}); util.requestFullscreen(document.documentElement, {navigationUI: "hide"});
} }
}); });
document.getElementById("switchbutton").addEventListener("click", function() { document.getElementById("switchbutton").addEventListener("click", function() {
@ -584,7 +626,7 @@ window.addEventListener("load", function() {
{id: "downbutton", key: KEY_DOWN} {id: "downbutton", key: KEY_DOWN}
].forEach(function(o) { ].forEach(function(o) {
document.getElementById(o.id).addEventListener("click", function() { document.getElementById(o.id).addEventListener("click", function() {
ws.send("k" + o.key); controller.keyboardKey(o.key);
}); });
}); });
document.getElementById("keyboardkeysbutton").addEventListener("click", function() { document.getElementById("keyboardkeysbutton").addEventListener("click", function() {
@ -593,13 +635,15 @@ window.addEventListener("load", function() {
document.getElementById("sendbutton").addEventListener("click", function() { document.getElementById("sendbutton").addEventListener("click", function() {
if (keyboardTextarea.value) { if (keyboardTextarea.value) {
// normalize line endings // normalize line endings
ws.send("t" + keyboardTextarea.value.replace(/\r\n?/g, "\n")); controller.keyboardText(keyboardTextarea.value.replace(/\r\n?/g, "\n"));
keyboardTextarea.value = ""; keyboardTextarea.value = "";
keyboardTextarea.oninput(); keyboardTextarea.oninput();
} }
history.back(); history.back();
}); });
window.addEventListener("popstate", updateUI); window.addEventListener("popstate", function() {
updateUI();
});
document.getElementById("reloadbutton").addEventListener("click", function() { document.getElementById("reloadbutton").addEventListener("click", function() {
location.reload(); location.reload();
}); });
@ -608,19 +652,21 @@ window.addEventListener("load", function() {
history.back(); history.back();
}); });
}); });
document.addEventListener("touchstart", handleTouchstart); document.addEventListener("touchstart", touchpad.handleTouchstart);
document.addEventListener("touchend", handleTouchend); document.addEventListener("touchend", touchpad.handleTouchend);
document.addEventListener("touchcancel", handleTouchend); document.addEventListener("touchcancel", touchpad.handleTouchcancel);
document.addEventListener("touchmove", handleTouchmove); document.addEventListener("touchmove", touchpad.handleTouchmove);
document.addEventListener("keydown", function(evt) { document.addEventListener("keydown", function(evt) {
if (activeScene && activeScene.classList.contains("key")) { if (activeScene && activeScene.classList.contains("key")) {
handleKeydown(evt); keyboard.handleKeydown(evt);
} }
}); });
addPointerlockchangeEventListener(updateUI); util.addPointerlockchangeEventListener(function() {
updateUI();
});
document.addEventListener("mousedown", function(event) { document.addEventListener("mousedown", function(event) {
if (activeScene != mouseScene && event.buttons == 1 && event.target.classList.contains("touch")) { if (activeScene != mouseScene && event.buttons == 1 && event.target.classList.contains("touch")) {
requestPointerLock(mouseScene); util.requestPointerLock(mouseScene);
} }
}); });
["touchstart", "touchend", "touchcancel", "touchmove"].forEach(function(type) { ["touchstart", "touchend", "touchcancel", "touchmove"].forEach(function(type) {
@ -628,8 +674,8 @@ window.addEventListener("load", function() {
evt.preventDefault(); evt.preventDefault();
}); });
}); });
mouseScene.addEventListener("mousedown", handleMousedown); mouseScene.addEventListener("mousedown", mouse.handleMousedown);
mouseScene.addEventListener("mouseup", handleMouseup); mouseScene.addEventListener("mouseup", mouse.handleMouseup);
mouseScene.addEventListener("mousemove", handleMousemove); mouseScene.addEventListener("mousemove", mouse.handleMousemove);
mouseScene.addEventListener("wheel", handleWheel); mouseScene.addEventListener("wheel", mouse.handleWheel);
}); });