The Konilo interpreter execs byte code in a loop. The Javascript VM cannot do anything else while this loop is running unfortunately, so the browser is unresponsive until all bytecode has executed.
The modification below adds an artificial sleep()
function that allows the event loop
to catch its breath and service event handlers (eg: UI clicks, form interaction, unrelated AJAX calls, etc...)
The EVENT_LOOP_PAUSE_TICKS
variable will need to be tuned to find a balance between initial load speed and UI
responsiveness.
Other ideas:
- Use an HTML gauge element to show loading progress when loading initial image.
- Use different tick sizes on initial load vs. program runtime.
async function sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
async function execute() {
input = " " + document.getElementById("input").value + " \n";
/*
|Ticks |Load Time | Blockage |
|------|----------|-----------------|
| 100 | 23,019ms | Not-Blocked |
| 200 | 21,927ms | Not-blocked |
| 350 | 6,438ms | Not-Blocked | <= Too slow
| 425 | 22,334ms | Not blocked | <= Anomaly (??)
| 500 | 3,746ms | Not-Blocked | <= Perfect?
| 550 | 1,980ms | Slight blockage | <= Too fast.
| 600 | 1,996ms | Slight blockage |
| 700 | 1,932ms | blocked |
| 1000 | 1,954ms | Blocked |
*/
// Tune this value to find a balance between speed and
// event loop blockage.
const EVENT_LOOP_PAUSE_TICKS = 500; // TODO: tune this.
while (input.length >= 1 && !isNaN(ip)) {
var o = m[ip];
process(o & 0xff);
process((o >> 8) & 0xff);
process((o >> 16) & 0xff);
process((o >> 24) & 0xff);
ip = ip + 1;
if (ip % EVENT_LOOP_PAUSE_TICKS === 0) {
await sleep(0);
}
}
document.getElementById("input").value = "";
console.log("done");
document.getElementById("display").scrollTop =
document.getElementById("display").scrollHeight;
}