summaryrefslogtreecommitdiff
path: root/src/engine/systems/Modal.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/engine/systems/Modal.ts')
-rw-r--r--src/engine/systems/Modal.ts93
1 files changed, 93 insertions, 0 deletions
diff --git a/src/engine/systems/Modal.ts b/src/engine/systems/Modal.ts
new file mode 100644
index 0000000..7643a73
--- /dev/null
+++ b/src/engine/systems/Modal.ts
@@ -0,0 +1,93 @@
+import { Game } from "..";
+import { System, SystemNames } from ".";
+import { Miscellaneous, ModalClose, ModalOpen, SOUNDS } from "../config";
+import { ComponentNames, Modal as ModalComponent } from "../components";
+import { Entity } from "../entities";
+import {
+ CodeConsumer,
+ CodeEditorInstance,
+ CodeEditorSingleton,
+ ModalInstance,
+ ModalSingleton,
+} from "../utils";
+
+export interface ModalInitState {
+ type: "CONTENT" | "CODE_EDITOR";
+ contentInit?: {
+ content: string;
+ };
+ codeInit?: {
+ code: string;
+ codeConsumer: CodeConsumer;
+ readonly?: boolean;
+ result?: { data?: string; error?: string };
+ };
+}
+
+export class Modal extends System {
+ private openingEntity: null | Entity = null;
+ private modalInstance: ModalInstance = ModalSingleton;
+ private codeEditorInstance: CodeEditorInstance = CodeEditorSingleton;
+
+ constructor() {
+ super(SystemNames.Modal);
+ }
+
+ public update(_dt: number, game: Game) {
+ if (this.openingEntity) {
+ if (this.openingEntity.hasComponent(ComponentNames.Modal)) {
+ return;
+ }
+ this.closeCallback();
+ }
+
+ game.forEachEntityWithComponent(ComponentNames.Modal, (entity) => {
+ const modalComponent = entity.getComponent<ModalComponent>(
+ ComponentNames.Modal
+ );
+ if (this.openingEntity) {
+ return;
+ }
+
+ this.openingEntity = entity;
+ SOUNDS.get(ModalOpen.name)!.play();
+
+ if (modalComponent.initState.type === "CONTENT") {
+ const content = `
+ <div style="text-align:center">
+ <div>${modalComponent.initState.contentInit!.content}</div>
+ <br>
+ <button id="close">Close</button>
+ </div>`;
+ this.modalInstance.open(content);
+ document
+ .getElementById("close")
+ ?.addEventListener("click", this.closeCallback.bind(this));
+ }
+
+ if (modalComponent.initState.type === "CODE_EDITOR") {
+ this.codeEditorInstance.open(
+ modalComponent.initState.codeInit!.code,
+ (code) => {
+ const result =
+ modalComponent.initState.codeInit!.codeConsumer(code);
+ if (result.consumed) {
+ this.closeCallback();
+ }
+ return result;
+ },
+ !!modalComponent.initState.codeInit!.readonly,
+ modalComponent.initState.codeInit!.result,
+ );
+ }
+ });
+ }
+
+ private closeCallback() {
+ this.openingEntity = null;
+ this.modalInstance.vanish();
+ this.codeEditorInstance.close();
+ document.getElementById(Miscellaneous.CANVAS_ID)!.focus();
+ SOUNDS.get(ModalClose.name)!.play();
+ }
+}