@fi4f/hg 0.0.0

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.
Files changed (74) hide show
  1. package/.gitattributes +2 -0
  2. package/.github/workflows/publish.yml +23 -0
  3. package/dist/asset.d.ts +111 -0
  4. package/dist/asset.d.ts.map +1 -0
  5. package/dist/asset.js +188 -0
  6. package/dist/asset.js.map +1 -0
  7. package/dist/event.d.ts +69 -0
  8. package/dist/event.d.ts.map +1 -0
  9. package/dist/event.js +133 -0
  10. package/dist/event.js.map +1 -0
  11. package/dist/hg.d.ts +18 -0
  12. package/dist/hg.d.ts.map +1 -0
  13. package/dist/hg.js +19 -0
  14. package/dist/hg.js.map +1 -0
  15. package/dist/math.d.ts +6 -0
  16. package/dist/math.d.ts.map +1 -0
  17. package/dist/math.js +6 -0
  18. package/dist/math.js.map +1 -0
  19. package/dist/matrix2.d.ts +91 -0
  20. package/dist/matrix2.d.ts.map +1 -0
  21. package/dist/matrix2.js +178 -0
  22. package/dist/matrix2.js.map +1 -0
  23. package/dist/matrix3.d.ts +146 -0
  24. package/dist/matrix3.d.ts.map +1 -0
  25. package/dist/matrix3.js +255 -0
  26. package/dist/matrix3.js.map +1 -0
  27. package/dist/matrix4.d.ts +219 -0
  28. package/dist/matrix4.d.ts.map +1 -0
  29. package/dist/matrix4.js +352 -0
  30. package/dist/matrix4.js.map +1 -0
  31. package/dist/scene.d.ts +34 -0
  32. package/dist/scene.d.ts.map +1 -0
  33. package/dist/scene.js +9 -0
  34. package/dist/scene.js.map +1 -0
  35. package/dist/stage.d.ts +128 -0
  36. package/dist/stage.d.ts.map +1 -0
  37. package/dist/stage.js +299 -0
  38. package/dist/stage.js.map +1 -0
  39. package/dist/types.d.ts +2 -0
  40. package/dist/types.d.ts.map +1 -0
  41. package/dist/types.js +2 -0
  42. package/dist/types.js.map +1 -0
  43. package/dist/vector2.d.ts +38 -0
  44. package/dist/vector2.d.ts.map +1 -0
  45. package/dist/vector2.js +67 -0
  46. package/dist/vector2.js.map +1 -0
  47. package/dist/vector3.d.ts +46 -0
  48. package/dist/vector3.d.ts.map +1 -0
  49. package/dist/vector3.js +74 -0
  50. package/dist/vector3.js.map +1 -0
  51. package/dist/vector4.d.ts +54 -0
  52. package/dist/vector4.d.ts.map +1 -0
  53. package/dist/vector4.js +81 -0
  54. package/dist/vector4.js.map +1 -0
  55. package/dist/version.d.ts +21 -0
  56. package/dist/version.d.ts.map +1 -0
  57. package/dist/version.js +14 -0
  58. package/dist/version.js.map +1 -0
  59. package/package.json +29 -0
  60. package/src/asset.ts +249 -0
  61. package/src/event.ts +174 -0
  62. package/src/hg.ts +21 -0
  63. package/src/math.ts +5 -0
  64. package/src/matrix2.ts +215 -0
  65. package/src/matrix3.ts +302 -0
  66. package/src/matrix4.ts +415 -0
  67. package/src/scene.ts +45 -0
  68. package/src/stage.ts +481 -0
  69. package/src/types.ts +1 -0
  70. package/src/vector2.ts +80 -0
  71. package/src/vector3.ts +88 -0
  72. package/src/vector4.ts +96 -0
  73. package/src/version.ts +26 -0
  74. package/tsconfig.json +44 -0
@@ -0,0 +1,81 @@
1
+ import { ADD, SUB, MUL, DIV, MOD } from "./math.js";
2
+ export const X = 0;
3
+ export const Y = 1;
4
+ export const Z = 2;
5
+ export const W = 3;
6
+ export const __get__ = {
7
+ x(a) { return a[X]; },
8
+ y(a) { return a[Y]; },
9
+ z(a) { return a[Z]; },
10
+ w(a) { return a[W]; },
11
+ };
12
+ export const __set__ = {
13
+ x(a, x) { return a[X] = x; },
14
+ y(a, y) { return a[Y] = y; },
15
+ z(a, z) { return a[Z] = z; },
16
+ w(a, w) { return a[W] = w; },
17
+ };
18
+ export function x(a, x) {
19
+ return x === undefined ? __get__.x(a) : __set__.x(a, x);
20
+ }
21
+ export function y(a, y) {
22
+ return y === undefined ? __get__.y(a) : __set__.y(a, y);
23
+ }
24
+ export function z(a, z) {
25
+ return z === undefined ? __get__.z(a) : __set__.z(a, z);
26
+ }
27
+ export function w(a, w) {
28
+ return w === undefined ? __get__.w(a) : __set__.w(a, w);
29
+ }
30
+ export const Vector4 = {
31
+ X, Y, Z, W,
32
+ __get__,
33
+ __set__,
34
+ x, y, z, w,
35
+ new(...a) {
36
+ if (a.length === 1)
37
+ return [a[X], a[X], a[X], a[X]];
38
+ else
39
+ return [a[X] ?? 0, a[Y] ?? 0, a[Z] ?? 0, a[W] ?? 0];
40
+ },
41
+ from(a) {
42
+ if (typeof a === "number")
43
+ return [a, a, a, a];
44
+ else
45
+ return [a[X] ?? 0, a[Y] ?? 0, a[Z] ?? 0, a[W] ?? 0];
46
+ },
47
+ el(op, a, b, out = Vector4.new()) {
48
+ const [xa, ya, za, wa] = Vector4.from(a);
49
+ const [xb, yb, zb, wb] = Vector4.from(b);
50
+ __set__.x(out, op(xa, xb));
51
+ __set__.y(out, op(ya, yb));
52
+ __set__.z(out, op(za, zb));
53
+ __set__.w(out, op(wa, wb));
54
+ return out;
55
+ },
56
+ add(a, b, out = Vector4.new()) {
57
+ return Vector4.el(ADD, a, b, out);
58
+ },
59
+ sub(a, b, out = Vector4.new()) {
60
+ return Vector4.el(SUB, a, b, out);
61
+ },
62
+ hmul(a, b, out = Vector4.new()) {
63
+ return Vector4.el(MUL, a, b, out);
64
+ },
65
+ hdiv(a, b, out = Vector4.new()) {
66
+ return Vector4.el(DIV, a, b, out);
67
+ },
68
+ hmod(a, b, out = Vector4.new()) {
69
+ return Vector4.el(MOD, a, b, out);
70
+ },
71
+ dot(a, b = a) {
72
+ const [xa, ya, za, wa] = Vector4.from(a);
73
+ const [xb, yb, zb, wb] = Vector4.from(b);
74
+ return xa * xb + ya * yb + za * zb + wa * wb;
75
+ },
76
+ toString(a) {
77
+ const [x, y, z, w] = Vector4.from(a);
78
+ return `vec4<${x}, ${y}, ${z}, ${w}>`;
79
+ }
80
+ };
81
+ //# sourceMappingURL=vector4.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vector4.js","sourceRoot":"","sources":["../src/vector4.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ export type Version = {
2
+ readonly moniker: string;
3
+ readonly major: number;
4
+ readonly minor: number;
5
+ readonly patch: number;
6
+ };
7
+ export declare const Version: {
8
+ "new"(o?: {
9
+ moniker?: string;
10
+ major?: number;
11
+ minor?: number;
12
+ patch?: number;
13
+ }): {
14
+ moniker: string;
15
+ major: number;
16
+ minor: number;
17
+ patch: number;
18
+ };
19
+ toString(a: Version): string;
20
+ };
21
+ //# sourceMappingURL=version.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,OAAO,GAAG;IACpB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAI,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAI,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAI,MAAM,CAAC;CAC1B,CAAA;AAED,eAAO,MAAM,OAAO;cACT;QACP,OAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,KAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,KAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,KAAQ,CAAC,EAAE,MAAM,CAAC;KACnB;;;;;;gBASW,OAAO;CAGpB,CAAA"}
@@ -0,0 +1,14 @@
1
+ export const Version = {
2
+ new(o) {
3
+ return {
4
+ moniker: o?.moniker ?? "hg",
5
+ major: o?.major ?? 0,
6
+ minor: o?.minor ?? 0,
7
+ patch: o?.patch ?? 0,
8
+ };
9
+ },
10
+ toString(a) {
11
+ return `${a.moniker} ${a.major}.${a.minor}.${a.patch}`;
12
+ }
13
+ };
14
+ //# sourceMappingURL=version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAOA,MAAM,CAAC,MAAM,OAAO,GAAG;IACrB,GAAG,CAAC,CAKH;QACC,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,OAAO,IAAI,IAAI;YAC3B,KAAK,EAAI,CAAC,EAAE,KAAK,IAAM,CAAC;YACxB,KAAK,EAAI,CAAC,EAAE,KAAK,IAAM,CAAC;YACxB,KAAK,EAAI,CAAC,EAAE,KAAK,IAAM,CAAC;SACP,CAAC;IACtB,CAAC;IAED,QAAQ,CAAC,CAAU;QACjB,OAAO,GAAG,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC;IACzD,CAAC;CACF,CAAA"}
package/package.json ADDED
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "@fi4f/hg",
3
+ "version": "0.0.0",
4
+ "description": "",
5
+ "homepage": "https://github.com/fi4f/hg#readme",
6
+ "bugs": {
7
+ "url": "https://github.com/fi4f/hg/issues"
8
+ },
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git+https://github.com/fi4f/hg.git"
12
+ },
13
+ "license": "ISC",
14
+ "author": "",
15
+ "type": "module",
16
+ "main" : "dist/hg.js",
17
+ "types": "dist/hg.d.ts",
18
+ "scripts": {
19
+ "test": "echo \"Error: no test specified\" && exit 1",
20
+ "dev": "concurrently \"tsc --watch\" \"npx serve\"",
21
+ "build": "tsc"
22
+ },
23
+ "dependencies": {
24
+ "typescript": "^5.9.3"
25
+ },
26
+ "devDependencies": {
27
+ "concurrently": "^9.2.1"
28
+ }
29
+ }
package/src/asset.ts ADDED
@@ -0,0 +1,249 @@
1
+ export const IMAGE = "image" as const;
2
+ export const AUDIO = "audio" as const;
3
+ export const TEXT = "text" as const;
4
+ export const BLOB = "blob" as const;
5
+ export const JSON = "json" as const;
6
+
7
+ export type IMAGE = typeof IMAGE;
8
+ export type AUDIO = typeof AUDIO;
9
+ export type TEXT = typeof TEXT ;
10
+ export type BLOB = typeof BLOB ;
11
+ export type JSON = typeof JSON ;
12
+
13
+ export type Kind = IMAGE | AUDIO | TEXT | BLOB | JSON;
14
+
15
+ export type Asset<T extends Kind> = { kind: T, path: string, id ?: string | undefined }
16
+ export namespace Asset {
17
+ export type Image = Asset<IMAGE>
18
+ export type Audio = Asset<AUDIO>
19
+ export type Text = Asset<TEXT >
20
+ export type Blob = Asset<BLOB >
21
+ export type Json = Asset<JSON >
22
+ }
23
+
24
+ export type Cache = {
25
+ images: { [id: string]: HTMLImageElement }
26
+ audios: { [id: string]: HTMLAudioElement }
27
+ texts: { [id: string]: string }
28
+ blobs: { [id: string]: globalThis.Blob }
29
+ jsons: { [id: string]: any }
30
+ }
31
+
32
+ export function load(a: Asset<any>) {
33
+ switch (a.kind) {
34
+ case IMAGE: return loadImage(a);
35
+ case AUDIO: return loadAudio(a);
36
+ case TEXT: return loadText (a);
37
+ case BLOB: return loadBlob (a);
38
+ case JSON: return loadJson (a);
39
+ default: throw `[Asset.load]: Unknown kind of asset '${a.kind}'`;
40
+ }
41
+ }
42
+
43
+ export function loadImage(a: Asset.Image) {
44
+ return new Promise<HTMLImageElement>((res, rej) => {
45
+ const image = new Image();
46
+ image.onload = () => res(image);
47
+ image.onerror = () => rej( );
48
+ image.src = a.path;
49
+ })
50
+ }
51
+
52
+ export function loadAudio(a: Asset.Audio) {
53
+ return new Promise<HTMLAudioElement>((res, rej) => {
54
+ const audio = new Audio();
55
+ audio.onload = () => res(audio);
56
+ audio.onerror = () => rej( );
57
+ audio.src = a.path;
58
+ })
59
+ }
60
+
61
+ export async function loadText(a: Asset.Text) {
62
+ return fetch(a.path).then(res => res.text())
63
+ }
64
+
65
+ export async function loadBlob(a: Asset.Blob) {
66
+ return fetch(a.path).then(res => res.blob())
67
+ }
68
+
69
+ export async function loadJson(a: Asset.Json) {
70
+ return fetch(a.path).then(res => res.json())
71
+ }
72
+
73
+ export const Asset = {
74
+ new<T extends Kind>(kind: T, path: string, id ?: string) {
75
+ return { kind, path, id } satisfies Asset<T>
76
+ },
77
+
78
+ Image(path: string, id ?: string) {
79
+ return Asset.new(IMAGE, path, id) satisfies Asset.Image
80
+ },
81
+
82
+ Audio(path: string, id ?: string) {
83
+ return Asset.new(AUDIO, path, id) satisfies Asset.Audio
84
+ },
85
+
86
+ Text(path: string, id ?: string) {
87
+ return Asset.new(TEXT, path, id) satisfies Asset.Text
88
+ },
89
+
90
+ Blob(path: string, id ?: string) {
91
+ return Asset.new(BLOB, path, id) satisfies Asset.Blob
92
+ },
93
+
94
+ Json(path: string, id ?: string) {
95
+ return Asset.new(JSON, path, id) satisfies Asset.Json
96
+ },
97
+ }
98
+
99
+ export const Cache = {
100
+ new() {
101
+ return {
102
+ images: {},
103
+ audios: {},
104
+ texts: {},
105
+ blobs: {},
106
+ jsons: {},
107
+ } satisfies Cache
108
+ },
109
+
110
+ getImage(cache: Cache, id: string) {
111
+ if (!(id in cache.images))
112
+ throw `[Cache.getImage]: Image with id '${id}' does not exist`;
113
+ return cache.images[id];
114
+ },
115
+
116
+ getAudio(cache: Cache, id: string) {
117
+ if (!(id in cache.audios))
118
+ throw `[Cache.getAudio]: Audio with id '${id}' does not exist`;
119
+ return cache.audios[id];
120
+ },
121
+
122
+ getText(cache: Cache, id: string) {
123
+ if (!(id in cache.texts))
124
+ throw `[Cache.getText]: Text with id '${id}' does not exist`;
125
+ return cache.texts[id];
126
+ },
127
+
128
+ getBlob(cache: Cache, id: string) {
129
+ if (!(id in cache.blobs))
130
+ throw `[Cache.getBlob]: Blob with id '${id}' does not exist`;
131
+ return cache.blobs[id];
132
+ },
133
+
134
+ getJson(cache: Cache, id: string) {
135
+ if(!(id in cache.jsons))
136
+ throw `[Cache.getJson]: Json with id '${id}' does not exist`;
137
+ return cache.jsons[id];
138
+ },
139
+
140
+ putImage(cache: Cache, id: string, image: HTMLImageElement) {
141
+ if (id in cache.images)
142
+ console.warn(`[Cache.putImage]: Image with id '${id}' already exists`);
143
+ return cache.images[id] = image;
144
+ },
145
+
146
+ putAudio(cache: Cache, id: string, audio: HTMLAudioElement) {
147
+ if (id in cache.audios)
148
+ console.warn(`[Cache.putAudio]: Audio with id '${id}' already exists`);
149
+ return cache.audios[id] = audio;
150
+ },
151
+
152
+ putText(cache: Cache, id: string, text: string) {
153
+ if (id in cache.texts)
154
+ console.warn(`[Cache.putText]: Text with id '${id}' already exists`);
155
+ return cache.texts[id] = text;
156
+ },
157
+
158
+ putBlob(cache: Cache, id: string, blob: Blob) {
159
+ if (id in cache.blobs)
160
+ console.warn(`[Cache.putBlob]: Blob with id '${id}' already exists`);
161
+ return cache.blobs[id] = blob;
162
+ },
163
+
164
+ putJson(cache: Cache, id: string, json: any) {
165
+ if (id in cache.jsons)
166
+ console.warn(`[Cache.putJson]: Json with id '${id}' already exists`);
167
+ return cache.jsons[id] = json;
168
+ },
169
+
170
+ freeImage(cache: Cache, id: string) {
171
+ delete cache.images[id];
172
+ },
173
+
174
+ freeAudio(cache: Cache, id: string) {
175
+ delete cache.audios[id];
176
+ },
177
+
178
+ freeText(cache: Cache, id: string) {
179
+ delete cache.texts[id];
180
+ },
181
+
182
+ freeBlob(cache: Cache, id: string) {
183
+ delete cache.blobs[id];
184
+ },
185
+
186
+ freeJson(cache: Cache, id: string) {
187
+ delete cache.jsons[id];
188
+ },
189
+
190
+ freeAll(cache: Cache) {
191
+ cache.images = {};
192
+ cache.audios = {};
193
+ cache.texts = {};
194
+ cache.blobs = {};
195
+ cache.jsons = {};
196
+ },
197
+
198
+ load(cache: Cache, a: Asset<any>) {
199
+ switch (a.kind) {
200
+ case IMAGE: return Cache.loadImage(cache, a);
201
+ case AUDIO: return Cache.loadAudio(cache, a);
202
+ case TEXT: return Cache.loadText (cache, a);
203
+ case BLOB: return Cache.loadBlob (cache, a);
204
+ case JSON: return Cache.loadJson (cache, a);
205
+ default: throw `[Cache.load]: Unknown kind of asset '${a.kind}'`;
206
+ }
207
+ },
208
+
209
+ async loadImage(cache: Cache, a: Asset.Image) {
210
+ const id = a.id ?? uniqueId(cache.images);
211
+ Cache.putImage(cache, id, await loadImage(a));
212
+ return id;
213
+ },
214
+
215
+ async loadAudio(cache: Cache, a: Asset.Audio) {
216
+ const id = a.id ?? uniqueId(cache.audios);
217
+ Cache.putAudio(cache, id, await loadAudio(a));
218
+ return id;
219
+ },
220
+
221
+ async loadText(cache: Cache, a: Asset.Text) {
222
+ const id = a.id ?? uniqueId(cache.texts );
223
+ Cache.putText(cache, id, await loadText(a));
224
+ return id;
225
+ },
226
+
227
+ async loadBlob(cache: Cache, a: Asset.Blob) {
228
+ const id = a.id ?? uniqueId(cache.blobs );
229
+ Cache.putBlob(cache, id, await loadBlob(a));
230
+ return id;
231
+ },
232
+
233
+ async loadJson(cache: Cache, a: Asset.Json) {
234
+ const id = a.id ?? uniqueId(cache.jsons );
235
+ Cache.putJson(cache, id, await loadJson(a));
236
+ return id;
237
+ },
238
+
239
+ async loadAll(cache: Cache, a: Array<Asset<any>>) {
240
+ return Promise.all(a.map(a => Cache.load(cache, a)));
241
+ }
242
+ }
243
+
244
+ function uniqueId(ids: {[id: string]: any}) {
245
+ let id = crypto.randomUUID();
246
+ while (id in ids)
247
+ id = crypto.randomUUID();
248
+ return id;
249
+ }
package/src/event.ts ADDED
@@ -0,0 +1,174 @@
1
+ import type { Maybe } from "./types.js"
2
+
3
+ export namespace Event {
4
+ export type Listener<T> = (event: T, context: Event.Context<T>) => void
5
+
6
+ export type Listen = { action: "listen" , path: string, type : string , listener : Listener<any> }
7
+ export type Deafen = { action: "deafen" , path: string, type ?: string | undefined, listener ?: Listener<any> | undefined }
8
+ export type Dispatch = { action: "dispatch", path: string, type: string, event: any }
9
+
10
+ export type Action = Listen | Deafen | Dispatch
11
+
12
+ export type Tree = {
13
+ root : Event.Node
14
+ pending: Array<Event.Action>
15
+ }
16
+
17
+ export type Node = {
18
+ children : Map<string, Event.Node >
19
+ listeners: Map<string, Set<Event.Listener<any>>>
20
+ }
21
+
22
+ export type Context<T> = {
23
+ tree: Event.Tree
24
+ node: Event.Node
25
+ path: string
26
+ type: string
27
+ self: Event.Listener<T>
28
+ }
29
+ }
30
+
31
+ export const Event = {
32
+ Tree: {
33
+ new() {
34
+ return {
35
+ root : Event.Node.new(),
36
+ pending: [ ]
37
+ } satisfies Event.Tree
38
+ }
39
+ },
40
+
41
+ Node: {
42
+ new() {
43
+ return {
44
+ children : new Map(),
45
+ listeners: new Map()
46
+ } satisfies Event.Node
47
+ }
48
+ },
49
+
50
+ once<T>(listener: Event.Listener<T>) {
51
+ return ((event: T, context: Event.Context<T>) => {
52
+ listener(event, context)
53
+ const { tree, path, type, self } = context
54
+ Event.deafen(tree, type, self, { path, defer: false })
55
+ }) satisfies Event.Listener<T>
56
+ },
57
+
58
+ listen<T>(tree: Event.Tree, type : string, listener : Event.Listener<T>, o ?: { path ?: string, defer ?: boolean }) {
59
+ const a: Event.Listen = { action: "listen", path: o?.path ?? "", type, listener }
60
+ if (o?.defer ?? true) queue(tree, a)
61
+ else flush(tree, a)
62
+ },
63
+
64
+ deafen<T>(tree: Event.Tree, type ?: string, listener ?: Event.Listener<T>, o ?: { path ?: string, defer ?: boolean }) {
65
+ const a: Event.Deafen = { action: "deafen", path: o?.path ?? "", type, listener }
66
+ if (o?.defer ?? true) queue(tree, a)
67
+ else flush(tree, a)
68
+ },
69
+
70
+ dispatch(tree: Event.Tree, type: string, event: any, o ?: { path ?: string, defer ?: boolean }) {
71
+ const a: Event.Dispatch = { action: "dispatch", path: o?.path ?? "", type, event }
72
+ if (o?.defer ?? true) queue(tree, a)
73
+ else flush(tree, a)
74
+ },
75
+
76
+ poll(tree: Event.Tree) {
77
+ tree.pending.splice(0).forEach(
78
+ a => flush(tree, a)
79
+ )
80
+ }
81
+ }
82
+
83
+ function queue(tree: Event.Tree, a: Event.Action) {
84
+ tree.pending.push(a)
85
+ }
86
+
87
+ function flush(tree: Event.Tree, a: Event.Action) {
88
+ switch(a.action) {
89
+ case "listen" : return onListen (tree, a)
90
+ case "deafen" : return onDeafen (tree, a)
91
+ case "dispatch": return onDispatch(tree, a)
92
+ }
93
+ }
94
+
95
+ function requestListeners(node: Maybe<Event.Node>, type: string) {
96
+ let list = node?.listeners.get(type)
97
+ // if (!list) node.listeners.set(
98
+ // type, list = new Set()
99
+ // )
100
+ return list
101
+ }
102
+
103
+ function requireListeners(node: Event.Node , type: string) {
104
+ let list = node.listeners.get(type)
105
+ if (!list) node.listeners.set(
106
+ type, list = new Set()
107
+ )
108
+ return list
109
+ }
110
+
111
+ function requestNode(root: Maybe<Event.Node>, path: string) {
112
+ for (const part of path.split("/")) {
113
+ let node = root?.children.get(part)
114
+ if (!node) return
115
+ root = node
116
+ }
117
+
118
+ return root
119
+ }
120
+
121
+ function requireNode(root: Event.Node , path: string) {
122
+ for (const part of path.split("/")) {
123
+ let node = root.children.get(part)
124
+ if (!node) root.children.set(
125
+ part, node = Event.Node.new()
126
+ )
127
+ root = node
128
+ }
129
+
130
+ return root
131
+ }
132
+
133
+ function onListen (tree: Event.Tree, a: Event.Listen ) {
134
+ const node = requireNode(tree.root, a.path)
135
+ const list = requireListeners(node, a.type)
136
+ list.add(a.listener)
137
+ }
138
+
139
+ function onDeafen (tree: Event.Tree, a: Event.Deafen ) {
140
+ if (a.type !== undefined && a.listener !== undefined) {
141
+ const node = requestNode(tree.root, a.path)
142
+ const list = requestListeners(node, a.type)
143
+ list?.delete(a.listener)
144
+ } else if (a.type !== undefined && a.listener === undefined) {
145
+ const node = requestNode(tree.root, a.path)
146
+ const list = requestListeners(node, a.type)
147
+ list?.clear()
148
+ } else if (a.type === undefined && a.listener !== undefined) {
149
+ const node = requestNode(tree.root, a.path)
150
+ node?.listeners.forEach((list) => {
151
+ list.delete(a.listener!)
152
+ })
153
+ } else if (a.type === undefined && a.listener === undefined) {
154
+ const node = requestNode(tree.root, a.path)
155
+ node?.children .clear()
156
+ node?.listeners.clear()
157
+ }
158
+ }
159
+
160
+ function onDispatch(tree: Event.Tree, { path, type, event }: Event.Dispatch) {
161
+ const node = requestNode(tree.root, path)
162
+ if (!node) return
163
+ reDispatch(tree, node, path, type, event)
164
+ }
165
+
166
+ function reDispatch(tree: Event.Tree, node: Event.Node, path: string, type: string, event: any) {
167
+ requestListeners(node, type)?.forEach(self => {
168
+ self(event, { tree, node, path, type, self })
169
+ })
170
+
171
+ node.children.forEach((child, name) => {
172
+ reDispatch(tree, child, `${path}/${name}`, type, event)
173
+ })
174
+ }
package/src/hg.ts ADDED
@@ -0,0 +1,21 @@
1
+ import { Version } from "./version.js";
2
+
3
+ export const VERSION = Version.new({
4
+ moniker: "hg",
5
+ major : 0,
6
+ minor : 0,
7
+ patch : 1,
8
+ })
9
+
10
+ export { Version } from "./version.js"
11
+ export { Vector2 } from "./vector2.js"
12
+ export { Vector3 } from "./vector3.js"
13
+ export { Vector4 } from "./vector4.js"
14
+ export { Matrix2 } from "./matrix2.js"
15
+ export { Matrix3 } from "./matrix3.js"
16
+ export { Matrix4 } from "./matrix4.js"
17
+ export { Stage } from "./stage.js"
18
+ export { Scene } from "./scene.js"
19
+ export { Event } from "./event.js"
20
+
21
+ export { Asset, Cache } from "./asset.js"
package/src/math.ts ADDED
@@ -0,0 +1,5 @@
1
+ export function ADD(a: number, b: number) { return a + b }
2
+ export function SUB(a: number, b: number) { return a - b }
3
+ export function MUL(a: number, b: number) { return a * b }
4
+ export function DIV(a: number, b: number) { return a / b }
5
+ export function MOD(a: number, b: number) { return a % b }