bg2e-js 2.2.12 → 2.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bg2e-js",
3
- "version": "2.2.12",
3
+ "version": "2.3.1",
4
4
  "description": "a graphics engine for productivity applications",
5
5
  "main": "./dist/bg2e-js.js",
6
6
  "types": "./src/index.ts",
@@ -0,0 +1,70 @@
1
+ import { useEffect, useMemo, useRef, useState } from "react";
2
+
3
+ import Canvas from "../app/Canvas";
4
+ import MainLoop from "../app/MainLoop";
5
+ import type AppController from "../app/AppController";
6
+ import Renderer from "../render/Renderer";
7
+
8
+ const mainLoopByCanvas = new WeakMap<HTMLCanvasElement, MainLoop>();
9
+
10
+ function resolveCanvas(canvas: string | HTMLCanvasElement): HTMLCanvasElement | null {
11
+ if (typeof canvas === "string") {
12
+ return document.querySelector(canvas);
13
+ } else {
14
+ return canvas;
15
+ }
16
+ }
17
+
18
+ type RendererConstructor<T extends Renderer> = new () => T;
19
+ type AppControllerConstructor<T extends AppController> = new () => T;
20
+
21
+ export default function useBg2e<R extends Renderer, A extends AppController>(
22
+ target: string | HTMLCanvasElement,
23
+ RendererType: RendererConstructor<R>,
24
+ AppControllerType: AppControllerConstructor<A>
25
+ ) {
26
+ const canvas = useMemo(() => {
27
+ if (typeof document === "undefined") return null; // SSR guard
28
+ return resolveCanvas(target);
29
+ }, [target]);
30
+ const mainLoopRef = useRef<MainLoop | null>(null);
31
+ const createdRef = useRef(false);
32
+
33
+ const [, forceUpdate] = useState(0);
34
+
35
+ useEffect(() => {
36
+ createdRef.current = false;
37
+
38
+ if (!canvas) {
39
+ mainLoopRef.current = null;
40
+ forceUpdate((x) => x + 1);
41
+ return;
42
+ }
43
+
44
+ const existing = mainLoopByCanvas.get(canvas);
45
+ if (existing) {
46
+ mainLoopRef.current = existing;
47
+ forceUpdate((x) => x + 1);
48
+ return;
49
+ }
50
+
51
+ const renderer = new RendererType();
52
+ const appController = new AppControllerType();
53
+
54
+ const bg2Canvas = new Canvas(canvas, renderer);
55
+ const mainLoop = new MainLoop(bg2Canvas, appController);
56
+
57
+ mainLoop.run(); // Background execution
58
+
59
+ mainLoopByCanvas.set(canvas, mainLoop);
60
+ mainLoopRef.current = mainLoop;
61
+ createdRef.current = true;
62
+
63
+ forceUpdate((x) => x + 1);
64
+ }, [canvas, RendererType, AppControllerType]);
65
+
66
+ return {
67
+ mainLoop: mainLoopRef.current,
68
+ canvas
69
+ }
70
+ }