@skewedaspect/sage 0.5.1 → 0.6.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/dist/sage.es.js CHANGED
@@ -1,9 +1,9 @@
1
- var I = Object.defineProperty;
2
- var k = (a, e, t) => e in a ? I(a, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : a[e] = t;
3
- var n = (a, e, t) => k(a, typeof e != "symbol" ? e + "" : e, t);
4
- import { FreeCamera as V, Vector3 as b, HemisphericLight as G, MeshBuilder as D, PhysicsAggregate as E, PhysicsShapeType as C, Scene as L, NullEngine as B, WebGPUEngine as K, Engine as U, HavokPlugin as R } from "@babylonjs/core";
5
- import T from "@babylonjs/havok";
6
- const m = "0.5.1";
1
+ var A = Object.defineProperty;
2
+ var I = (r, e, t) => e in r ? A(r, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : r[e] = t;
3
+ var n = (r, e, t) => I(r, typeof e != "symbol" ? e + "" : e, t);
4
+ import { FreeCamera as G, Vector3 as b, HemisphericLight as V, MeshBuilder as E, PhysicsAggregate as C, PhysicsShapeType as D, Scene as B, NullEngine as L, WebGPUEngine as K, Engine as T, HavokPlugin as U } from "@babylonjs/core";
5
+ import R from "@babylonjs/havok";
6
+ const m = "0.6.0";
7
7
  class z {
8
8
  /**
9
9
  * Creates an instance of SkewedAspectGameEngine.
@@ -15,7 +15,7 @@ class z {
15
15
  * @param engines - The engines used in the game.
16
16
  * @param managers - The managers used in the game.
17
17
  */
18
- constructor(e, t, s, i, o, r, c) {
18
+ constructor(e, t, i, s, o, c, a) {
19
19
  n(this, "canvas");
20
20
  n(this, "renderEngine");
21
21
  n(this, "physics");
@@ -23,26 +23,96 @@ class z {
23
23
  n(this, "engines");
24
24
  n(this, "eventBus");
25
25
  n(this, "logger");
26
+ n(this, "started", !1);
26
27
  n(this, "_log");
27
- this.canvas = e, this.renderEngine = t, this.physics = s, this.eventBus = i, this.logger = o, this.engines = r, this.managers = c, this._log = o.getLogger("GameEngine");
28
+ // Lifecycle hooks
29
+ n(this, "_beforeStartHook", null);
30
+ n(this, "_onStartHook", null);
31
+ n(this, "_onTeardownHook", null);
32
+ this.canvas = e, this.renderEngine = t, this.physics = i, this.eventBus = s, this.logger = o, this.engines = c, this.managers = a, this._log = o.getLogger("GameEngine");
28
33
  }
29
34
  //------------------------------------------------------------------------------------------------------------------
30
35
  // Public API
31
36
  //------------------------------------------------------------------------------------------------------------------
37
+ /**
38
+ * Register a function to be called before the game engine starts
39
+ * @param hook - Async function to be called before start
40
+ * @throws Error if a hook is already registered
41
+ */
42
+ onBeforeStart(e) {
43
+ if (this._beforeStartHook !== null)
44
+ throw new Error("A beforeStart hook is already registered. Only one hook is allowed per lifecycle event.");
45
+ this._beforeStartHook = e;
46
+ }
47
+ /**
48
+ * Register a function to be called after the game engine starts
49
+ * @param hook - Async function to be called after start
50
+ * @throws Error if a hook is already registered
51
+ */
52
+ onStart(e) {
53
+ if (this._onStartHook !== null)
54
+ throw new Error("An onStart hook is already registered. Only one hook is allowed per lifecycle event.");
55
+ this._onStartHook = e;
56
+ }
57
+ /**
58
+ * Register a function to be called when the game engine stops
59
+ * @param hook - Async function to be called during teardown
60
+ * @throws Error if a hook is already registered
61
+ */
62
+ onTeardown(e) {
63
+ if (this._onTeardownHook !== null)
64
+ throw new Error("An onTeardown hook is already registered. Only one hook is allowed per lifecycle event.");
65
+ this._onTeardownHook = e;
66
+ }
32
67
  /**
33
68
  * Starts the game engine.
34
69
  */
35
70
  async start() {
36
- this._log.info(`Starting SkewedAspect Game Engine (Version: ${m})...`), await this.managers.gameManager.start(this.canvas), this._log.info("Game engine started successfully");
71
+ this.started ? this._log.warn("Game engine is already started. Skipping start.") : (this._log.info(`Starting SkewedAspect Game Engine (Version: ${m})...`), this._beforeStartHook && (this._log.debug("Executing beforeStart hook..."), await this._beforeStartHook(this)), await this.managers.gameManager.start(this.canvas), this._log.info("Game engine started successfully"), this._onStartHook && (this._log.debug("Executing onStart hook..."), await this._onStartHook(this)), this.started = !0);
37
72
  }
38
73
  /**
39
74
  * Stops the game engine.
40
75
  */
41
76
  async stop() {
42
- this._log.info(`Stopping SkewedAspect Game Engine (Version: ${m})...`), await this.managers.gameManager.stop(), this._log.info("Game engine stopped successfully");
77
+ if (this.started) {
78
+ this._log.info(`Stopping SkewedAspect Game Engine (Version: ${m})...`);
79
+ let e = null;
80
+ if (this._onTeardownHook)
81
+ try {
82
+ this._log.debug("Executing onTeardown hook..."), await this._onTeardownHook(this);
83
+ } catch (t) {
84
+ this._log.error(`Error in onTeardown hook: ${t}`), e = e || t;
85
+ }
86
+ for (const t of Object.keys(this.managers)) {
87
+ const i = this.managers[t];
88
+ if (typeof i.$teardown == "function")
89
+ try {
90
+ this._log.debug(`Tearing down manager: ${t}`), await i.$teardown();
91
+ } catch (s) {
92
+ this._log.error(`Error tearing down manager ${t}: ${s}`), e = e || s;
93
+ }
94
+ }
95
+ for (const t of Object.keys(this.engines)) {
96
+ const i = this.engines[t];
97
+ if (typeof i.$teardown == "function")
98
+ try {
99
+ this._log.debug(`Tearing down engine: ${t}`), await i.$teardown();
100
+ } catch (s) {
101
+ this._log.error(`Error tearing down engine ${t}: ${s}`), e = e || s;
102
+ }
103
+ }
104
+ try {
105
+ await this.managers.gameManager.stop();
106
+ } catch (t) {
107
+ this._log.error(`Error stopping game manager: ${t}`), e = e || t;
108
+ }
109
+ if (this._log.info("Game engine stopped successfully"), e)
110
+ throw e;
111
+ } else
112
+ this._log.warn("Game engine is not started. Skipping stop.");
43
113
  }
44
114
  }
45
- class W {
115
+ class P {
46
116
  constructor() {
47
117
  n(this, "timers");
48
118
  this.timers = /* @__PURE__ */ new Map();
@@ -73,9 +143,9 @@ class W {
73
143
  * Format a log message with category, timestamp and log level
74
144
  */
75
145
  formatMessage(e, t) {
76
- const s = /* @__PURE__ */ new Date(), i = s.getHours() % 12 || 12, o = s.getMinutes().toString().padStart(2, "0"), r = s.getSeconds().toString().padStart(2, "0"), c = s.getHours() >= 12 ? "PM" : "AM", h = `[${i}:${o}:${r} ${c}]`, u = t.toUpperCase();
146
+ const i = /* @__PURE__ */ new Date(), s = i.getHours() % 12 || 12, o = i.getMinutes().toString().padStart(2, "0"), c = i.getSeconds().toString().padStart(2, "0"), a = i.getHours() >= 12 ? "PM" : "AM", h = `[${s}:${o}:${c} ${a}]`, d = t.toUpperCase();
77
147
  return [
78
- `${h} %c${u}%c (${e}): `,
148
+ `${h} %c${d}%c (${e}): `,
79
149
  // Format string with placeholders
80
150
  this.getStyleForLevel(t),
81
151
  // Level style
@@ -85,62 +155,62 @@ class W {
85
155
  // Reset style
86
156
  ];
87
157
  }
88
- trace(e, t, ...s) {
89
- const [i, o, r, c] = this.formatMessage(e, "trace");
90
- console.debug(i, o, r, c, t, ...s);
158
+ trace(e, t, ...i) {
159
+ const [s, o, c, a] = this.formatMessage(e, "trace");
160
+ console.debug(s, o, c, a, t, ...i);
91
161
  }
92
- debug(e, t, ...s) {
93
- const [i, o, r, c] = this.formatMessage(e, "debug");
94
- console.debug(i, o, r, c, t, ...s);
162
+ debug(e, t, ...i) {
163
+ const [s, o, c, a] = this.formatMessage(e, "debug");
164
+ console.debug(s, o, c, a, t, ...i);
95
165
  }
96
- info(e, t, ...s) {
97
- const [i, o, r, c] = this.formatMessage(e, "info");
98
- console.info(i, o, r, c, t, ...s);
166
+ info(e, t, ...i) {
167
+ const [s, o, c, a] = this.formatMessage(e, "info");
168
+ console.info(s, o, c, a, t, ...i);
99
169
  }
100
- warn(e, t, ...s) {
101
- const [i, o, r, c] = this.formatMessage(e, "warn");
102
- console.warn(i, o, r, c, t, ...s);
170
+ warn(e, t, ...i) {
171
+ const [s, o, c, a] = this.formatMessage(e, "warn");
172
+ console.warn(s, o, c, a, t, ...i);
103
173
  }
104
- error(e, t, ...s) {
105
- const [i, o, r, c] = this.formatMessage(e, "error");
106
- console.error(i, o, r, c, t, ...s);
174
+ error(e, t, ...i) {
175
+ const [s, o, c, a] = this.formatMessage(e, "error");
176
+ console.error(s, o, c, a, t, ...i);
107
177
  }
108
178
  /**
109
179
  * Start a timer with the specified label.
110
180
  */
111
181
  time(e, t) {
112
- const s = `${e}:${t}`;
113
- this.timers.set(s, performance.now());
182
+ const i = `${e}:${t}`;
183
+ this.timers.set(i, performance.now());
114
184
  }
115
185
  /**
116
186
  * End a timer and log the elapsed time.
117
187
  */
118
188
  timeEnd(e, t) {
119
- const s = `${e}:${t}`, i = this.timers.get(s);
120
- if (i !== void 0) {
121
- const o = performance.now() - i;
122
- this.timers.delete(s);
123
- const [r, c, h, u] = this.formatMessage(e, "timer");
189
+ const i = `${e}:${t}`, s = this.timers.get(i);
190
+ if (s !== void 0) {
191
+ const o = performance.now() - s;
192
+ this.timers.delete(i);
193
+ const [c, a, h, d] = this.formatMessage(e, "timer");
124
194
  console.info(
125
- `${r} Timer '${t}' completed in ${o.toFixed(2)}ms`,
126
- c,
195
+ `${c} Timer '${t}' completed in ${o.toFixed(2)}ms`,
196
+ a,
127
197
  h,
128
- u
198
+ d
129
199
  );
130
200
  } else
131
201
  console.warn(`[${e}]: Timer '${t}' does not exist`);
132
202
  }
133
203
  }
134
- class P {
135
- trace(e, t, ...s) {
204
+ class H {
205
+ trace(e, t, ...i) {
136
206
  }
137
- debug(e, t, ...s) {
207
+ debug(e, t, ...i) {
138
208
  }
139
- info(e, t, ...s) {
209
+ info(e, t, ...i) {
140
210
  }
141
- warn(e, t, ...s) {
211
+ warn(e, t, ...i) {
142
212
  }
143
- error(e, t, ...s) {
213
+ error(e, t, ...i) {
144
214
  }
145
215
  time(e, t) {
146
216
  }
@@ -148,11 +218,11 @@ class P {
148
218
  }
149
219
  }
150
220
  class g {
151
- constructor(e, t = "none", s = new P()) {
221
+ constructor(e, t = "none", i = new H()) {
152
222
  n(this, "category");
153
223
  n(this, "backend");
154
224
  n(this, "minLevel");
155
- this.category = e, this.backend = s, this.minLevel = t;
225
+ this.category = e, this.backend = i, this.minLevel = t;
156
226
  }
157
227
  /**
158
228
  * Update the logger's backend and minimum level
@@ -203,14 +273,14 @@ class g {
203
273
  }
204
274
  }
205
275
  }
206
- class F {
276
+ class O {
207
277
  /**
208
278
  * Create a new LoggingUtility.
209
279
  *
210
280
  * @param level - The minimum logging level (defaults to INFO)
211
281
  * @param backend - The logging backend to use (defaults to ConsoleBackend)
212
282
  */
213
- constructor(e = "debug", t = new W()) {
283
+ constructor(e = "debug", t = new P()) {
214
284
  n(this, "backend");
215
285
  n(this, "level");
216
286
  n(this, "loggers");
@@ -256,7 +326,7 @@ class F {
256
326
  return t;
257
327
  }
258
328
  }
259
- class O {
329
+ class W {
260
330
  /**
261
331
  * Creates a new GameEventBus instance
262
332
  *
@@ -302,14 +372,14 @@ class O {
302
372
  */
303
373
  subscribeExact(e, t) {
304
374
  this._log.debug(`Adding exact subscription for: ${e}`);
305
- let s = this.directMap.get(e);
306
- s || (s = /* @__PURE__ */ new Set(), this.directMap.set(e, s));
307
- const i = {
375
+ let i = this.directMap.get(e);
376
+ i || (i = /* @__PURE__ */ new Set(), this.directMap.set(e, i));
377
+ const s = {
308
378
  callback: (o) => t(o)
309
379
  // runtime "type-lie" cast
310
380
  };
311
- return s.add(i), () => {
312
- this._log.debug(`Removing exact subscription for: ${e}`), s.delete(i), s.size === 0 && this.directMap.delete(e);
381
+ return i.add(s), () => {
382
+ this._log.debug(`Removing exact subscription for: ${e}`), i.delete(s), i.size === 0 && this.directMap.delete(e);
313
383
  };
314
384
  }
315
385
  /**
@@ -323,20 +393,20 @@ class O {
323
393
  * @returns {Unsubscribe} function that unsubscribes this pattern-based subscription.
324
394
  */
325
395
  subscribePattern(e, t) {
326
- let s;
396
+ let i;
327
397
  if (typeof e == "string") {
328
398
  const o = e.replace(/[-/\\^$+?.()|[\]{}]/g, "\\$&").replace(/\*/g, ".*");
329
- s = new RegExp(`^${o}$`), this._log.debug(
330
- `Adding pattern subscription for string: ${e}, regex: ${s.toString()}`
399
+ i = new RegExp(`^${o}$`), this._log.debug(
400
+ `Adding pattern subscription for string: ${e}, regex: ${i.toString()}`
331
401
  );
332
402
  } else
333
- s = e, this._log.debug(`Adding pattern subscription for regex: ${s.toString()}`);
334
- const i = {
335
- pattern: s,
403
+ i = e, this._log.debug(`Adding pattern subscription for regex: ${i.toString()}`);
404
+ const s = {
405
+ pattern: i,
336
406
  callback: (o) => t(o)
337
407
  };
338
- return this.patternSubs.add(i), () => {
339
- this._log.debug(`Removing pattern subscription: ${s.toString()}`), this.patternSubs.delete(i);
408
+ return this.patternSubs.add(s), () => {
409
+ this._log.debug(`Removing pattern subscription: ${i.toString()}`), this.patternSubs.delete(s);
340
410
  };
341
411
  }
342
412
  /**
@@ -349,53 +419,59 @@ class O {
349
419
  publish(e) {
350
420
  this._log.trace(`Publishing event: ${e.type}`, e);
351
421
  let t = 0;
352
- const s = this.directMap.get(e.type);
353
- if (s) {
354
- t += s.size;
355
- for (const i of s)
356
- Promise.resolve().then(() => i.callback(e));
422
+ const i = this.directMap.get(e.type);
423
+ if (i) {
424
+ t += i.size;
425
+ for (const s of i)
426
+ Promise.resolve().then(() => s.callback(e));
357
427
  }
358
- for (const i of this.patternSubs)
359
- i.pattern && i.pattern.test(e.type) && (t++, Promise.resolve().then(() => i.callback(e)));
428
+ for (const s of this.patternSubs)
429
+ s.pattern && s.pattern.test(e.type) && (t++, Promise.resolve().then(() => s.callback(e)));
360
430
  t === 0 ? this._log.debug(`No subscribers found for event: ${e.type}`) : this._log.trace(`Event ${e.type} dispatched to ${t} subscribers`);
361
431
  }
362
432
  }
363
- class N {
364
- constructor(e, t, s) {
433
+ class F {
434
+ constructor(e, t, i) {
365
435
  n(this, "_engine");
366
436
  n(this, "_physics");
367
437
  n(this, "_log");
368
- this._engine = e, this._physics = t, this._log = (s == null ? void 0 : s.getLogger("SceneEngine")) || new g("SceneEngine");
438
+ this._engine = e, this._physics = t, this._log = (i == null ? void 0 : i.getLogger("SceneEngine")) || new g("SceneEngine");
369
439
  }
370
440
  async _buildDemoScene(e, t) {
371
441
  this._log.debug("Building demo scene..."), this._log.trace("Creating camera...");
372
- const s = new V("camera1", new b(0, 5, -10), e);
373
- s.setTarget(b.Zero()), s.attachControl(t, !0), this._log.trace("Creating light...");
374
- const i = new G("light", new b(0, 1, 0), e);
375
- i.intensity = 0.7, this._log.trace("Creating sphere...");
376
- const o = D.CreateSphere("sphere", { diameter: 2, segments: 32 }, e);
442
+ const i = new G("camera1", new b(0, 5, -10), e);
443
+ i.setTarget(b.Zero()), i.attachControl(t, !0), this._log.trace("Creating light...");
444
+ const s = new V("light", new b(0, 1, 0), e);
445
+ s.intensity = 0.7, this._log.trace("Creating sphere...");
446
+ const o = E.CreateSphere("sphere", { diameter: 2, segments: 32 }, e);
377
447
  o.position.y = 4, this._log.trace("Creating ground...");
378
- const r = D.CreateGround("ground", { width: 10, height: 10 }, e);
379
- this._log.trace("Adding physics to sphere..."), new E(
448
+ const c = E.CreateGround("ground", { width: 10, height: 10 }, e);
449
+ this._log.trace("Adding physics to sphere..."), new C(
380
450
  o,
381
- C.SPHERE,
451
+ D.SPHERE,
382
452
  { mass: 1, restitution: 0.75 },
383
453
  e
384
- ), this._log.trace("Adding physics to ground..."), new E(r, C.BOX, { mass: 0 }, e), this._log.debug("Demo scene built successfully");
454
+ ), this._log.trace("Adding physics to ground..."), new C(c, D.BOX, { mass: 0 }, e), this._log.debug("Demo scene built successfully");
385
455
  }
386
456
  // TODO: This needs more logic to handle different scenes
387
457
  async loadScene(e) {
388
458
  this._log.info("Loading scene..."), this._log.time("sceneLoad"), this._log.debug("Creating new scene...");
389
- const t = new L(this._engine);
459
+ const t = new B(this._engine);
390
460
  return this._log.debug("Enabling physics with gravity (0, -9.8, 0)..."), t.enablePhysics(new b(0, -9.8, 0), this._physics), await this._buildDemoScene(t, e), this._log.timeEnd("sceneLoad"), this._log.info("Scene loaded successfully"), t;
391
461
  }
462
+ /**
463
+ * Tears down the scene engine and cleans up any resources
464
+ */
465
+ async $teardown() {
466
+ return this._log.info("Tearing down SceneEngine"), this._log.info("SceneEngine torn down successfully"), Promise.resolve();
467
+ }
392
468
  }
393
- const J = [
469
+ const N = [
394
470
  "trigger",
395
471
  "toggle",
396
472
  "value"
397
473
  ];
398
- class Y {
474
+ class J {
399
475
  //------------------------------------------------------------------------------------------------------------------
400
476
  /**
401
477
  * Create a new trigger binding
@@ -405,7 +481,7 @@ class Y {
405
481
  * @param reader - Input reader to read values from
406
482
  * @param options - Binding configuration options
407
483
  */
408
- constructor(e, t, s, i = {}) {
484
+ constructor(e, t, i, s = {}) {
409
485
  n(this, "type", "trigger");
410
486
  n(this, "action");
411
487
  n(this, "context");
@@ -416,7 +492,7 @@ class Y {
416
492
  n(this, "_threshold");
417
493
  // State tracking
418
494
  n(this, "_lastDigitalState", !1);
419
- this.action = e, this.deviceID = t, this.reader = s, this.context = i.context, this._edgeMode = i.edgeMode ?? "rising", this._threshold = i.threshold ?? 0.5;
495
+ this.action = e, this.deviceID = t, this.reader = i, this.context = s.context, this._edgeMode = s.edgeMode ?? "rising", this._threshold = s.threshold ?? 0.5;
420
496
  }
421
497
  //------------------------------------------------------------------------------------------------------------------
422
498
  // Public Getters
@@ -443,39 +519,39 @@ class Y {
443
519
  * @returns True if an action was triggered, false otherwise
444
520
  */
445
521
  process(e, t) {
446
- const s = this.reader.getValue(e) ?? !1, i = typeof s == "boolean" ? s : s >= this._threshold;
522
+ const i = this.reader.getValue(e) ?? !1, s = typeof i == "boolean" ? i : i >= this._threshold;
447
523
  let o = !1;
448
524
  switch (this._edgeMode) {
449
525
  case "rising":
450
- o = i && !this._lastDigitalState;
526
+ o = s && !this._lastDigitalState;
451
527
  break;
452
528
  case "falling":
453
- o = !i && this._lastDigitalState;
529
+ o = !s && this._lastDigitalState;
454
530
  break;
455
531
  case "both":
456
- o = i !== this._lastDigitalState;
532
+ o = s !== this._lastDigitalState;
457
533
  break;
458
534
  }
459
- if (this._lastDigitalState = i, o) {
460
- let r;
535
+ if (this._lastDigitalState = s, o) {
536
+ let c;
461
537
  if (this.action.type === "analog") {
462
- let h = typeof s == "number" ? s : s ? 1 : 0;
538
+ let h = typeof i == "number" ? i : i ? 1 : 0;
463
539
  if (this.action.minValue !== void 0 || this.action.maxValue !== void 0) {
464
- const u = this.action.minValue ?? 0, _ = this.action.maxValue ?? 1;
465
- h = u + h * (_ - u);
540
+ const d = this.action.minValue ?? 0, _ = this.action.maxValue ?? 1;
541
+ h = d + h * (_ - d);
466
542
  }
467
- r = h;
543
+ c = h;
468
544
  } else
469
- r = !0;
470
- const c = {
545
+ c = !0;
546
+ const a = {
471
547
  type: `action:${this.action.name}`,
472
548
  payload: {
473
- value: r,
549
+ value: c,
474
550
  deviceId: this.deviceID,
475
551
  context: this.context
476
552
  }
477
553
  };
478
- t.publish(c);
554
+ t.publish(a);
479
555
  }
480
556
  }
481
557
  /**
@@ -496,7 +572,7 @@ class Y {
496
572
  };
497
573
  }
498
574
  }
499
- class H {
575
+ class Y {
500
576
  //------------------------------------------------------------------------------------------------------------------
501
577
  /**
502
578
  * Create a new toggle binding
@@ -506,7 +582,7 @@ class H {
506
582
  * @param reader - Input reader to read values from
507
583
  * @param options - Binding configuration options
508
584
  */
509
- constructor(e, t, s, i = {}) {
585
+ constructor(e, t, i, s = {}) {
510
586
  n(this, "type", "toggle");
511
587
  n(this, "action");
512
588
  n(this, "context");
@@ -521,7 +597,7 @@ class H {
521
597
  // State tracking
522
598
  n(this, "_lastDigitalState", !1);
523
599
  n(this, "_toggleState");
524
- this.action = e, this.deviceID = t, this.reader = s, this.context = i.context, this._invert = i.invert ?? !1, this._threshold = i.threshold ?? 0.5, this._initialState = i.initialState ?? !1, this._toggleState = this._initialState, this._onValue = i.onValue ?? !0, this._offValue = i.offValue ?? !1;
600
+ this.action = e, this.deviceID = t, this.reader = i, this.context = s.context, this._invert = s.invert ?? !1, this._threshold = s.threshold ?? 0.5, this._initialState = s.initialState ?? !1, this._toggleState = this._initialState, this._onValue = s.onValue ?? !0, this._offValue = s.offValue ?? !1;
525
601
  }
526
602
  //------------------------------------------------------------------------------------------------------------------
527
603
  // Public Getters
@@ -590,8 +666,8 @@ class H {
590
666
  * @param eventBus - Event bus to emit action events to
591
667
  */
592
668
  process(e, t) {
593
- const s = this.reader.getValue(e) ?? !1, i = typeof s == "boolean" ? s : s >= this._threshold, o = this._invert ? !i && this._lastDigitalState : i && !this._lastDigitalState;
594
- this._lastDigitalState = i, o && (this._toggleState = !this._toggleState, t.publish({
669
+ const i = this.reader.getValue(e) ?? !1, s = typeof i == "boolean" ? i : i >= this._threshold, o = this._invert ? !s && this._lastDigitalState : s && !this._lastDigitalState;
670
+ this._lastDigitalState = s, o && (this._toggleState = !this._toggleState, t.publish({
595
671
  type: `action:${this.action.name}`,
596
672
  payload: {
597
673
  value: this.value,
@@ -625,7 +701,7 @@ class H {
625
701
  };
626
702
  }
627
703
  }
628
- class X {
704
+ class j {
629
705
  //------------------------------------------------------------------------------------------------------------------
630
706
  /**
631
707
  * Create a new value binding
@@ -635,7 +711,7 @@ class X {
635
711
  * @param reader - Input reader to read values from
636
712
  * @param options - Binding configuration options
637
713
  */
638
- constructor(e, t, s, i = {}) {
714
+ constructor(e, t, i, s = {}) {
639
715
  n(this, "type", "value");
640
716
  n(this, "action");
641
717
  n(this, "context");
@@ -653,11 +729,11 @@ class X {
653
729
  n(this, "_max");
654
730
  // State tracking
655
731
  n(this, "_lastValue");
656
- this.action = e, this.deviceID = t, this.reader = s, this.context = i.context, this._scale = i.scale ?? 1, this._offset = i.offset ?? 0, this._invert = i.invert ?? !1, this._emitOnChange = i.emitOnChange ?? !0, this._deadzone = i.deadzone ?? 0, this._onValue = i.onValue ?? !0, this._offValue = i.offValue ?? !1;
732
+ this.action = e, this.deviceID = t, this.reader = i, this.context = s.context, this._scale = s.scale ?? 1, this._offset = s.offset ?? 0, this._invert = s.invert ?? !1, this._emitOnChange = s.emitOnChange ?? !0, this._deadzone = s.deadzone ?? 0, this._onValue = s.onValue ?? !0, this._offValue = s.offValue ?? !1;
657
733
  const o = this.action.type === "analog" ? this.action.minValue ?? Number.NEGATIVE_INFINITY : Number.NEGATIVE_INFINITY;
658
- this._min = i.min ?? o;
659
- const r = this.action.type === "analog" ? this.action.maxValue ?? Number.POSITIVE_INFINITY : Number.POSITIVE_INFINITY;
660
- this._max = i.max ?? r;
734
+ this._min = s.min ?? o;
735
+ const c = this.action.type === "analog" ? this.action.maxValue ?? Number.POSITIVE_INFINITY : Number.POSITIVE_INFINITY;
736
+ this._max = s.max ?? c;
661
737
  }
662
738
  //------------------------------------------------------------------------------------------------------------------
663
739
  /**
@@ -689,13 +765,13 @@ class X {
689
765
  * @returns True if a value was emitted, false otherwise
690
766
  */
691
767
  process(e, t) {
692
- const s = this.reader.getValue(e);
693
- if (s === void 0)
694
- return;
695
- const i = typeof s == "boolean" ? s ? 1 : 0 : s;
768
+ const i = this.reader.getValue(e);
696
769
  if (i === void 0)
697
770
  return;
698
- let o = this._deadzone > 0 && Math.abs(i) < this._deadzone ? 0 : i;
771
+ const s = typeof i == "boolean" ? i ? 1 : 0 : i;
772
+ if (s === void 0)
773
+ return;
774
+ let o = this._deadzone > 0 && Math.abs(s) < this._deadzone ? 0 : s;
699
775
  o = (this._invert ? -o : o) * this._scale + this._offset, o = Math.max(this._min, Math.min(this._max, o)), !(this._emitOnChange && this._lastValue === o) && (this._lastValue = o, t.publish({
700
776
  type: `action:${this.action.name}`,
701
777
  payload: {
@@ -723,7 +799,7 @@ class X {
723
799
  };
724
800
  }
725
801
  }
726
- class w {
802
+ class S {
727
803
  /**
728
804
  * Creates a new KeyboardValueReader
729
805
  *
@@ -765,7 +841,7 @@ class w {
765
841
  * @returns A new KeyboardValueReader instance
766
842
  */
767
843
  static fromString(e, t = {}) {
768
- return new w(e, t);
844
+ return new S(e, t);
769
845
  }
770
846
  /**
771
847
  * Returns a JSON-serializable representation of this keyboard value reader
@@ -815,8 +891,8 @@ class x {
815
891
  return t ? t.pressed : void 0;
816
892
  }
817
893
  case "position": {
818
- const [t, s] = this.sourceKey.split(":");
819
- return !t || !s || t !== "absolute" && t !== "relative" || s !== "x" && s !== "y" ? void 0 : e.position[t][s];
894
+ const [t, i] = this.sourceKey.split(":");
895
+ return !t || !i || t !== "absolute" && t !== "relative" || i !== "x" && i !== "y" ? void 0 : e.position[t][i];
820
896
  }
821
897
  case "wheel": {
822
898
  const t = this.sourceKey === "deltaX" || this.sourceKey === "deltaY" || this.sourceKey === "deltaZ";
@@ -833,12 +909,12 @@ class x {
833
909
  * @returns A new MouseValueReader instance
834
910
  */
835
911
  static fromString(e) {
836
- const [t, ...s] = e.split(":"), i = s.join(":");
837
- if (!t || !i)
912
+ const [t, ...i] = e.split(":"), s = i.join(":");
913
+ if (!t || !s)
838
914
  throw new Error(`Invalid mouse source format: ${e}`);
839
915
  return new x(
840
916
  t,
841
- i
917
+ s
842
918
  );
843
919
  }
844
920
  /**
@@ -854,7 +930,7 @@ class x {
854
930
  };
855
931
  }
856
932
  }
857
- class S {
933
+ class $ {
858
934
  /**
859
935
  * Creates a new GamepadValueReader
860
936
  *
@@ -862,7 +938,7 @@ class S {
862
938
  * @param sourceKey - The specific key for this input type
863
939
  * @param options - Configuration options
864
940
  */
865
- constructor(e, t, s = {}) {
941
+ constructor(e, t, i = {}) {
866
942
  /**
867
943
  * The type of gamepad input
868
944
  */
@@ -883,7 +959,7 @@ class S {
883
959
  * Whether to invert axis values
884
960
  */
885
961
  n(this, "invert");
886
- this.sourceType = e, this.sourceKey = t, this.useAnalogValue = s.useAnalogValue || !1, this.deadzone = s.deadzone || 0.1, this.invert = s.invert || !1;
962
+ this.sourceType = e, this.sourceKey = t, this.useAnalogValue = i.useAnalogValue || !1, this.deadzone = i.deadzone || 0.1, this.invert = i.invert || !1;
887
963
  }
888
964
  /**
889
965
  * Gets the value of the input source based on the current state
@@ -914,12 +990,12 @@ class S {
914
990
  * @returns A new GamepadValueReader instance
915
991
  */
916
992
  static fromString(e, t = {}) {
917
- const [s, i] = e.split(":");
918
- if (!s || !i)
993
+ const [i, s] = e.split(":");
994
+ if (!i || !s)
919
995
  throw new Error(`Invalid gamepad source format: ${e}`);
920
- return new S(
921
- s,
996
+ return new $(
922
997
  i,
998
+ s,
923
999
  t
924
1000
  );
925
1001
  }
@@ -941,7 +1017,7 @@ class S {
941
1017
  };
942
1018
  }
943
1019
  }
944
- class j {
1020
+ class X {
945
1021
  /**
946
1022
  * Creates an instance of BindingManager.
947
1023
  *
@@ -963,8 +1039,8 @@ class j {
963
1039
  n(this, "_eventBus");
964
1040
  /** Logger instance */
965
1041
  n(this, "_log");
966
- this._eventBus = e, this._eventBus.subscribe("input:changed", (s) => {
967
- s.payload && this.$handleInput(s.payload.device, s.payload.state);
1042
+ this._eventBus = e, this._eventBus.subscribe("input:changed", (i) => {
1043
+ i.payload && this.$handleInput(i.payload.device, i.payload.state);
968
1044
  }), this._log = (t == null ? void 0 : t.getLogger("BindingManager")) || new g("BindingManager"), this._log.debug("BindingManager initialized");
969
1045
  }
970
1046
  //------------------------------------------------------------------------------------------------------------------
@@ -987,11 +1063,11 @@ class j {
987
1063
  * @returns The context object
988
1064
  */
989
1065
  _getOrCreateContext(e, t = !0) {
990
- let s = this._contexts.get(e);
991
- return s || (s = {
1066
+ let i = this._contexts.get(e);
1067
+ return i || (i = {
992
1068
  name: e,
993
1069
  exclusive: t
994
- }, this._contexts.set(e, s), this._log.debug(`Auto-created context "${e}" (exclusive: ${t})`)), s;
1070
+ }, this._contexts.set(e, i), this._log.debug(`Auto-created context "${e}" (exclusive: ${t})`)), i;
995
1071
  }
996
1072
  /**
997
1073
  * Deactivate all exclusive contexts except the specified one
@@ -1001,11 +1077,11 @@ class j {
1001
1077
  */
1002
1078
  _deactivateExclusiveContexts(e) {
1003
1079
  const t = [];
1004
- for (const s of this._activeContexts) {
1005
- if (s === e)
1080
+ for (const i of this._activeContexts) {
1081
+ if (i === e)
1006
1082
  continue;
1007
- const i = this._contexts.get(s);
1008
- i != null && i.exclusive && (this._activeContexts.delete(s), t.push(s));
1083
+ const s = this._contexts.get(i);
1084
+ s != null && s.exclusive && (this._activeContexts.delete(i), t.push(i));
1009
1085
  }
1010
1086
  return t;
1011
1087
  }
@@ -1019,33 +1095,33 @@ class j {
1019
1095
  const t = this._actions.get(e.action);
1020
1096
  if (!t)
1021
1097
  return this._log.warn(`Cannot create binding: Action "${e.action}" not found.`), null;
1022
- const { deviceID: s, ...i } = e.input;
1098
+ const { deviceID: i, ...s } = e.input;
1023
1099
  switch (e.type) {
1024
1100
  case "trigger":
1025
- return new Y(
1101
+ return new J(
1026
1102
  t,
1027
- s,
1028
- this._createInputSourceFromDefinition(i),
1103
+ i,
1104
+ this._createInputSourceFromDefinition(s),
1029
1105
  {
1030
1106
  ...e.options || {},
1031
1107
  context: e.context
1032
1108
  }
1033
1109
  );
1034
1110
  case "toggle":
1035
- return new H(
1111
+ return new Y(
1036
1112
  t,
1037
- s,
1038
- this._createInputSourceFromDefinition(i),
1113
+ i,
1114
+ this._createInputSourceFromDefinition(s),
1039
1115
  {
1040
1116
  ...e.options || {},
1041
1117
  context: e.context
1042
1118
  }
1043
1119
  );
1044
1120
  case "value":
1045
- return new X(
1121
+ return new j(
1046
1122
  t,
1047
- s,
1048
- this._createInputSourceFromDefinition(i),
1123
+ i,
1124
+ this._createInputSourceFromDefinition(s),
1049
1125
  {
1050
1126
  ...e.options || {},
1051
1127
  context: e.context
@@ -1065,7 +1141,7 @@ class j {
1065
1141
  _createInputSourceFromDefinition(e) {
1066
1142
  switch (e.type) {
1067
1143
  case "keyboard":
1068
- return new w(
1144
+ return new S(
1069
1145
  e.sourceKey,
1070
1146
  e.options
1071
1147
  );
@@ -1082,7 +1158,7 @@ class j {
1082
1158
  const t = e.sourceType;
1083
1159
  if (!(t === "button" || t === "axis"))
1084
1160
  throw new Error(`Invalid gamepad source type: ${t}`);
1085
- return new S(
1161
+ return new $(
1086
1162
  t,
1087
1163
  e.sourceKey,
1088
1164
  e.options
@@ -1102,10 +1178,10 @@ class j {
1102
1178
  * @param state - Current input state
1103
1179
  */
1104
1180
  $handleInput(e, t) {
1105
- const s = this._bindings.get(e.id);
1106
- if (!(!s || s.length === 0) && !(this._activeContexts.size === 0 && s.some((i) => i.context)))
1107
- for (const i of s)
1108
- this._isBindingContextActive(i) && i.process(t, this._eventBus);
1181
+ const i = this._bindings.get(e.id);
1182
+ if (!(!i || i.length === 0) && !(this._activeContexts.size === 0 && i.some((s) => s.context)))
1183
+ for (const s of i)
1184
+ this._isBindingContextActive(s) && s.process(t, this._eventBus);
1109
1185
  }
1110
1186
  //------------------------------------------------------------------------------------------------------------------
1111
1187
  // Action Management API
@@ -1145,8 +1221,8 @@ class j {
1145
1221
  * @returns The registered context
1146
1222
  */
1147
1223
  registerContext(e, t = !0) {
1148
- const s = this._getOrCreateContext(e, t);
1149
- return s.exclusive !== t && (s.exclusive = t, this._log.info(`Updated context "${e}" exclusivity: ${t}`)), s;
1224
+ const i = this._getOrCreateContext(e, t);
1225
+ return i.exclusive !== t && (i.exclusive = t, this._log.info(`Updated context "${e}" exclusivity: ${t}`)), i;
1150
1226
  }
1151
1227
  /**
1152
1228
  * Activates a context, enabling all bindings associated with it.
@@ -1155,14 +1231,14 @@ class j {
1155
1231
  * @param contextName - The name of the context to activate
1156
1232
  */
1157
1233
  activateContext(e) {
1158
- const s = this._getOrCreateContext(e).exclusive;
1159
- this._log.debug(`Activating context "${e}" (exclusive: ${s})`);
1160
- const i = this._activeContexts.has(e);
1161
- if (s) {
1234
+ const i = this._getOrCreateContext(e).exclusive;
1235
+ this._log.debug(`Activating context "${e}" (exclusive: ${i})`);
1236
+ const s = this._activeContexts.has(e);
1237
+ if (i) {
1162
1238
  const o = this._deactivateExclusiveContexts(e);
1163
1239
  o.length > 0 && this._log.info(`Deactivated exclusive contexts: ${o.join(", ")}`);
1164
1240
  }
1165
- i || (this._activeContexts.add(e), this._log.info(`Context "${e}" activated${s ? " as exclusive" : ""}`));
1241
+ s || (this._activeContexts.add(e), this._log.info(`Context "${e}" activated${i ? " as exclusive" : ""}`));
1166
1242
  }
1167
1243
  /**
1168
1244
  * Deactivates a context, disabling all bindings associated with it
@@ -1209,7 +1285,7 @@ class j {
1209
1285
  */
1210
1286
  $registerBinding(e) {
1211
1287
  var t;
1212
- if (!J.includes(e.type))
1288
+ if (!N.includes(e.type))
1213
1289
  throw new Error(`Invalid binding type: ${e.type}`);
1214
1290
  e.context && !this._contexts.has(e.context) && this.registerContext(e.context), this._bindings.has(e.deviceID) || this._bindings.set(e.deviceID, []), (t = this._bindings.get(e.deviceID)) == null || t.push(e), this._log.debug(`Registered ${e.type} binding for "${e.action.name}" in context "${e.context || null}"`);
1215
1291
  }
@@ -1230,15 +1306,15 @@ class j {
1230
1306
  */
1231
1307
  unregisterBindings(e, t = null) {
1232
1308
  this._log.debug(`Unregistering all bindings for action "${e}" in context "${t}"`);
1233
- let s = 0;
1234
- for (const [i, o] of this._bindings.entries()) {
1235
- const r = o.filter((c) => {
1236
- const h = c.context || null, u = c.action.name !== e || h !== t;
1237
- return u || s++, u;
1309
+ let i = 0;
1310
+ for (const [s, o] of this._bindings.entries()) {
1311
+ const c = o.filter((a) => {
1312
+ const h = a.context || null, d = a.action.name !== e || h !== t;
1313
+ return d || i++, d;
1238
1314
  });
1239
- r.length !== o.length && this._bindings.set(i, r);
1315
+ c.length !== o.length && this._bindings.set(s, c);
1240
1316
  }
1241
- this._log.info(`Removed ${s} bindings for action "${e}" in context "${t}"`);
1317
+ this._log.info(`Removed ${i} bindings for action "${e}" in context "${t}"`);
1242
1318
  }
1243
1319
  /**
1244
1320
  * Gets all bindings for a specific action
@@ -1248,13 +1324,13 @@ class j {
1248
1324
  * @returns Array of bindings that match the criteria
1249
1325
  */
1250
1326
  getBindingsForAction(e, t) {
1251
- const s = [];
1252
- for (const i of this._bindings.values())
1253
- for (const o of i) {
1254
- const r = o.context || null;
1255
- o.action.name === e && (!t || r === t) && s.push(o);
1327
+ const i = [];
1328
+ for (const s of this._bindings.values())
1329
+ for (const o of s) {
1330
+ const c = o.context || null;
1331
+ o.action.name === e && (!t || c === t) && i.push(o);
1256
1332
  }
1257
- return s;
1333
+ return i;
1258
1334
  }
1259
1335
  //------------------------------------------------------------------------------------------------------------------
1260
1336
  // Configuration Management API
@@ -1266,24 +1342,24 @@ class j {
1266
1342
  */
1267
1343
  exportConfiguration() {
1268
1344
  this._log.debug("Exporting binding configuration");
1269
- const e = [...this._actions.values()].map((i) => i.type === "analog" ? {
1270
- name: i.name,
1271
- type: i.type,
1272
- minValue: i.minValue ?? 0,
1273
- maxValue: i.maxValue ?? 1
1274
- } : i), t = [];
1275
- for (const i of this._bindings.values())
1276
- for (const o of i)
1345
+ const e = [...this._actions.values()].map((s) => s.type === "analog" ? {
1346
+ name: s.name,
1347
+ type: s.type,
1348
+ minValue: s.minValue ?? 0,
1349
+ maxValue: s.maxValue ?? 1
1350
+ } : s), t = [];
1351
+ for (const s of this._bindings.values())
1352
+ for (const o of s)
1277
1353
  t.push(o.toJSON());
1278
- const s = [...this._contexts.values()].map((i) => ({
1279
- name: i.name,
1280
- exclusive: i.exclusive,
1281
- active: this._activeContexts.has(i.name)
1354
+ const i = [...this._contexts.values()].map((s) => ({
1355
+ name: s.name,
1356
+ exclusive: s.exclusive,
1357
+ active: this._activeContexts.has(s.name)
1282
1358
  }));
1283
- return this._log.info(`Configuration exported: ${e.length} actions, ${t.length} bindings, ${s.length} contexts`), {
1359
+ return this._log.info(`Configuration exported: ${e.length} actions, ${t.length} bindings, ${i.length} contexts`), {
1284
1360
  actions: e,
1285
1361
  bindings: t,
1286
- contexts: s
1362
+ contexts: i
1287
1363
  };
1288
1364
  }
1289
1365
  /**
@@ -1300,29 +1376,36 @@ class j {
1300
1376
  for (const t of e.bindings)
1301
1377
  try {
1302
1378
  this.registerBinding(t);
1303
- } catch (s) {
1304
- s instanceof Error && this._log.error(`Failed to import binding for action "${t.action}": ${s.message}`);
1379
+ } catch (i) {
1380
+ i instanceof Error && this._log.error(`Failed to import binding for action "${t.action}": ${i.message}`);
1305
1381
  }
1306
1382
  this._log.info(`Configuration imported: ${e.actions.length} actions, ${e.bindings.length} bindings, ${e.contexts.length} contexts`);
1307
1383
  }
1384
+ /**
1385
+ * Tears down the binding manager and cleans up any resources
1386
+ */
1387
+ async $teardown() {
1388
+ return this._log.info("Tearing down BindingManager"), this._bindings.clear(), this._actions.clear(), this._contexts.clear(), this._activeContexts.clear(), this._log.info("BindingManager torn down successfully"), Promise.resolve();
1389
+ }
1308
1390
  }
1309
- function A() {
1391
+ function w() {
1310
1392
  return typeof window < "u" && typeof window.document < "u";
1311
1393
  }
1312
- function $() {
1313
- return A() && !!window.navigator.gpu;
1394
+ function k() {
1395
+ return w() && !!window.navigator.gpu;
1314
1396
  }
1315
1397
  class Z {
1316
1398
  //------------------------------------------------------------------------------------------------------------------
1317
- constructor(e, t, s, i, o) {
1399
+ constructor(e, t, i, s, o) {
1318
1400
  n(this, "_engine");
1319
1401
  n(this, "_entityManager");
1320
1402
  n(this, "_inputManager");
1321
1403
  n(this, "_sceneEngine");
1322
1404
  n(this, "_currentScene", null);
1323
1405
  n(this, "_log");
1406
+ n(this, "_boundResizeHandler");
1324
1407
  n(this, "started", !1);
1325
- this._engine = e, this._sceneEngine = t, this._entityManager = s, this._inputManager = i, this._log = (o == null ? void 0 : o.getLogger("GameManager")) || new g("GameManager"), A() && window.addEventListener("resize", this._resizeHandler.bind(this));
1408
+ this._engine = e, this._sceneEngine = t, this._entityManager = i, this._inputManager = s, this._log = (o == null ? void 0 : o.getLogger("GameManager")) || new g("GameManager"), this._boundResizeHandler = this._resizeHandler.bind(this), w() && window.addEventListener("resize", this._boundResizeHandler);
1326
1409
  }
1327
1410
  _renderLoop() {
1328
1411
  const e = this._engine.getDeltaTime();
@@ -1340,8 +1423,15 @@ class Z {
1340
1423
  async stop() {
1341
1424
  this.started = !1, this._engine.stopRenderLoop(), this._log.info("SkewedAspect Game Engine stopped successfully");
1342
1425
  }
1426
+ /**
1427
+ * Tears down any resources held by the GameManager
1428
+ * This handles unregistering event listeners and any other cleanup
1429
+ */
1430
+ async $teardown() {
1431
+ this._log.info("Tearing down GameManager"), this.started && await this.stop(), w() && window.removeEventListener("resize", this._boundResizeHandler), this._log.info("GameManager torn down successfully");
1432
+ }
1343
1433
  }
1344
- class ue {
1434
+ class de {
1345
1435
  constructor() {
1346
1436
  n(this, "entity", null);
1347
1437
  }
@@ -1369,7 +1459,7 @@ class q {
1369
1459
  * @param behaviors - An array of behaviors to attach to the entity.
1370
1460
  * @param eventBus
1371
1461
  */
1372
- constructor(e, t, s, i) {
1462
+ constructor(e, t, i, s) {
1373
1463
  /** The unique identifier of the entity. */
1374
1464
  n(this, "id");
1375
1465
  /** The type of the entity. */
@@ -1382,8 +1472,8 @@ class q {
1382
1472
  n(this, "eventBus");
1383
1473
  /** The event subscriptions for the entity. */
1384
1474
  n(this, "subscriptions", /* @__PURE__ */ new Map());
1385
- this.id = crypto.randomUUID(), this.type = e, this.state = s, this.eventBus = t;
1386
- for (const o of i)
1475
+ this.id = crypto.randomUUID(), this.type = e, this.state = i, this.eventBus = t;
1476
+ for (const o of s)
1387
1477
  this.attachBehavior(new o());
1388
1478
  }
1389
1479
  //------------------------------------------------------------------------------------------------------------------
@@ -1405,8 +1495,8 @@ class q {
1405
1495
  */
1406
1496
  $update(e) {
1407
1497
  var t;
1408
- for (const s of this.behaviors.values())
1409
- (t = s.update) == null || t.call(s, e, this.state);
1498
+ for (const i of this.behaviors.values())
1499
+ (t = i.update) == null || t.call(i, e, this.state);
1410
1500
  }
1411
1501
  /**
1412
1502
  * Destroys the entity by calling the destroy method of its behaviors.
@@ -1432,12 +1522,12 @@ class q {
1432
1522
  if (this.behaviors.has(e.name))
1433
1523
  throw new Error(`Behavior ${e.name} is already attached to this entity.`);
1434
1524
  for (const t of e.eventSubscriptions) {
1435
- const s = this.subscriptions.get(t);
1436
- if (s)
1437
- s.count++;
1525
+ const i = this.subscriptions.get(t);
1526
+ if (i)
1527
+ i.count++;
1438
1528
  else {
1439
- const i = this.eventBus.subscribe(t, this.$processEvent.bind(this));
1440
- this.subscriptions.set(t, { count: 1, unsubscribe: i });
1529
+ const s = this.eventBus.subscribe(t, this.$processEvent.bind(this));
1530
+ this.subscriptions.set(t, { count: 1, unsubscribe: s });
1441
1531
  }
1442
1532
  }
1443
1533
  this.behaviors.set(e.name, e), e.$setEntity(this);
@@ -1449,9 +1539,9 @@ class q {
1449
1539
  detachBehavior(e) {
1450
1540
  const t = this.behaviors.get(e);
1451
1541
  if (t) {
1452
- for (const s of t.eventSubscriptions) {
1453
- const i = this.subscriptions.get(s);
1454
- i && (i.count--, i.count <= 0 && (i.unsubscribe(), this.subscriptions.delete(s)));
1542
+ for (const i of t.eventSubscriptions) {
1543
+ const s = this.subscriptions.get(i);
1544
+ s && (s.count--, s.count <= 0 && (s.unsubscribe(), this.subscriptions.delete(i)));
1455
1545
  }
1456
1546
  this.behaviors.delete(t.name), t.$setEntity(null);
1457
1547
  }
@@ -1464,7 +1554,7 @@ class Q {
1464
1554
  * @param logger - The logging utility to use
1465
1555
  * @param bindingManager - The binding manager for registering actions
1466
1556
  */
1467
- constructor(e, t, s) {
1557
+ constructor(e, t, i) {
1468
1558
  /** The event bus for the entity manager. */
1469
1559
  n(this, "eventBus");
1470
1560
  /** A map of entities managed by the entity manager. */
@@ -1475,7 +1565,7 @@ class Q {
1475
1565
  n(this, "bindingManager");
1476
1566
  /** Logger instance */
1477
1567
  n(this, "_log");
1478
- this.eventBus = e, this.bindingManager = s, this._log = (t == null ? void 0 : t.getLogger("EntityManager")) || new g("EntityManager"), this._log.info("EntityManager initialized");
1568
+ this.eventBus = e, this.bindingManager = i, this._log = (t == null ? void 0 : t.getLogger("EntityManager")) || new g("EntityManager"), this._log.info("EntityManager initialized");
1479
1569
  }
1480
1570
  //------------------------------------------------------------------------------------------------------------------
1481
1571
  // Private Methods
@@ -1497,14 +1587,14 @@ class Q {
1497
1587
  if (e.actions)
1498
1588
  for (const t of e.actions)
1499
1589
  try {
1500
- const s = this.bindingManager.getAction(t.name);
1501
- s ? this._areActionsCompatible(s, t) ? this._log.trace(
1590
+ const i = this.bindingManager.getAction(t.name);
1591
+ i ? this._areActionsCompatible(i, t) ? this._log.trace(
1502
1592
  `Action "${t.name}" already registered with compatible options, skipping registration`
1503
1593
  ) : this._log.warn(
1504
- `Action "${t.name}" already registered with different options. Entity "${e.type}" requires: ${JSON.stringify(t)}, but found: ${JSON.stringify(s)}`
1594
+ `Action "${t.name}" already registered with different options. Entity "${e.type}" requires: ${JSON.stringify(t)}, but found: ${JSON.stringify(i)}`
1505
1595
  ) : (this._log.debug(`Registering action "${t.name}" from entity type "${e.type}"`), this.bindingManager.registerAction(t));
1506
- } catch (s) {
1507
- this._log.debug(`Failed to register action "${t.name}": ${s instanceof Error ? s.message : String(s)}`);
1596
+ } catch (i) {
1597
+ this._log.debug(`Failed to register action "${t.name}": ${i instanceof Error ? i.message : String(i)}`);
1508
1598
  }
1509
1599
  }
1510
1600
  $frameUpdate(e) {
@@ -1528,31 +1618,51 @@ class Q {
1528
1618
  * @param initialState - The initial state of the entity.
1529
1619
  * @returns The created entity.
1530
1620
  */
1531
- createEntity(e, t = {}) {
1532
- var r;
1621
+ async createEntity(e, t = {}) {
1622
+ var c;
1533
1623
  this._log.debug(`Creating entity of type: ${e}`);
1534
- const s = this.entityDefinitions.get(e);
1535
- if (!s) {
1536
- const c = `Entity type ${e} is not registered.`;
1537
- throw this._log.error(c), new Error(c);
1624
+ const i = this.entityDefinitions.get(e);
1625
+ if (!i) {
1626
+ const a = `Entity type ${e} is not registered.`;
1627
+ throw this._log.error(a), new Error(a);
1628
+ }
1629
+ this._log.trace(`Using entity definition with ${((c = i.behaviors) == null ? void 0 : c.length) || 0} behaviors`);
1630
+ let s = { ...i.defaultState, ...t };
1631
+ if (i.onBeforeCreate) {
1632
+ this._log.trace(`Calling onBeforeCreate hook for entity type: ${e}`);
1633
+ const a = await i.onBeforeCreate(s);
1634
+ a !== void 0 && (s = a);
1538
1635
  }
1539
- this._log.trace(`Using entity definition with ${((r = s.behaviors) == null ? void 0 : r.length) || 0} behaviors`);
1540
- const i = { ...s.defaultState, ...t }, o = new q(
1541
- s.type,
1636
+ const o = new q(
1637
+ i.type,
1542
1638
  this.eventBus,
1543
- i,
1544
- s.behaviors
1639
+ s,
1640
+ i.behaviors
1545
1641
  );
1546
- return this.entities.set(o.id, o), this._log.debug(`Entity created with ID: ${o.id}`), o;
1642
+ if (this.entities.set(o.id, o), this._log.debug(`Entity created with ID: ${o.id}`), i.onCreate) {
1643
+ this._log.trace(`Calling onCreate hook for entity type: ${e}`);
1644
+ const a = await i.onCreate(o.state);
1645
+ a !== void 0 && (o.state = a);
1646
+ }
1647
+ return o;
1547
1648
  }
1548
1649
  /**
1549
1650
  * Destroys the entity with the given ID.
1550
1651
  * @param entityID - The ID of the entity to destroy.
1551
1652
  */
1552
- destroyEntity(e) {
1653
+ async destroyEntity(e) {
1553
1654
  this._log.debug(`Destroying entity: ${e}`);
1554
1655
  const t = this.entities.get(e);
1555
- t ? (t.$destroy(), this.entities.delete(e), this._log.debug(`Entity ${e} destroyed`)) : this._log.warn(`Attempted to destroy non-existent entity: ${e}`);
1656
+ if (t) {
1657
+ const i = this.entityDefinitions.get(t.type);
1658
+ if (i != null && i.onBeforeDestroy) {
1659
+ this._log.trace(`Calling onBeforeDestroy hook for entity: ${e}`);
1660
+ const s = await i.onBeforeDestroy(t.state);
1661
+ s !== void 0 && (t.state = s);
1662
+ }
1663
+ await t.$destroy(), i != null && i.onDestroy && (this._log.trace(`Calling onDestroy hook for entity: ${e}`), await i.onDestroy(t.state)), this.entities.delete(e), this._log.debug(`Entity ${e} destroyed`);
1664
+ } else
1665
+ this._log.warn(`Attempted to destroy non-existent entity: ${e}`);
1556
1666
  }
1557
1667
  /**
1558
1668
  * Gets the entity with the given ID.
@@ -1576,6 +1686,21 @@ class Q {
1576
1686
  removeEntity(e) {
1577
1687
  this._log.debug(`Removing entity: ${e}`), this.entities.get(e) ? (this.entities.delete(e), this._log.debug(`Entity ${e} removed`)) : this._log.warn(`Attempted to remove non-existent entity: ${e}`);
1578
1688
  }
1689
+ /**
1690
+ * Tears down all entities and releases resources
1691
+ * @returns A promise that resolves when all entities have been destroyed
1692
+ */
1693
+ async $teardown() {
1694
+ this._log.info(`Tearing down EntityManager with ${this.entities.size} entities`);
1695
+ const e = [...this.entities.keys()];
1696
+ for (const t of e)
1697
+ try {
1698
+ await this.destroyEntity(t);
1699
+ } catch (i) {
1700
+ this._log.error(`Error destroying entity ${t}: ${i}`);
1701
+ }
1702
+ this.entityDefinitions.clear(), this._log.info("EntityManager torn down successfully");
1703
+ }
1579
1704
  }
1580
1705
  class ee {
1581
1706
  //------------------------------------------------------------------------------------------------------------------
@@ -1631,10 +1756,10 @@ class ee {
1631
1756
  return { ...this._keyboardDevice };
1632
1757
  }
1633
1758
  /**
1634
- * Destroy the keyboard resource access and clean up event listeners
1759
+ * Tears down the keyboard resource access and cleans up event listeners
1635
1760
  */
1636
- destroy() {
1637
- window.removeEventListener("keydown", this._handleKeyDown), window.removeEventListener("keyup", this._handleKeyUp);
1761
+ $teardown() {
1762
+ return window.removeEventListener("keydown", this._handleKeyDown), window.removeEventListener("keyup", this._handleKeyUp), Promise.resolve();
1638
1763
  }
1639
1764
  //------------------------------------------------------------------------------------------------------------------
1640
1765
  // Private Methods
@@ -1652,13 +1777,13 @@ class ee {
1652
1777
  this._keysState[e.code] = !0;
1653
1778
  const t = {};
1654
1779
  t[e.code] = !0;
1655
- const s = {
1780
+ const i = {
1656
1781
  type: "keyboard",
1657
1782
  keys: { ...this._keysState },
1658
1783
  delta: t,
1659
1784
  event: e
1660
1785
  };
1661
- this._notifyInputChanged(s);
1786
+ this._notifyInputChanged(i);
1662
1787
  }
1663
1788
  /**
1664
1789
  * Handle keyboard key up events
@@ -1667,13 +1792,13 @@ class ee {
1667
1792
  this._keysState[e.code] = !1;
1668
1793
  const t = {};
1669
1794
  t[e.code] = !1;
1670
- const s = {
1795
+ const i = {
1671
1796
  type: "keyboard",
1672
1797
  keys: { ...this._keysState },
1673
1798
  delta: t,
1674
1799
  event: e
1675
1800
  };
1676
- this._notifyInputChanged(s);
1801
+ this._notifyInputChanged(i);
1677
1802
  }
1678
1803
  /**
1679
1804
  * Notify subscribers of device connected event
@@ -1761,10 +1886,10 @@ class te {
1761
1886
  return { ...this._mouseDevice };
1762
1887
  }
1763
1888
  /**
1764
- * Destroy the mouse resource access and clean up event listeners
1889
+ * Tears down the mouse resource access and cleans up event listeners
1765
1890
  */
1766
- destroy() {
1767
- this._targetElement.removeEventListener("mousedown", this._handleMouseDown), this._targetElement.removeEventListener("mouseup", this._handleMouseUp), this._targetElement.removeEventListener("mousemove", this._handleMouseMove), this._targetElement.removeEventListener("wheel", this._handleMouseWheel);
1891
+ $teardown() {
1892
+ return this._targetElement.removeEventListener("mousedown", this._handleMouseDown), this._targetElement.removeEventListener("mouseup", this._handleMouseUp), this._targetElement.removeEventListener("mousemove", this._handleMouseMove), this._targetElement.removeEventListener("wheel", this._handleMouseWheel), Promise.resolve();
1768
1893
  }
1769
1894
  //------------------------------------------------------------------------------------------------------------------
1770
1895
  // Private Methods
@@ -1779,10 +1904,10 @@ class te {
1779
1904
  * Handle mouse button down events
1780
1905
  */
1781
1906
  _handleMouseDown(e) {
1782
- const t = `button-${e.button}`, s = {
1907
+ const t = `button-${e.button}`, i = {
1783
1908
  pressed: !0
1784
1909
  };
1785
- this._buttonState[t] = s, this._notifyInputChanged({
1910
+ this._buttonState[t] = i, this._notifyInputChanged({
1786
1911
  type: "mouse",
1787
1912
  event: e,
1788
1913
  buttons: { ...this._buttonState },
@@ -1794,10 +1919,10 @@ class te {
1794
1919
  * Handle mouse button up events
1795
1920
  */
1796
1921
  _handleMouseUp(e) {
1797
- const t = `button-${e.button}`, s = {
1922
+ const t = `button-${e.button}`, i = {
1798
1923
  pressed: !1
1799
1924
  };
1800
- this._buttonState[t] = s, this._notifyInputChanged({
1925
+ this._buttonState[t] = i, this._notifyInputChanged({
1801
1926
  type: "mouse",
1802
1927
  event: e,
1803
1928
  buttons: { ...this._buttonState },
@@ -1857,7 +1982,7 @@ class te {
1857
1982
  this._onInputChanged && this._onInputChanged(this._mouseDevice, e);
1858
1983
  }
1859
1984
  }
1860
- class se {
1985
+ class ie {
1861
1986
  //------------------------------------------------------------------------------------------------------------------
1862
1987
  /**
1863
1988
  * Create a new GamepadResourceAccess
@@ -1911,10 +2036,10 @@ class se {
1911
2036
  getStates() {
1912
2037
  const e = {};
1913
2038
  return Object.keys(this._buttonStates).forEach((t) => {
1914
- const s = Number(t), i = this._buttonStates[s] || {}, o = this._axesStates[s] || {};
1915
- e[s] = {
2039
+ const i = Number(t), s = this._buttonStates[i] || {}, o = this._axesStates[i] || {};
2040
+ e[i] = {
1916
2041
  type: "gamepad",
1917
- buttons: { ...i },
2042
+ buttons: { ...s },
1918
2043
  axes: { ...o }
1919
2044
  };
1920
2045
  }), e;
@@ -1934,11 +2059,11 @@ class se {
1934
2059
  * @param index - The index of the gamepad state to get
1935
2060
  */
1936
2061
  getState(e) {
1937
- const t = this._buttonStates[e], s = this._axesStates[e];
1938
- return !t && !s ? null : {
2062
+ const t = this._buttonStates[e], i = this._axesStates[e];
2063
+ return !t && !i ? null : {
1939
2064
  type: "gamepad",
1940
2065
  buttons: t ? { ...t } : {},
1941
- axes: s ? { ...s } : {}
2066
+ axes: i ? { ...i } : {}
1942
2067
  };
1943
2068
  }
1944
2069
  /**
@@ -1951,46 +2076,46 @@ class se {
1951
2076
  for (const t of e) {
1952
2077
  if (!t)
1953
2078
  continue;
1954
- const s = t.index;
1955
- if (!this._gamepadDevices[s]) {
2079
+ const i = t.index;
2080
+ if (!this._gamepadDevices[i]) {
1956
2081
  this._handleGamepadConnected(t);
1957
2082
  continue;
1958
2083
  }
1959
- const i = this._gamepadDevices[s];
1960
- if (!i)
2084
+ const s = this._gamepadDevices[i];
2085
+ if (!s)
1961
2086
  continue;
1962
- const o = this._buttonStates[s] || {}, r = this._axesStates[s] || {}, c = {};
2087
+ const o = this._buttonStates[i] || {}, c = this._axesStates[i] || {}, a = {};
1963
2088
  let h = !1;
1964
- t.buttons.forEach((d, p) => {
2089
+ t.buttons.forEach((u, p) => {
1965
2090
  const l = `button-${p}`, f = {
1966
- pressed: d.pressed,
1967
- touched: d.touched,
1968
- value: d.value
2091
+ pressed: u.pressed,
2092
+ touched: u.touched,
2093
+ value: u.value
1969
2094
  };
1970
- c[l] = f;
2095
+ a[l] = f;
1971
2096
  const y = o[l];
1972
2097
  (!y || y.pressed !== f.pressed || y.touched !== f.touched || y.value !== f.value) && (h = !0);
1973
2098
  });
1974
- const u = {};
2099
+ const d = {};
1975
2100
  let _ = !1;
1976
- if (t.axes.forEach((d, p) => {
2101
+ if (t.axes.forEach((u, p) => {
1977
2102
  const l = `axis-${p}`;
1978
- u[l] = d, r[l] !== d && (_ = !0);
1979
- }), this._buttonStates[s] = c, this._axesStates[s] = u, h || _) {
1980
- const d = {
2103
+ d[l] = u, c[l] !== u && (_ = !0);
2104
+ }), this._buttonStates[i] = a, this._axesStates[i] = d, h || _) {
2105
+ const u = {
1981
2106
  type: "gamepad",
1982
- buttons: { ...c },
1983
- axes: { ...u }
2107
+ buttons: { ...a },
2108
+ axes: { ...d }
1984
2109
  };
1985
- this._notifyInputChanged(i, d);
2110
+ this._notifyInputChanged(s, u);
1986
2111
  }
1987
2112
  }
1988
2113
  }
1989
2114
  /**
1990
- * Destroy the gamepad resource access and clean up event listeners
2115
+ * Tears down the gamepad resource access and cleans up event listeners
1991
2116
  */
1992
- destroy() {
1993
- window.removeEventListener("gamepadconnected", this._handleGamepadConnected), window.removeEventListener("gamepaddisconnected", this._handleGamepadDisconnected);
2117
+ $teardown() {
2118
+ return window.removeEventListener("gamepadconnected", this._handleGamepadConnected), window.removeEventListener("gamepaddisconnected", this._handleGamepadDisconnected), Promise.resolve();
1994
2119
  }
1995
2120
  //------------------------------------------------------------------------------------------------------------------
1996
2121
  // Private Methods
@@ -2009,32 +2134,32 @@ class se {
2009
2134
  * Handle gamepad connected event
2010
2135
  */
2011
2136
  _handleGamepadConnected(e) {
2012
- const t = e instanceof GamepadEvent ? e.gamepad : e, s = t.index, i = {
2013
- id: `gamepad-${s}`,
2137
+ const t = e instanceof GamepadEvent ? e.gamepad : e, i = t.index, s = {
2138
+ id: `gamepad-${i}`,
2014
2139
  name: t.id,
2015
2140
  type: "gamepad",
2016
2141
  connected: !0,
2017
- index: s,
2142
+ index: i,
2018
2143
  mapping: t.mapping,
2019
2144
  axes: Array.from(t.axes),
2020
2145
  buttons: Array.from(t.buttons)
2021
2146
  };
2022
- this._gamepadDevices[s] = i;
2147
+ this._gamepadDevices[i] = s;
2023
2148
  const o = {};
2024
- Array.from(t.buttons).forEach((c, h) => {
2149
+ Array.from(t.buttons).forEach((a, h) => {
2025
2150
  o[`button-${h}`] = {
2026
- pressed: c.pressed,
2027
- touched: c.touched,
2028
- value: c.value
2151
+ pressed: a.pressed,
2152
+ touched: a.touched,
2153
+ value: a.value
2029
2154
  };
2030
- }), this._buttonStates[s] = o;
2031
- const r = {};
2032
- Array.from(t.axes).forEach((c, h) => {
2033
- r[`axis-${h}`] = c;
2034
- }), this._axesStates[s] = r, this._notifyDeviceConnected(i), this._notifyInputChanged(i, {
2155
+ }), this._buttonStates[i] = o;
2156
+ const c = {};
2157
+ Array.from(t.axes).forEach((a, h) => {
2158
+ c[`axis-${h}`] = a;
2159
+ }), this._axesStates[i] = c, this._notifyDeviceConnected(s), this._notifyInputChanged(s, {
2035
2160
  type: "gamepad",
2036
2161
  buttons: { ...o },
2037
- axes: { ...r },
2162
+ axes: { ...c },
2038
2163
  event: e instanceof GamepadEvent ? e : void 0
2039
2164
  });
2040
2165
  }
@@ -2042,8 +2167,8 @@ class se {
2042
2167
  * Handle gamepad disconnected event
2043
2168
  */
2044
2169
  _handleGamepadDisconnected(e) {
2045
- const s = e.gamepad.index, i = this._gamepadDevices[s];
2046
- i && (i.connected = !1, this._notifyDeviceDisconnected(i), this._gamepadDevices[s] = void 0, this._buttonStates[s] = void 0, this._axesStates[s] = void 0);
2170
+ const i = e.gamepad.index, s = this._gamepadDevices[i];
2171
+ s && (s.connected = !1, this._notifyDeviceDisconnected(s), this._gamepadDevices[i] = void 0, this._buttonStates[i] = void 0, this._axesStates[i] = void 0);
2047
2172
  }
2048
2173
  /**
2049
2174
  * Notify subscribers of device connected event
@@ -2064,7 +2189,7 @@ class se {
2064
2189
  this._onInputChanged && this._onInputChanged(e, t);
2065
2190
  }
2066
2191
  }
2067
- class ie {
2192
+ class se {
2068
2193
  //------------------------------------------------------------------------------------------------------------------
2069
2194
  /**
2070
2195
  * Create a new UserInputManager
@@ -2073,14 +2198,14 @@ class ie {
2073
2198
  * @param canvas - The DOM element to attach input listeners to
2074
2199
  * @param logger - The logging utility to use
2075
2200
  */
2076
- constructor(e, t, s) {
2201
+ constructor(e, t, i) {
2077
2202
  n(this, "_eventBus");
2078
2203
  n(this, "_keyboardRA");
2079
2204
  n(this, "_mouseRA");
2080
2205
  n(this, "_gamepadRA");
2081
2206
  /** Logger instance */
2082
2207
  n(this, "_log");
2083
- this._eventBus = e, this._log = (s == null ? void 0 : s.getLogger("UserInputManager")) || new g("UserInputManager"), this._log.info("Initializing UserInputManager"), this._log.debug("Initializing input resource access classes"), this._keyboardRA = new ee(), this._mouseRA = new te(t), this._gamepadRA = new se(), this._log.debug("Registering input event callbacks"), this._keyboardRA.onDeviceConnected(this._publishDeviceConnected.bind(this)), this._keyboardRA.onInputChanged(this._publishInputChanged.bind(this)), this._mouseRA.onDeviceConnected(this._publishDeviceConnected.bind(this)), this._mouseRA.onInputChanged(this._publishInputChanged.bind(this)), this._gamepadRA.onDeviceConnected(this._publishDeviceConnected.bind(this)), this._gamepadRA.onDeviceDisconnected(this._publishDeviceDisconnected.bind(this)), this._gamepadRA.onInputChanged(this._publishInputChanged.bind(this)), this._log.info("UserInputManager initialized successfully");
2208
+ this._eventBus = e, this._log = (i == null ? void 0 : i.getLogger("UserInputManager")) || new g("UserInputManager"), this._log.info("Initializing UserInputManager"), this._log.debug("Initializing input resource access classes"), this._keyboardRA = new ee(), this._mouseRA = new te(t), this._gamepadRA = new ie(), this._log.debug("Registering input event callbacks"), this._keyboardRA.onDeviceConnected(this._publishDeviceConnected.bind(this)), this._keyboardRA.onInputChanged(this._publishInputChanged.bind(this)), this._mouseRA.onDeviceConnected(this._publishDeviceConnected.bind(this)), this._mouseRA.onInputChanged(this._publishInputChanged.bind(this)), this._gamepadRA.onDeviceConnected(this._publishDeviceConnected.bind(this)), this._gamepadRA.onDeviceDisconnected(this._publishDeviceDisconnected.bind(this)), this._gamepadRA.onInputChanged(this._publishInputChanged.bind(this)), this._log.info("UserInputManager initialized successfully");
2084
2209
  }
2085
2210
  //------------------------------------------------------------------------------------------------------------------
2086
2211
  // Private methods
@@ -2112,7 +2237,7 @@ class ie {
2112
2237
  */
2113
2238
  _publishInputChanged(e, t) {
2114
2239
  this._log.trace(`Input changed: ${e.id}`, t);
2115
- const s = {
2240
+ const i = {
2116
2241
  type: "input:changed",
2117
2242
  payload: {
2118
2243
  deviceId: e.id,
@@ -2120,16 +2245,22 @@ class ie {
2120
2245
  state: t
2121
2246
  }
2122
2247
  };
2123
- this._eventBus.publish(s);
2248
+ this._eventBus.publish(i);
2124
2249
  }
2125
2250
  //------------------------------------------------------------------------------------------------------------------
2126
2251
  // Internal methods
2127
2252
  //------------------------------------------------------------------------------------------------------------------
2128
2253
  /**
2129
- * Destroy the input manager and clean up event listeners
2254
+ * Tears down the input manager and clean up event listeners
2130
2255
  */
2131
- $destroy() {
2132
- this._log.info("Destroying UserInputManager"), this._log.debug("Cleaning up input resource access instances"), this._keyboardRA.destroy(), this._mouseRA.destroy(), this._gamepadRA.destroy(), this._log.info("UserInputManager destroyed");
2256
+ $teardown() {
2257
+ return this._log.info("Tearing down UserInputManager"), this._log.debug("Cleaning up input resource access instances"), Promise.all([
2258
+ this._keyboardRA.$teardown(),
2259
+ this._mouseRA.$teardown(),
2260
+ this._gamepadRA.$teardown()
2261
+ ]).then(() => {
2262
+ this._log.info("UserInputManager torn down successfully");
2263
+ });
2133
2264
  }
2134
2265
  //------------------------------------------------------------------------------------------------------------------
2135
2266
  // Public methods
@@ -2161,9 +2292,9 @@ class ie {
2161
2292
  return this._gamepadRA.getDevice(t);
2162
2293
  } else {
2163
2294
  const t = this.listDevices();
2164
- for (const s of t)
2165
- if (s.id === e)
2166
- return s;
2295
+ for (const i of t)
2296
+ if (i.id === e)
2297
+ return i;
2167
2298
  }
2168
2299
  return this._log.warn(`Device not found: ${e}`), null;
2169
2300
  }
@@ -2174,48 +2305,48 @@ class ie {
2174
2305
  this._gamepadRA.pollGamepads();
2175
2306
  }
2176
2307
  }
2177
- async function M(a, e) {
2178
- const t = new K(a, e);
2308
+ async function M(r, e) {
2309
+ const t = new K(r, e);
2179
2310
  return await t.initAsync(), t;
2180
2311
  }
2181
- function v(a, e) {
2182
- return new U(a, e.antialias, e.options, e.adaptToDeviceRatio);
2312
+ function v(r, e) {
2313
+ return new T(r, e.antialias, e.options, e.adaptToDeviceRatio);
2183
2314
  }
2184
- function ne(a) {
2185
- return new B(a);
2315
+ function ne(r) {
2316
+ return new L(r);
2186
2317
  }
2187
- async function oe(a, e) {
2188
- if (a === null)
2318
+ async function oe(r, e) {
2319
+ if (r === null)
2189
2320
  return console.debug("Using Null Engine"), ne(e);
2190
2321
  const t = e.engine || "auto";
2191
2322
  if (t === "webgpu")
2192
- if ($())
2323
+ if (k())
2193
2324
  try {
2194
- return console.debug("Using forced WebGPU engine"), await M(a, e);
2195
- } catch (s) {
2196
- throw console.error("Forced WebGPU initialization failed:", s), new Error(
2325
+ return console.debug("Using forced WebGPU engine"), await M(r, e);
2326
+ } catch (i) {
2327
+ throw console.error("Forced WebGPU initialization failed:", i), new Error(
2197
2328
  "Forced WebGPU failed to initialize. If WebGPU is required, check browser compatibility."
2198
2329
  );
2199
2330
  }
2200
2331
  else
2201
2332
  throw new Error("WebGPU was forced but is not available in this browser.");
2202
2333
  if (t === "webgl")
2203
- return console.debug("Using forced WebGL engine"), v(a, e);
2204
- if ($())
2334
+ return console.debug("Using forced WebGL engine"), v(r, e);
2335
+ if (k())
2205
2336
  try {
2206
- return console.debug("Using WebGPU"), M(a, e).catch((s) => (console.warn("WebGPU initialization failed, falling back to WebGL:", s), v(a, e)));
2207
- } catch (s) {
2208
- console.warn("WebGPU initialization failed, falling back to WebGL:", s);
2337
+ return console.debug("Using WebGPU"), M(r, e).catch((i) => (console.warn("WebGPU initialization failed, falling back to WebGL:", i), v(r, e)));
2338
+ } catch (i) {
2339
+ console.warn("WebGPU initialization failed, falling back to WebGL:", i);
2209
2340
  }
2210
2341
  else
2211
2342
  console.warn("WebGPU not supported, falling back to WebGL.");
2212
- return console.debug("Using WebGL"), v(a, e);
2343
+ return console.debug("Using WebGL"), v(r, e);
2213
2344
  }
2214
2345
  async function ae() {
2215
- const a = await T();
2216
- return new R(!0, a);
2346
+ const r = await R();
2347
+ return new U(!0, r);
2217
2348
  }
2218
- const de = ["keyboard", "mouse", "gamepad"], le = [
2349
+ const ue = ["keyboard", "mouse", "gamepad"], le = [
2219
2350
  "trace",
2220
2351
  "debug",
2221
2352
  "info",
@@ -2223,30 +2354,30 @@ const de = ["keyboard", "mouse", "gamepad"], le = [
2223
2354
  "error",
2224
2355
  "none"
2225
2356
  ];
2226
- async function ge(a, e, t = {}) {
2227
- const s = new F(t.logLevel || "debug"), i = s.getLogger("SAGE");
2228
- i.info(`Initializing SAGE Game Engine v${m}...`), i.debug("Creating rendering engine...");
2229
- const o = await oe(a, t.renderOptions || {});
2230
- i.debug("Creating physics engine...");
2231
- const r = await ae();
2232
- i.debug("Creating event bus...");
2233
- const c = new O(s);
2234
- i.debug("Creating scene engine...");
2235
- const h = new N(o, r, s);
2236
- i.debug("Creating managers...");
2237
- const u = new ie(c, a, s), _ = new j(c, s), d = new Q(c, s, _), p = new Z(o, h, d, u, s);
2238
- i.info(`SAGE Game Engine v${m} initialized successfully.`), i.debug("Loading entities...");
2357
+ async function ge(r, e, t = {}) {
2358
+ const i = new O(t.logLevel || "debug"), s = i.getLogger("SAGE");
2359
+ s.info(`Initializing SAGE Game Engine v${m}...`), s.debug("Creating rendering engine...");
2360
+ const o = await oe(r, t.renderOptions || {});
2361
+ s.debug("Creating physics engine...");
2362
+ const c = await ae();
2363
+ s.debug("Creating event bus...");
2364
+ const a = new W(i);
2365
+ s.debug("Creating scene engine...");
2366
+ const h = new F(o, c, i);
2367
+ s.debug("Creating managers...");
2368
+ const d = new se(a, r, i), _ = new X(a, i), u = new Q(a, i, _), p = new Z(o, h, u, d, i);
2369
+ s.info(`SAGE Game Engine v${m} initialized successfully.`), s.debug("Loading entities...");
2239
2370
  for (const l of e)
2240
- d.registerEntityDefinition(l);
2241
- if (i.debug("Registering default input bindings..."), t.bindings)
2371
+ u.registerEntityDefinition(l);
2372
+ if (s.debug("Registering default input bindings..."), t.bindings)
2242
2373
  for (const l of t.bindings)
2243
2374
  _.registerBinding(l);
2244
2375
  return new z(
2245
- a,
2246
- o,
2247
2376
  r,
2377
+ o,
2248
2378
  c,
2249
- s,
2379
+ a,
2380
+ i,
2250
2381
  // Engines
2251
2382
  {
2252
2383
  sceneEngine: h
@@ -2254,25 +2385,25 @@ async function ge(a, e, t = {}) {
2254
2385
  // Managers
2255
2386
  {
2256
2387
  bindingManager: _,
2257
- entityManager: d,
2388
+ entityManager: u,
2258
2389
  gameManager: p,
2259
- inputManager: u
2390
+ inputManager: d
2260
2391
  }
2261
2392
  );
2262
2393
  }
2263
2394
  export {
2264
- W as ConsoleBackend,
2395
+ P as ConsoleBackend,
2265
2396
  q as GameEntity,
2266
- ue as GameEntityBehavior,
2267
- O as GameEventBus,
2397
+ de as GameEntityBehavior,
2398
+ W as GameEventBus,
2268
2399
  le as LogLevels,
2269
- F as LoggingUtility,
2270
- P as NullBackend,
2400
+ O as LoggingUtility,
2401
+ H as NullBackend,
2271
2402
  g as SAGELogger,
2272
2403
  z as SkewedAspectGameEngine,
2273
2404
  m as VERSION,
2274
- J as bindingTypes,
2405
+ N as bindingTypes,
2275
2406
  ge as createGameEngine,
2276
- de as validDeviceTypes
2407
+ ue as validDeviceTypes
2277
2408
  };
2278
2409
  //# sourceMappingURL=sage.es.js.map