mirror of
https://github.com/codeninjasuk/game-freddies-adventure.git
synced 2024-12-02 20:26:56 -05:00
169 lines
4.8 KiB
JavaScript
169 lines
4.8 KiB
JavaScript
|
var channelHandlers = {}
|
||
|
|
||
|
function addSimMessageHandler(channel, handler) {
|
||
|
channelHandlers[channel] = handler;
|
||
|
}
|
||
|
|
||
|
function makeCodeRun(options) {
|
||
|
var code = "";
|
||
|
var isReady = false;
|
||
|
var simState = {}
|
||
|
var simStateChanged = false
|
||
|
var started = false;
|
||
|
var meta = undefined;
|
||
|
|
||
|
// hide scrollbar
|
||
|
window.scrollTo(0, 1);
|
||
|
// init runtime
|
||
|
initSimState();
|
||
|
fetchCode();
|
||
|
|
||
|
// helpers
|
||
|
function fetchCode() {
|
||
|
sendReq(options.js, function (c, status) {
|
||
|
if (status != 200)
|
||
|
return;
|
||
|
code = c;
|
||
|
// find metadata
|
||
|
code.replace(/^\/\/\s+meta=([^\n]+)\n/m, function (m, metasrc) {
|
||
|
meta = JSON.parse(metasrc);
|
||
|
})
|
||
|
var vel = document.getElementById("version");
|
||
|
if (meta.version && meta.repo && vel) {
|
||
|
var ap = document.createElement("a");
|
||
|
ap.download = "arcade.uf2";
|
||
|
ap.href = "https://github.com/" + meta.repo + "/releases/download/v" + meta.version + "/arcade.uf2";
|
||
|
ap.innerText = "v" + meta.version;
|
||
|
vel.appendChild(ap);
|
||
|
}
|
||
|
// load simulator with correct version
|
||
|
document.getElementById("simframe")
|
||
|
.setAttribute("src", meta.simUrl);
|
||
|
initFullScreen();
|
||
|
})
|
||
|
}
|
||
|
|
||
|
function startSim() {
|
||
|
if (!code || !isReady || started)
|
||
|
return
|
||
|
setState("run");
|
||
|
started = true;
|
||
|
const runMsg = {
|
||
|
type: "run",
|
||
|
parts: [],
|
||
|
code: code,
|
||
|
partDefinitions: {},
|
||
|
cdnUrl: meta.cdnUrl,
|
||
|
version: meta.target,
|
||
|
storedState: simState,
|
||
|
frameCounter: 1,
|
||
|
options: {
|
||
|
"theme": "green",
|
||
|
"player": ""
|
||
|
},
|
||
|
id: "green-" + Math.random()
|
||
|
}
|
||
|
postMessage(runMsg);
|
||
|
}
|
||
|
|
||
|
function stopSim() {
|
||
|
setState("stopped");
|
||
|
postMessage({
|
||
|
type: "stop"
|
||
|
});
|
||
|
started = false;
|
||
|
}
|
||
|
|
||
|
window.addEventListener('message', function (ev) {
|
||
|
var d = ev.data
|
||
|
if (d.type == "ready") {
|
||
|
var loader = document.getElementById("loader");
|
||
|
if (loader)
|
||
|
loader.remove();
|
||
|
isReady = true;
|
||
|
startSim();
|
||
|
} else if (d.type == "simulator") {
|
||
|
switch (d.command) {
|
||
|
case "restart":
|
||
|
stopSim();
|
||
|
startSim();
|
||
|
break;
|
||
|
case "setstate":
|
||
|
if (d.stateValue === null)
|
||
|
delete simState[d.stateKey];
|
||
|
else
|
||
|
simState[d.stateKey] = d.stateValue;
|
||
|
simStateChanged = true;
|
||
|
break;
|
||
|
}
|
||
|
} else if (d.type === "messagepacket" && d.channel) {
|
||
|
const handler = channelHandlers[d.channel]
|
||
|
if (handler) {
|
||
|
try {
|
||
|
const buf = d.data;
|
||
|
const str = uint8ArrayToString(buf);
|
||
|
const data = JSON.parse(str)
|
||
|
handler(data);
|
||
|
} catch (e) {
|
||
|
console.log(`invalid simmessage`)
|
||
|
console.log(e)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}, false);
|
||
|
|
||
|
// helpers
|
||
|
function uint8ArrayToString(input) {
|
||
|
let len = input.length;
|
||
|
let res = ""
|
||
|
for (let i = 0; i < len; ++i)
|
||
|
res += String.fromCharCode(input[i]);
|
||
|
return res;
|
||
|
}
|
||
|
|
||
|
function setState(st) {
|
||
|
var r = document.getElementById("root");
|
||
|
if (r)
|
||
|
r.setAttribute("data-state", st);
|
||
|
}
|
||
|
|
||
|
function postMessage(msg) {
|
||
|
const frame = document.getElementById("simframe");
|
||
|
if (frame)
|
||
|
frame.contentWindow.postMessage(msg, meta.simUrl);
|
||
|
}
|
||
|
|
||
|
function sendReq(url, cb) {
|
||
|
var xhttp = new XMLHttpRequest();
|
||
|
xhttp.onreadystatechange = function () {
|
||
|
if (xhttp.readyState == 4) {
|
||
|
cb(xhttp.responseText, xhttp.status)
|
||
|
}
|
||
|
};
|
||
|
xhttp.open("GET", url, true);
|
||
|
xhttp.send();
|
||
|
}
|
||
|
|
||
|
function initSimState() {
|
||
|
try {
|
||
|
simState = JSON.parse(localStorage["simstate"])
|
||
|
} catch (e) {
|
||
|
simState = {}
|
||
|
}
|
||
|
setInterval(function () {
|
||
|
if (simStateChanged)
|
||
|
localStorage["simstate"] = JSON.stringify(simState)
|
||
|
simStateChanged = false
|
||
|
}, 200)
|
||
|
}
|
||
|
|
||
|
function initFullScreen() {
|
||
|
var sim = document.getElementById("simframe");
|
||
|
var fs = document.getElementById("fullscreen");
|
||
|
if (fs && sim.requestFullscreen) {
|
||
|
fs.onclick = function() { sim.requestFullscreen(); }
|
||
|
} else if (fs) {
|
||
|
fs.remove();
|
||
|
}
|
||
|
}
|
||
|
}
|