You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
206 lines
5.9 KiB
206 lines
5.9 KiB
var statusElement = document.getElementById("status"); |
|
var progressElement = document.getElementById("progress"); |
|
var spinnerElement = document.getElementById("spinner"); |
|
|
|
var stdinBuffer = []; |
|
|
|
var terminal = $("#output").terminal( |
|
function(command) { |
|
// send command characters one by one, with 10ms interval, otherwise it will block for unknown reason |
|
const sendChar = () => { |
|
if (i < command.length) { |
|
stdinBuffer.push(command.charCodeAt(i)); |
|
i++; |
|
setTimeout(sendChar, 10); // 10ms |
|
} else { |
|
stdinBuffer.push(13); |
|
} |
|
} |
|
let i = 0; |
|
sendChar(); |
|
}, |
|
{ |
|
greetings: "", |
|
name: "js_demo", |
|
prompt: "[[;yellow;]> ]" |
|
} |
|
); |
|
|
|
var Module = { |
|
preRun: [ |
|
function() { |
|
var lastCh = null; |
|
|
|
function stdin() { |
|
var ch = stdinBuffer.shift(); |
|
if (ch !== undefined) { |
|
lastCh = ch; |
|
} else { |
|
// if no input then send 0, null, 0, null, ... to trick emscripten, |
|
// otherwise it will stop calling this function |
|
lastCh = lastCh === null ? 0 : null; |
|
} |
|
return lastCh; |
|
} |
|
|
|
FS.init(stdin); |
|
} |
|
], |
|
|
|
postRun: [], |
|
|
|
onRuntimeInitialized: function () { |
|
console.log("onRuntimeInitialized"); |
|
Module._init(); |
|
Module._startFlow(); |
|
|
|
const canvas = document.getElementById("canvas"); |
|
const ctx = canvas.getContext("2d"); |
|
|
|
const displayWidth = canvas.width; |
|
const displayHeight = canvas.height; |
|
|
|
let wheelDeltaY = 0; |
|
let wheelClicked = 0; |
|
let pointerEvents = []; |
|
|
|
const tick = () => { |
|
if (!Module._mainLoop()) { |
|
// flow is stopped |
|
return; |
|
} |
|
|
|
if (pointerEvents.length > 0) { |
|
for (let i = 0; i < pointerEvents.length; i++) { |
|
const pointerEvent = pointerEvents[i]; |
|
Module._onPointerEvent(pointerEvent.x, pointerEvent.y, pointerEvent.pressed); |
|
} |
|
pointerEvents = []; |
|
} |
|
|
|
if (wheelDeltaY != 0 || wheelClicked != 0) { |
|
Modulentime._onMouseWheelEvent(wheelDeltaY, wheelClicked); |
|
wheelDeltaY = 0; |
|
wheelClicked = 0; |
|
} |
|
|
|
var buf_addr = Module._getSyncedBuffer(); |
|
if (buf_addr != 0) { |
|
const screen = new Uint8ClampedArray(Module.HEAPU8.subarray(buf_addr, buf_addr + displayWidth * displayHeight *4)); |
|
var imgData = new ImageData(screen, displayWidth, displayHeight); |
|
ctx.putImageData(imgData, 0, 0, 0, 0, canvas.width, canvas.height); |
|
} |
|
|
|
window.requestAnimationFrame(tick); |
|
}; |
|
|
|
window.requestAnimationFrame(tick); |
|
|
|
function sendPointerEvent(event) { |
|
var bbox = canvas.getBoundingClientRect(); |
|
const x = (event.clientX - bbox.left) * (canvas.width / bbox.width); |
|
const y = (event.clientY - bbox.top) * (canvas.height / bbox.height); |
|
const pressed = event.buttons == 1 ? 1 : 0; |
|
pointerEvents.push({ x, y, pressed }); |
|
event.preventDefault(); |
|
event.stopPropagation(); |
|
} |
|
|
|
canvas.addEventListener("pointerdown", event => { |
|
if (event.buttons == 4) { |
|
wasmRuntime.wheelClicked = 1; |
|
} |
|
canvas.setPointerCapture(event.pointerId); |
|
sendPointerEvent(event); |
|
}, true); |
|
|
|
canvas.addEventListener("pointermove",event => { |
|
sendPointerEvent(event); |
|
}, true); |
|
|
|
canvas.addEventListener("pointerup",event => { |
|
canvas.releasePointerCapture(event.pointerId); |
|
sendPointerEvent(event); |
|
}, true); |
|
|
|
canvas.addEventListener("pointercancel",event => { |
|
canvas.releasePointerCapture(event.pointerId); |
|
sendPointerEvent(event); |
|
}, true); |
|
|
|
document.addEventListener("wheel", event => { |
|
wheelDeltaY += -event.deltaY; |
|
}, true); |
|
}, |
|
|
|
print: function(text) { |
|
if (arguments.length > 1) { |
|
text = Array.prototype.slice.call(arguments).join(" "); |
|
} |
|
|
|
console.log(text); |
|
|
|
if (text.startsWith("**ERROR")) { |
|
terminal.error(text); |
|
} else { |
|
terminal.echo(text); |
|
} |
|
}, |
|
|
|
printErr: function(text) { |
|
if (arguments.length > 1) { |
|
text = Array.prototype.slice.call(arguments).join(" "); |
|
} |
|
console.error(text); |
|
}, |
|
|
|
setStatus: function(text) { |
|
if (!Module.setStatus.last) |
|
Module.setStatus.last = { time: Date.now(), text: "" }; |
|
if (text === Module.setStatus.last.text) return; |
|
var m = text.match(/([^(]+)\((\d+(\.\d+)?)\/(\d+)\)/); |
|
var now = Date.now(); |
|
if (m && now - Module.setStatus.last.time < 30) return; // if this is a progress update, skip it if too soon |
|
Module.setStatus.last.time = now; |
|
Module.setStatus.last.text = text; |
|
if (m) { |
|
text = m[1]; |
|
progressElement.value = parseInt(m[2]) * 100; |
|
progressElement.max = parseInt(m[4]) * 100; |
|
progressElement.hidden = false; |
|
spinnerElement.hidden = false; |
|
} else { |
|
progressElement.value = null; |
|
progressElement.max = null; |
|
progressElement.hidden = true; |
|
if (!text) spinnerElement.style.display = "none"; |
|
} |
|
statusElement.innerHTML = text; |
|
}, |
|
|
|
totalDependencies: 0, |
|
|
|
monitorRunDependencies: function(left) { |
|
this.totalDependencies = Math.max(this.totalDependencies, left); |
|
Module.setStatus( |
|
left |
|
? "Preparing... (" + |
|
(this.totalDependencies - left) + |
|
"/" + |
|
this.totalDependencies + |
|
")" |
|
: "All downloads complete." |
|
); |
|
} |
|
}; |
|
|
|
Module.setStatus("Downloading..."); |
|
|
|
window.onerror = function(event) { |
|
// TODO: do not warn on ok events like simulating an infinite loop or exitStatus |
|
Module.setStatus("Exception thrown, see JavaScript console"); |
|
spinnerElement.style.display = "none"; |
|
Module.setStatus = function(text) { |
|
if (text) Module.printErr("[post-exception status] " + text); |
|
}; |
|
};
|
|
|