From 9c13a555be09f77d70378dc170b8a4a7094aea1e Mon Sep 17 00:00:00 2001 From: rei1024 Date: Mon, 30 Sep 2024 21:02:42 +0900 Subject: [PATCH] refactor: setRLE --- index.html | 10 +++++++++- src/main.ts | 27 +++++++++------------------ src/setRLE.ts | 20 ++++++++++++++++++++ src/style.css | 4 ++++ 4 files changed, 42 insertions(+), 19 deletions(-) create mode 100644 src/setRLE.ts diff --git a/index.html b/index.html index 4297920..4d0b558 100644 --- a/index.html +++ b/index.html @@ -32,9 +32,17 @@

Input

>
- +
+

diff --git a/src/main.ts b/src/main.ts index fb2f3b4..464b6db 100644 --- a/src/main.ts +++ b/src/main.ts @@ -4,7 +4,7 @@ import { Engine, Vector3 } from "babylonjs"; import { BitWorld } from "@ca-ts/algo/bit"; import { setupArcRotateCamera } from "./camera"; import { createTemplateCell } from "./cell"; -import { parseRLE } from "@ca-ts/rle"; +import { setRLE } from "./setRLE"; const WORLD_SIZE = 32 * 2; let historySize = 16; @@ -148,25 +148,16 @@ configButton.addEventListener("click", () => { }); const readRLE = document.getElementById("readRLE") as HTMLElement; +const rleErrorMessage = document.getElementById("rleError") as HTMLElement; +const inputRLE = document.getElementById("inputRLE") as HTMLTextAreaElement; readRLE.addEventListener("click", () => { - const inputRLE = document.getElementById("inputRLE") as HTMLTextAreaElement; - const data = parseRLE(inputRLE.value); clearCell(); - - const centerX = - Math.floor(bitWorld.getWidth() / 2) - - Math.floor((data.size?.width ?? 0) / 2); - const centerY = - Math.floor(bitWorld.getHeight() / 2) - - Math.floor((data.size?.height ?? 0) / 2); - for (const { - position: { x, y }, - state, - } of data.cells) { - if (state === 1) { - bitWorld.set(x + centerX, y + centerY); - } + rleErrorMessage.textContent = null; + try { + setRLE(bitWorld, inputRLE.value); + } catch (error) { + rleErrorMessage.textContent = "Invalid RLE or oversized"; + throw error; } - settingsDialog.close(); }); diff --git a/src/setRLE.ts b/src/setRLE.ts new file mode 100644 index 0000000..c1b3506 --- /dev/null +++ b/src/setRLE.ts @@ -0,0 +1,20 @@ +import type { BitWorld } from "@ca-ts/algo/bit"; +import { parseRLE } from "@ca-ts/rle"; + +export function setRLE(bitWorld: BitWorld, sourceRLE: string) { + const data = parseRLE(sourceRLE); + + const width = data.size?.width ?? 0; + const height = data.size?.height ?? 0; + + const centerX = Math.floor(bitWorld.getWidth() / 2) - Math.floor(width / 2); + const centerY = Math.floor(bitWorld.getHeight() / 2) - Math.floor(height / 2); + for (const { + position: { x, y }, + state, + } of data.cells) { + if (state === 1) { + bitWorld.set(x + centerX, y + centerY); + } + } +} diff --git a/src/style.css b/src/style.css index e527d04..b6e5153 100644 --- a/src/style.css +++ b/src/style.css @@ -82,3 +82,7 @@ dialog button.btn:focus { outline: none; /* デフォルトのアウトラインを消す */ box-shadow: 0 0 0 3px rgba(0, 0, 0, 0.5); /* フォーカス時のシャドウ */ } + +#rleError { + color: #dc2626; /* red-600 */ +}