From 8f8923f4d94e0c18186987d551730e3dd5f1fe0d Mon Sep 17 00:00:00 2001 From: Exelo Date: Mon, 17 Mar 2025 15:12:05 +0100 Subject: [PATCH 1/5] feat: add wgsl handling (#3) --- apps/web/src/loader/loader.ts | 7 +++++-- apps/web/src/types/game.type.ts | 3 ++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/apps/web/src/loader/loader.ts b/apps/web/src/loader/loader.ts index 937d220..d8efecb 100644 --- a/apps/web/src/loader/loader.ts +++ b/apps/web/src/loader/loader.ts @@ -10,7 +10,8 @@ export const loadGameFiles = async ( ): Promise<[IGameOptions["files"], any]> => { const files = { assets: new Map(), - scripts: new Map(), + wasm: new Map(), + wgsl: new Map(), }; let mainModule = undefined; logger.info("Starting load game files from cache"); @@ -21,7 +22,9 @@ export const loadGameFiles = async ( continue; } if (file.path.endsWith(".wasm")) { - files.scripts.set(file.path, file.localPath); + files.wasm.set(file.path, file.localPath); + } else if (file.path.endsWith(".wgsl")) { + files.wgsl.set(file.path, file.localPath); } else { files.assets.set(file.path, file.localPath); } diff --git a/apps/web/src/types/game.type.ts b/apps/web/src/types/game.type.ts index 757c453..2cb5425 100644 --- a/apps/web/src/types/game.type.ts +++ b/apps/web/src/types/game.type.ts @@ -2,6 +2,7 @@ export interface IGameOptions { canvas: HTMLCanvasElement; files: { assets: Map; - scripts: Map; + wasm: Map; + wgsl: Map; }; } From 3bb3c00f1bf7f658852e2541f3a8bcd17b970ecc Mon Sep 17 00:00:00 2001 From: MartinFillon Date: Mon, 17 Mar 2025 15:47:39 +0100 Subject: [PATCH 2/5] ci: add basic ci using bun instead of pnpm --- .github/workflows/tests.yml | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 .github/workflows/tests.yml diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 0000000..13d905c --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,37 @@ +name: Tests + +on: + pull_request: + branches: + - master + - dev + workflow_dispatch: + +env: + EM_CACHE_FOLDER: "emsdk-cache" + +jobs: + tests: + runs-on: ubuntu-latest + steps: + - name: "Checkout" + uses: actions/checkout@v2 + with: + fetch-depth: 0 + + - name: "Setup node" + uses: actions/setup-node@v2 + with: + node-version: "23.6.0" + + - name: "Setup bun" + uses: oven-sh/setup-bun@v2 + + - name: "Install dependencies" + run: bun install + + - name: "Run tests" + run: bun lerna run test:unit + + - name: "Run linter" + run: bun lerna run lint From 9c09420cd5871ed345aa6936a6df1a0593d3fbbd Mon Sep 17 00:00:00 2001 From: MartinFillon Date: Mon, 17 Mar 2025 16:06:33 +0100 Subject: [PATCH 3/5] ci: branch was named master instead of main --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 13d905c..8f93744 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -3,7 +3,7 @@ name: Tests on: pull_request: branches: - - master + - main - dev workflow_dispatch: From af087fdcc9c512a754aa319f8dea8ec90231c921 Mon Sep 17 00:00:00 2001 From: Bill Date: Thu, 13 Mar 2025 15:47:56 +0100 Subject: [PATCH 4/5] feat: create front loader --- apps/web/src/assets/logo.png | Bin 0 -> 20534 bytes apps/web/src/cache/cache.ts | 8 ++--- apps/web/src/ids.ts | 1 + apps/web/src/index.html | 10 ++++-- apps/web/src/style.css | 49 ++++++++++++++++++++++++++++++ apps/web/src/utils/delay.utils.ts | 1 + apps/web/src/window.ts | 28 +++++++++++++---- 7 files changed, 85 insertions(+), 12 deletions(-) create mode 100644 apps/web/src/assets/logo.png create mode 100644 apps/web/src/style.css create mode 100644 apps/web/src/utils/delay.utils.ts diff --git a/apps/web/src/assets/logo.png b/apps/web/src/assets/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..35b9d5be6b36f66aa9fef62c73ab51a2331c2d22 GIT binary patch literal 20534 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 { const res = []; - for (const file of files) { + setLoadingTotalFiles(files.length); + for (const [i, file] of files.entries()) { + setLoadingStatus(file.path, i); res.push(await this._updateCacheFile(file)); } return res; } private async _updateCacheFile(fileManifest: IManifestFile): Promise { - setLoadingStatus(`Fetching ${fileManifest.path}`); - const res = await fetch(`${env.PUBLIC_BASE_SERVER_URL}/game/${fileManifest.path}`); const file = await this.fs.getFile(fileManifest.path); diff --git a/apps/web/src/ids.ts b/apps/web/src/ids.ts index 22dc405..e7f1280 100644 --- a/apps/web/src/ids.ts +++ b/apps/web/src/ids.ts @@ -2,4 +2,5 @@ export const IDS = { canvas: "nanoforge-canvas", loader: "nanoforge-loader", loaderStatus: "nanoforge-loader-status", + loadingBar: "loading-bar-fill", }; diff --git a/apps/web/src/index.html b/apps/web/src/index.html index 16f4b35..e27da8f 100644 --- a/apps/web/src/index.html +++ b/apps/web/src/index.html @@ -2,13 +2,19 @@ + Title

-
Loading...
-
+ +
+
+
+
+
+
new Promise((resolve) => setTimeout(resolve, ms)); diff --git a/apps/web/src/window.ts b/apps/web/src/window.ts index 722a81a..18f1db4 100644 --- a/apps/web/src/window.ts +++ b/apps/web/src/window.ts @@ -1,22 +1,38 @@ import { IDS } from "./ids"; -import { getElementById, setHiddenStatusOnId } from "./utils/document.utils"; +import { delay } from "./utils/delay.utils"; +import { setHiddenStatusOnId } from "./utils/document.utils"; import { Logger } from "./utils/logger.utils"; const logger: Logger = new Logger("Window"); +let totalFiles = 0; -export const changeWindowToGame = () => { +export const changeWindowToGame = async () => { setHiddenStatusOnId(IDS.loader, true); setHiddenStatusOnId(IDS.canvas, false); + await delay(500); + const loader = document.getElementById(IDS.loader); + if (loader) loader.classList.add("fade-out"); logger.info("Change window to game"); }; -export const changeWindowToLoader = () => { +export const changeWindowToLoader = async () => { setHiddenStatusOnId(IDS.canvas, true); setHiddenStatusOnId(IDS.loader, false); logger.info("Change window to loader"); }; -export const setLoadingStatus = (text: string) => { - const el = getElementById(IDS.loaderStatus); - el.innerText = text; +export const setLoadingStatus = (filename: string, index?: number | null) => { + const loaderFilename = document.getElementById(IDS.loaderStatus); + const loadingBarFill = document.getElementById(IDS.loadingBar); + + if (loaderFilename) loaderFilename.innerText = filename; + + if (loadingBarFill && index && totalFiles > 0) { + const progress = ((index + 1) / totalFiles) * 100; + loadingBarFill.style.width = `${progress}%`; + } +}; + +export const setLoadingTotalFiles = (total: number) => { + totalFiles = total; }; From 1b349e9ff637266a22d12ca425f37f3e6735b422 Mon Sep 17 00:00:00 2001 From: Bill Date: Fri, 14 Mar 2025 15:18:28 +0100 Subject: [PATCH 5/5] feat(web): create html error handling --- apps/web/src/cache/cache.ts | 2 +- apps/web/src/ids.ts | 7 ++++++- apps/web/src/index.html | 14 ++++++++++---- apps/web/src/index.ts | 4 ++++ apps/web/src/style.css | 29 ++++++++++++++++++++++++++++- apps/web/src/window.ts | 12 +++++++++++- 6 files changed, 60 insertions(+), 8 deletions(-) diff --git a/apps/web/src/cache/cache.ts b/apps/web/src/cache/cache.ts index 63aad43..fa11b0b 100644 --- a/apps/web/src/cache/cache.ts +++ b/apps/web/src/cache/cache.ts @@ -38,7 +38,7 @@ export class GameCache { const res = []; setLoadingTotalFiles(files.length); for (const [i, file] of files.entries()) { - setLoadingStatus(file.path, i); + setLoadingStatus(`Download: ${file.path.replace(/^\/+/, "")}`, i); res.push(await this._updateCacheFile(file)); } return res; diff --git a/apps/web/src/ids.ts b/apps/web/src/ids.ts index e7f1280..bea4561 100644 --- a/apps/web/src/ids.ts +++ b/apps/web/src/ids.ts @@ -1,6 +1,11 @@ export const IDS = { canvas: "nanoforge-canvas", loader: "nanoforge-loader", - loaderStatus: "nanoforge-loader-status", + + loadingStatus: "loading-status", + loadingStep: "loading-step", loadingBar: "loading-bar-fill", + + loaderError: "loader-error", + loaderErrorMessage: "loader-error-message", }; diff --git a/apps/web/src/index.html b/apps/web/src/index.html index e27da8f..bc65100 100644 --- a/apps/web/src/index.html +++ b/apps/web/src/index.html @@ -9,10 +9,16 @@
-
-
-
-
+
+ +
+
+
+
+
diff --git a/apps/web/src/index.ts b/apps/web/src/index.ts index c2fd8d5..38b281b 100644 --- a/apps/web/src/index.ts +++ b/apps/web/src/index.ts @@ -3,15 +3,18 @@ import { runGame } from "./game"; import { loadGameFiles } from "./loader"; import { getManifest } from "./manifest"; import { Logger } from "./utils/logger.utils"; +import { setError, setLoadingStatus } from "./window"; const logger = new Logger("Loader"); const runLoad = async () => { logger.info("Starting loading game"); + const manifest = await getManifest(); const cache = new GameCache(); const extendedManifest = await cache.updateCache(manifest, true); const [files, mainModule] = await loadGameFiles(extendedManifest); + setLoadingStatus("Starting game"); runGame(mainModule, { files }); }; @@ -20,5 +23,6 @@ runLoad() logger.info("Game loaded !"); }) .catch((e) => { + setError(e); logger.error(`Failed to load game : ${e}`); }); diff --git a/apps/web/src/style.css b/apps/web/src/style.css index 88a9754..3b45b39 100644 --- a/apps/web/src/style.css +++ b/apps/web/src/style.css @@ -4,6 +4,7 @@ left: 0; top: 0; background-color: oklch(0.21 0.034 264.665); + font-weight: bold; color: white; position: absolute; display: flex; @@ -18,7 +19,7 @@ width: 125px; } -#loading-progress { +#loading-status { width: 100%; display: flex; flex-direction: column; @@ -26,6 +27,10 @@ gap: 10px; } +#loading-status[hidden] { + display: none !important; +} + #loading-bar { height: 12px; width: 500px; @@ -42,6 +47,28 @@ transition: width 0.3s ease-in-out; } +#loader-error { + width: 100%; + display: flex; + flex-direction: column; + align-items: center; + gap: 10px; +} + +#loader-error[hidden] { + display: none !important; +} + +#back-home { + background-color: rgba(151, 63, 255, 0.8); + text-decoration: none; + border-radius: 5px; + font-weight: bold; + font-size: large; + color: white; + padding: 10px; +} + .fade-out { opacity: 0; transition: opacity 1s ease-out; diff --git a/apps/web/src/window.ts b/apps/web/src/window.ts index 18f1db4..9a2b0cc 100644 --- a/apps/web/src/window.ts +++ b/apps/web/src/window.ts @@ -22,7 +22,7 @@ export const changeWindowToLoader = async () => { }; export const setLoadingStatus = (filename: string, index?: number | null) => { - const loaderFilename = document.getElementById(IDS.loaderStatus); + const loaderFilename = document.getElementById(IDS.loadingStep); const loadingBarFill = document.getElementById(IDS.loadingBar); if (loaderFilename) loaderFilename.innerText = filename; @@ -36,3 +36,13 @@ export const setLoadingStatus = (filename: string, index?: number | null) => { export const setLoadingTotalFiles = (total: number) => { totalFiles = total; }; + +export const setError = (error: string) => { + const loaderErrorMessage = document.getElementById(IDS.loaderErrorMessage); + + if (!loaderErrorMessage) return; + loaderErrorMessage.innerText = error; + + setHiddenStatusOnId(IDS.loadingStatus, true); + setHiddenStatusOnId(IDS.loaderError, false); +};