destroy event listeners when code is stopped, refactor away codestopper
This commit is contained in:
parent
eb04bc72d1
commit
809c272bd8
@ -1,9 +1,10 @@
|
|||||||
export class CodeRunner {
|
export class CodeRunner {
|
||||||
constructor(console, codeStopper) {
|
constructor(console, gamelib) {
|
||||||
this.console = console;
|
this.console = console;
|
||||||
this.codeStopper = codeStopper;
|
this.gamelib = gamelib;
|
||||||
this.isRunning = false;
|
this.isRunning = false;
|
||||||
this.evalScope = {};
|
this.evalScope = {};
|
||||||
|
this.abortController = new AbortController();
|
||||||
|
|
||||||
globalThis.playgroundConsole = this.console;
|
globalThis.playgroundConsole = this.console;
|
||||||
}
|
}
|
||||||
@ -14,12 +15,13 @@ export class CodeRunner {
|
|||||||
|
|
||||||
async run() {
|
async run() {
|
||||||
this.isRunning = true;
|
this.isRunning = true;
|
||||||
|
this.abortController = new AbortController();
|
||||||
|
|
||||||
|
this.gamelib.init();
|
||||||
|
|
||||||
this.console.clear();
|
this.console.clear();
|
||||||
this.console.log("Running code...");
|
this.console.log("Running code...");
|
||||||
|
|
||||||
this.codeStopper.start();
|
|
||||||
|
|
||||||
// Use RNG to prevent caching
|
// Use RNG to prevent caching
|
||||||
const encodedText = encodeURIComponent(
|
const encodedText = encodeURIComponent(
|
||||||
`let console=playgroundConsole;${this.code}/*(tph): ${Math.random()}*/`,
|
`let console=playgroundConsole;${this.code}/*(tph): ${Math.random()}*/`,
|
||||||
@ -35,7 +37,10 @@ export class CodeRunner {
|
|||||||
|
|
||||||
stop() {
|
stop() {
|
||||||
this.isRunning = false;
|
this.isRunning = false;
|
||||||
this.codeStopper.stop();
|
this.abortController.abort();
|
||||||
|
|
||||||
|
this.gamelib.destroy();
|
||||||
|
|
||||||
this.console.log("Stopping code...");
|
this.console.log("Stopping code...");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,24 +0,0 @@
|
|||||||
export class CodeStopper {
|
|
||||||
constructor() {
|
|
||||||
this.abortController = new AbortController();
|
|
||||||
}
|
|
||||||
|
|
||||||
start() {
|
|
||||||
this.abortController = new AbortController();
|
|
||||||
}
|
|
||||||
|
|
||||||
stop() {
|
|
||||||
this.abortController.abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
isStopped() {
|
|
||||||
return this.abortController.signal.aborted;
|
|
||||||
}
|
|
||||||
|
|
||||||
addListener(fn) {
|
|
||||||
this.abortController.signal
|
|
||||||
.addEventListener("abort", () => {
|
|
||||||
fn();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
130
src/gamelib.js
130
src/gamelib.js
@ -1,13 +1,5 @@
|
|||||||
export class Gamelib {
|
export class Gamelib {
|
||||||
keysPressed = new Set();
|
#loopInterval;
|
||||||
keyPressHandlers = new Map();
|
|
||||||
keyReleaseHandlers = new Map();
|
|
||||||
mouseMoveHandler = null;
|
|
||||||
mouseButtonsPressed = new Set();
|
|
||||||
mouseDownHandlers = new Map();
|
|
||||||
mouseUpHandlers = new Map();
|
|
||||||
mouseX = null;
|
|
||||||
mouseY = null;
|
|
||||||
|
|
||||||
MouseButton = {
|
MouseButton = {
|
||||||
Left: 0,
|
Left: 0,
|
||||||
@ -15,9 +7,8 @@ export class Gamelib {
|
|||||||
Middle: 2,
|
Middle: 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor(console, codeStopper, assetProvider, canvasElement) {
|
constructor(console, assetProvider, canvasElement) {
|
||||||
this.console = console;
|
this.console = console;
|
||||||
this.codeStopper = codeStopper;
|
|
||||||
this.assetProvider = assetProvider;
|
this.assetProvider = assetProvider;
|
||||||
|
|
||||||
this.canvas = canvasElement;
|
this.canvas = canvasElement;
|
||||||
@ -28,50 +19,37 @@ export class Gamelib {
|
|||||||
this.cx = this.canvas.getContext("2d");
|
this.cx = this.canvas.getContext("2d");
|
||||||
this.cx.imageSmootingEnabled = false;
|
this.cx.imageSmootingEnabled = false;
|
||||||
|
|
||||||
document.body.addEventListener("keydown", (ev) => {
|
this.keysPressed = new Set();
|
||||||
this.keysPressed.add(ev.key);
|
this.keyPressHandlers = new Map();
|
||||||
this.keyPressHandlers.get(ev.key)?.();
|
this.keyReleaseHandlers = new Map();
|
||||||
});
|
this.mouseMoveHandler = null;
|
||||||
|
this.mouseButtonsPressed = new Set();
|
||||||
|
this.mouseDownHandlers = new Map();
|
||||||
|
this.mouseUpHandlers = new Map();
|
||||||
|
this.mouseX = null;
|
||||||
|
this.mouseY = null;
|
||||||
|
}
|
||||||
|
|
||||||
document.body.addEventListener("keyup", (ev) => {
|
init() {
|
||||||
this.keysPressed.delete(ev.key);
|
document.body.addEventListener("keydown", this.#keydownListener.bind(this));
|
||||||
this.keyReleaseHandlers.get(ev.key)?.();
|
document.body.addEventListener("keyup", this.#keyupListener.bind(this));
|
||||||
});
|
|
||||||
|
|
||||||
canvasElement.addEventListener("mousemove", (ev) => {
|
this.canvas.addEventListener("mousemove", this.#mousemoveListener.bind(this));
|
||||||
const ratioX = canvasElement.width / canvasElement.clientWidth;
|
this.canvas.addEventListener("mousedown", this.#mousedownListener.bind(this));
|
||||||
const ratioY = canvasElement.height / canvasElement.clientHeight;
|
this.canvas.addEventListener("mouseup", this.#mouseupListener.bind(this));
|
||||||
|
this.canvas.addEventListener("contextmenu", this.#contextMenuListener.bind(this));
|
||||||
|
}
|
||||||
|
|
||||||
this.mouseX = ev.offsetX * ratioX;
|
destroy() {
|
||||||
this.mouseY = ev.offsetY * ratioY;
|
document.body.removeEventListener("keydown", this.#keydownListener);
|
||||||
|
document.body.removeEventListener("keyup", this.#keyupListener);
|
||||||
|
|
||||||
this.mouseMoveHandler?.(
|
this.canvas.removeEventListener("mousemove", this.#mousemoveListener);
|
||||||
ev.offsetX * ratioX,
|
this.canvas.removeEventListener("mousedown", this.#mousedownListener);
|
||||||
ev.offsetY * ratioY,
|
this.canvas.removeEventListener("mouseup", this.#mouseupListener);
|
||||||
ev.movementX * ratioX,
|
this.canvas.removeEventListener("contextmenu", this.#contextMenuListener);
|
||||||
ev.movementY * ratioY,
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
canvasElement.addEventListener("mousedown", (ev) => {
|
clearInterval(this.#loopInterval);
|
||||||
const ratioX = canvasElement.width / canvasElement.clientWidth;
|
|
||||||
const ratioY = canvasElement.height / canvasElement.clientHeight;
|
|
||||||
|
|
||||||
this.mouseButtonsPressed.add(ev.button);
|
|
||||||
this.mouseDownHandlers.get(ev.button)?.(ev.offsetX * ratioX, ev.offsetY * ratioY);
|
|
||||||
});
|
|
||||||
|
|
||||||
canvasElement.addEventListener("mouseup", (ev) => {
|
|
||||||
const ratioX = canvasElement.width / canvasElement.clientWidth;
|
|
||||||
const ratioY = canvasElement.height / canvasElement.clientHeight;
|
|
||||||
|
|
||||||
this.mouseButtonsPressed.delete(ev.button);
|
|
||||||
this.mouseUpHandlers.get(ev.button)?.(ev.offsetX * ratioX, ev.offsetY * ratioY);
|
|
||||||
});
|
|
||||||
|
|
||||||
canvasElement.addEventListener("contextmenu", (ev) => {
|
|
||||||
ev.preventDefault();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
println(msg) {
|
println(msg) {
|
||||||
@ -80,7 +58,8 @@ export class Gamelib {
|
|||||||
|
|
||||||
startGameLoop(loopFunction) {
|
startGameLoop(loopFunction) {
|
||||||
let before = Date.now();
|
let before = Date.now();
|
||||||
const loopInterval = setInterval(() => {
|
|
||||||
|
this.#loopInterval = setInterval(() => {
|
||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
const deltaT = (now - before) / 1000;
|
const deltaT = (now - before) / 1000;
|
||||||
before = now;
|
before = now;
|
||||||
@ -90,14 +69,16 @@ export class Gamelib {
|
|||||||
this.console.error(error);
|
this.console.error(error);
|
||||||
}
|
}
|
||||||
}, 16);
|
}, 16);
|
||||||
|
}
|
||||||
|
|
||||||
if (this.codeStopper?.isStopped()) {
|
#keydownListener(ev) {
|
||||||
clearInterval(loopInterval);
|
this.keysPressed.add(ev.key);
|
||||||
}
|
this.keyPressHandlers.get(ev.key)?.();
|
||||||
|
}
|
||||||
|
|
||||||
this.codeStopper?.addListener(() => {
|
#keyupListener(ev) {
|
||||||
clearInterval(loopInterval);
|
this.keysPressed.delete(ev.key);
|
||||||
});
|
this.keyReleaseHandlers.get(ev.key)?.();
|
||||||
}
|
}
|
||||||
|
|
||||||
isPressed(key) {
|
isPressed(key) {
|
||||||
@ -112,6 +93,37 @@ export class Gamelib {
|
|||||||
this.keyReleaseHandlers.set(key, handlerFunction);
|
this.keyReleaseHandlers.set(key, handlerFunction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#mousemoveListener(ev) {
|
||||||
|
const ratioX = this.canvas.width / this.canvas.clientWidth;
|
||||||
|
const ratioY = this.canvas.height / this.canvas.clientHeight;
|
||||||
|
|
||||||
|
this.mouseX = ev.offsetX * ratioX;
|
||||||
|
this.mouseY = ev.offsetY * ratioY;
|
||||||
|
|
||||||
|
this.mouseMoveHandler?.(
|
||||||
|
ev.offsetX * ratioX,
|
||||||
|
ev.offsetY * ratioY,
|
||||||
|
ev.movementX * ratioX,
|
||||||
|
ev.movementY * ratioY,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#mousedownListener(ev) {
|
||||||
|
const ratioX = this.canvas.width / this.canvas.clientWidth;
|
||||||
|
const ratioY = this.canvas.height / this.canvas.clientHeight;
|
||||||
|
|
||||||
|
this.mouseButtonsPressed.add(ev.button);
|
||||||
|
this.mouseDownHandlers.get(ev.button)?.(ev.offsetX * ratioX, ev.offsetY * ratioY);
|
||||||
|
}
|
||||||
|
|
||||||
|
#mouseupListener(ev) {
|
||||||
|
const ratioX = this.canvas.width / this.canvas.clientWidth;
|
||||||
|
const ratioY = this.canvas.height / this.canvas.clientHeight;
|
||||||
|
|
||||||
|
this.mouseButtonsPressed.delete(ev.button);
|
||||||
|
this.mouseUpHandlers.get(ev.button)?.(ev.offsetX * ratioX, ev.offsetY * ratioY);
|
||||||
|
}
|
||||||
|
|
||||||
onMouseMove(handlerFunction) {
|
onMouseMove(handlerFunction) {
|
||||||
this.mouseMoveHandler = handlerFunction;
|
this.mouseMoveHandler = handlerFunction;
|
||||||
}
|
}
|
||||||
@ -128,6 +140,10 @@ export class Gamelib {
|
|||||||
this.mouseUpHandlers.set(button, handlerFunction);
|
this.mouseUpHandlers.set(button, handlerFunction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#contextMenuListener(ev) {
|
||||||
|
ev.preventDefault();
|
||||||
|
}
|
||||||
|
|
||||||
rgb(red, green, blue) {
|
rgb(red, green, blue) {
|
||||||
return `rgb(${red}, ${green}, ${blue})`;
|
return `rgb(${red}, ${green}, ${blue})`;
|
||||||
}
|
}
|
||||||
|
11
src/index.js
11
src/index.js
@ -6,7 +6,6 @@ import { CodeRunner } from "./code_runner.js";
|
|||||||
import { AssetEditor } from "./asset_editor.js";
|
import { AssetEditor } from "./asset_editor.js";
|
||||||
import { AssetProvider } from "./asset_provider.js";
|
import { AssetProvider } from "./asset_provider.js";
|
||||||
import { Gamelib } from "./gamelib.js";
|
import { Gamelib } from "./gamelib.js";
|
||||||
import { CodeStopper } from "./code_stopper.js";
|
|
||||||
import { KarlkoderCodec } from "./karlkoder_codec.js";
|
import { KarlkoderCodec } from "./karlkoder_codec.js";
|
||||||
import { promptUpload } from "./prompt_upload.js";
|
import { promptUpload } from "./prompt_upload.js";
|
||||||
import { GamelibCompleter } from "./gamelib_completer.js";
|
import { GamelibCompleter } from "./gamelib_completer.js";
|
||||||
@ -40,20 +39,14 @@ addEventListener("DOMContentLoaded", () => {
|
|||||||
playgroundConsole.getInterface().log("Karlkode 1.0");
|
playgroundConsole.getInterface().log("Karlkode 1.0");
|
||||||
});
|
});
|
||||||
|
|
||||||
const codeStopper = new CodeStopper();
|
|
||||||
|
|
||||||
const assetProvider = new AssetProvider();
|
const assetProvider = new AssetProvider();
|
||||||
|
|
||||||
const codeRunner = new CodeRunner(playgroundConsole.getInterface(), codeStopper);
|
|
||||||
const assetEditor = new AssetEditor(document.querySelector("#asset-editor-container"), []);
|
const assetEditor = new AssetEditor(document.querySelector("#asset-editor-container"), []);
|
||||||
|
|
||||||
new ConsoleInput(document.querySelector("#console-input"), playgroundConsole, codeRunner);
|
|
||||||
|
|
||||||
const htmlExporter = new HtmlExporter(assetProvider);
|
const htmlExporter = new HtmlExporter(assetProvider);
|
||||||
|
|
||||||
const gamelib = new Gamelib(
|
const gamelib = new Gamelib(
|
||||||
playgroundConsole.getInterface(),
|
playgroundConsole.getInterface(),
|
||||||
codeStopper,
|
|
||||||
assetProvider,
|
assetProvider,
|
||||||
document.querySelector("canvas"),
|
document.querySelector("canvas"),
|
||||||
);
|
);
|
||||||
@ -64,6 +57,10 @@ globalThis.karlkoder = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const codeRunner = new CodeRunner(playgroundConsole.getInterface(), gamelib);
|
||||||
|
|
||||||
|
new ConsoleInput(document.querySelector("#console-input"), playgroundConsole, codeRunner);
|
||||||
|
|
||||||
const runButton = document.querySelector("#run-button");
|
const runButton = document.querySelector("#run-button");
|
||||||
const toggleAssetEditorButton = document.querySelector("#toggle-asset-editor-button");
|
const toggleAssetEditorButton = document.querySelector("#toggle-asset-editor-button");
|
||||||
const projectName = document.querySelector("#project-name");
|
const projectName = document.querySelector("#project-name");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user