@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/classes/gameEngine.d.ts +26 -0
- package/dist/classes/input/gamepad.d.ts +2 -2
- package/dist/classes/input/keyboard.d.ts +2 -2
- package/dist/classes/input/mouse.d.ts +2 -2
- package/dist/engines/scene.d.ts +4 -0
- package/dist/interfaces/entity.d.ts +4 -0
- package/dist/managers/binding.d.ts +4 -0
- package/dist/managers/entity.d.ts +7 -2
- package/dist/managers/game.d.ts +6 -0
- package/dist/managers/input.d.ts +2 -2
- package/dist/managers/level.d.ts +4 -0
- package/dist/sage.es.js +481 -350
- package/dist/sage.es.js.map +1 -1
- package/dist/sage.umd.js +1 -1
- package/dist/sage.umd.js.map +1 -1
- package/package.json +8 -10
package/dist/sage.es.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var n = (
|
|
4
|
-
import { FreeCamera as
|
|
5
|
-
import
|
|
6
|
-
const m = "0.
|
|
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,
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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${
|
|
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, ...
|
|
89
|
-
const [
|
|
90
|
-
console.debug(
|
|
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, ...
|
|
93
|
-
const [
|
|
94
|
-
console.debug(
|
|
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, ...
|
|
97
|
-
const [
|
|
98
|
-
console.info(
|
|
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, ...
|
|
101
|
-
const [
|
|
102
|
-
console.warn(
|
|
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, ...
|
|
105
|
-
const [
|
|
106
|
-
console.error(
|
|
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
|
|
113
|
-
this.timers.set(
|
|
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
|
|
120
|
-
if (
|
|
121
|
-
const o = performance.now() -
|
|
122
|
-
this.timers.delete(
|
|
123
|
-
const [
|
|
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
|
-
`${
|
|
126
|
-
|
|
195
|
+
`${c} Timer '${t}' completed in ${o.toFixed(2)}ms`,
|
|
196
|
+
a,
|
|
127
197
|
h,
|
|
128
|
-
|
|
198
|
+
d
|
|
129
199
|
);
|
|
130
200
|
} else
|
|
131
201
|
console.warn(`[${e}]: Timer '${t}' does not exist`);
|
|
132
202
|
}
|
|
133
203
|
}
|
|
134
|
-
class
|
|
135
|
-
trace(e, t, ...
|
|
204
|
+
class H {
|
|
205
|
+
trace(e, t, ...i) {
|
|
136
206
|
}
|
|
137
|
-
debug(e, t, ...
|
|
207
|
+
debug(e, t, ...i) {
|
|
138
208
|
}
|
|
139
|
-
info(e, t, ...
|
|
209
|
+
info(e, t, ...i) {
|
|
140
210
|
}
|
|
141
|
-
warn(e, t, ...
|
|
211
|
+
warn(e, t, ...i) {
|
|
142
212
|
}
|
|
143
|
-
error(e, t, ...
|
|
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",
|
|
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 =
|
|
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
|
|
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
|
|
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
|
|
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
|
|
306
|
-
|
|
307
|
-
const
|
|
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
|
|
312
|
-
this._log.debug(`Removing exact subscription for: ${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
|
|
396
|
+
let i;
|
|
327
397
|
if (typeof e == "string") {
|
|
328
398
|
const o = e.replace(/[-/\\^$+?.()|[\]{}]/g, "\\$&").replace(/\*/g, ".*");
|
|
329
|
-
|
|
330
|
-
`Adding pattern subscription for string: ${e}, regex: ${
|
|
399
|
+
i = new RegExp(`^${o}$`), this._log.debug(
|
|
400
|
+
`Adding pattern subscription for string: ${e}, regex: ${i.toString()}`
|
|
331
401
|
);
|
|
332
402
|
} else
|
|
333
|
-
|
|
334
|
-
const
|
|
335
|
-
pattern:
|
|
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(
|
|
339
|
-
this._log.debug(`Removing pattern subscription: ${
|
|
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
|
|
353
|
-
if (
|
|
354
|
-
t +=
|
|
355
|
-
for (const
|
|
356
|
-
Promise.resolve().then(() =>
|
|
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
|
|
359
|
-
|
|
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
|
|
364
|
-
constructor(e, t,
|
|
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 = (
|
|
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
|
|
373
|
-
|
|
374
|
-
const
|
|
375
|
-
|
|
376
|
-
const o =
|
|
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
|
|
379
|
-
this._log.trace("Adding physics to sphere..."), new
|
|
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
|
-
|
|
451
|
+
D.SPHERE,
|
|
382
452
|
{ mass: 1, restitution: 0.75 },
|
|
383
453
|
e
|
|
384
|
-
), this._log.trace("Adding physics to ground..."), new
|
|
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
|
|
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
|
|
469
|
+
const N = [
|
|
394
470
|
"trigger",
|
|
395
471
|
"toggle",
|
|
396
472
|
"value"
|
|
397
473
|
];
|
|
398
|
-
class
|
|
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,
|
|
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 =
|
|
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
|
|
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 =
|
|
526
|
+
o = s && !this._lastDigitalState;
|
|
451
527
|
break;
|
|
452
528
|
case "falling":
|
|
453
|
-
o = !
|
|
529
|
+
o = !s && this._lastDigitalState;
|
|
454
530
|
break;
|
|
455
531
|
case "both":
|
|
456
|
-
o =
|
|
532
|
+
o = s !== this._lastDigitalState;
|
|
457
533
|
break;
|
|
458
534
|
}
|
|
459
|
-
if (this._lastDigitalState =
|
|
460
|
-
let
|
|
535
|
+
if (this._lastDigitalState = s, o) {
|
|
536
|
+
let c;
|
|
461
537
|
if (this.action.type === "analog") {
|
|
462
|
-
let h = typeof
|
|
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
|
|
465
|
-
h =
|
|
540
|
+
const d = this.action.minValue ?? 0, _ = this.action.maxValue ?? 1;
|
|
541
|
+
h = d + h * (_ - d);
|
|
466
542
|
}
|
|
467
|
-
|
|
543
|
+
c = h;
|
|
468
544
|
} else
|
|
469
|
-
|
|
470
|
-
const
|
|
545
|
+
c = !0;
|
|
546
|
+
const a = {
|
|
471
547
|
type: `action:${this.action.name}`,
|
|
472
548
|
payload: {
|
|
473
|
-
value:
|
|
549
|
+
value: c,
|
|
474
550
|
deviceId: this.deviceID,
|
|
475
551
|
context: this.context
|
|
476
552
|
}
|
|
477
553
|
};
|
|
478
|
-
t.publish(
|
|
554
|
+
t.publish(a);
|
|
479
555
|
}
|
|
480
556
|
}
|
|
481
557
|
/**
|
|
@@ -496,7 +572,7 @@ class Y {
|
|
|
496
572
|
};
|
|
497
573
|
}
|
|
498
574
|
}
|
|
499
|
-
class
|
|
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,
|
|
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 =
|
|
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
|
|
594
|
-
this._lastDigitalState =
|
|
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
|
|
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,
|
|
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 =
|
|
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 =
|
|
659
|
-
const
|
|
660
|
-
this._max =
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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,
|
|
819
|
-
return !t || !
|
|
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, ...
|
|
837
|
-
if (!t || !
|
|
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
|
-
|
|
917
|
+
s
|
|
842
918
|
);
|
|
843
919
|
}
|
|
844
920
|
/**
|
|
@@ -854,7 +930,7 @@ class x {
|
|
|
854
930
|
};
|
|
855
931
|
}
|
|
856
932
|
}
|
|
857
|
-
class
|
|
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,
|
|
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 =
|
|
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 [
|
|
918
|
-
if (!
|
|
993
|
+
const [i, s] = e.split(":");
|
|
994
|
+
if (!i || !s)
|
|
919
995
|
throw new Error(`Invalid gamepad source format: ${e}`);
|
|
920
|
-
return new
|
|
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
|
|
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", (
|
|
967
|
-
|
|
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
|
|
991
|
-
return
|
|
1066
|
+
let i = this._contexts.get(e);
|
|
1067
|
+
return i || (i = {
|
|
992
1068
|
name: e,
|
|
993
1069
|
exclusive: t
|
|
994
|
-
}, this._contexts.set(e,
|
|
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
|
|
1005
|
-
if (
|
|
1080
|
+
for (const i of this._activeContexts) {
|
|
1081
|
+
if (i === e)
|
|
1006
1082
|
continue;
|
|
1007
|
-
const
|
|
1008
|
-
|
|
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:
|
|
1098
|
+
const { deviceID: i, ...s } = e.input;
|
|
1023
1099
|
switch (e.type) {
|
|
1024
1100
|
case "trigger":
|
|
1025
|
-
return new
|
|
1101
|
+
return new J(
|
|
1026
1102
|
t,
|
|
1027
|
-
|
|
1028
|
-
this._createInputSourceFromDefinition(
|
|
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
|
|
1111
|
+
return new Y(
|
|
1036
1112
|
t,
|
|
1037
|
-
|
|
1038
|
-
this._createInputSourceFromDefinition(
|
|
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
|
|
1121
|
+
return new j(
|
|
1046
1122
|
t,
|
|
1047
|
-
|
|
1048
|
-
this._createInputSourceFromDefinition(
|
|
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
|
|
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
|
|
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
|
|
1106
|
-
if (!(!
|
|
1107
|
-
for (const
|
|
1108
|
-
this._isBindingContextActive(
|
|
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
|
|
1149
|
-
return
|
|
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
|
|
1159
|
-
this._log.debug(`Activating context "${e}" (exclusive: ${
|
|
1160
|
-
const
|
|
1161
|
-
if (
|
|
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
|
-
|
|
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 (!
|
|
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
|
|
1234
|
-
for (const [
|
|
1235
|
-
const
|
|
1236
|
-
const h =
|
|
1237
|
-
return
|
|
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
|
-
|
|
1315
|
+
c.length !== o.length && this._bindings.set(s, c);
|
|
1240
1316
|
}
|
|
1241
|
-
this._log.info(`Removed ${
|
|
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
|
|
1252
|
-
for (const
|
|
1253
|
-
for (const o of
|
|
1254
|
-
const
|
|
1255
|
-
o.action.name === e && (!t ||
|
|
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
|
|
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((
|
|
1270
|
-
name:
|
|
1271
|
-
type:
|
|
1272
|
-
minValue:
|
|
1273
|
-
maxValue:
|
|
1274
|
-
} :
|
|
1275
|
-
for (const
|
|
1276
|
-
for (const o of
|
|
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
|
|
1279
|
-
name:
|
|
1280
|
-
exclusive:
|
|
1281
|
-
active: this._activeContexts.has(
|
|
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, ${
|
|
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:
|
|
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 (
|
|
1304
|
-
|
|
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
|
|
1391
|
+
function w() {
|
|
1310
1392
|
return typeof window < "u" && typeof window.document < "u";
|
|
1311
1393
|
}
|
|
1312
|
-
function
|
|
1313
|
-
return
|
|
1394
|
+
function k() {
|
|
1395
|
+
return w() && !!window.navigator.gpu;
|
|
1314
1396
|
}
|
|
1315
1397
|
class Z {
|
|
1316
1398
|
//------------------------------------------------------------------------------------------------------------------
|
|
1317
|
-
constructor(e, t,
|
|
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 =
|
|
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
|
|
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,
|
|
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 =
|
|
1386
|
-
for (const o of
|
|
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
|
|
1409
|
-
(t =
|
|
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
|
|
1436
|
-
if (
|
|
1437
|
-
|
|
1525
|
+
const i = this.subscriptions.get(t);
|
|
1526
|
+
if (i)
|
|
1527
|
+
i.count++;
|
|
1438
1528
|
else {
|
|
1439
|
-
const
|
|
1440
|
-
this.subscriptions.set(t, { count: 1, unsubscribe:
|
|
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
|
|
1453
|
-
const
|
|
1454
|
-
|
|
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,
|
|
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 =
|
|
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
|
|
1501
|
-
|
|
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(
|
|
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 (
|
|
1507
|
-
this._log.debug(`Failed to register action "${t.name}": ${
|
|
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
|
|
1621
|
+
async createEntity(e, t = {}) {
|
|
1622
|
+
var c;
|
|
1533
1623
|
this._log.debug(`Creating entity of type: ${e}`);
|
|
1534
|
-
const
|
|
1535
|
-
if (!
|
|
1536
|
-
const
|
|
1537
|
-
throw this._log.error(
|
|
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
|
-
|
|
1540
|
-
|
|
1541
|
-
s.type,
|
|
1636
|
+
const o = new q(
|
|
1637
|
+
i.type,
|
|
1542
1638
|
this.eventBus,
|
|
1543
|
-
|
|
1544
|
-
|
|
1639
|
+
s,
|
|
1640
|
+
i.behaviors
|
|
1545
1641
|
);
|
|
1546
|
-
|
|
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
|
-
|
|
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
|
-
*
|
|
1759
|
+
* Tears down the keyboard resource access and cleans up event listeners
|
|
1635
1760
|
*/
|
|
1636
|
-
|
|
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
|
|
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(
|
|
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
|
|
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(
|
|
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
|
-
*
|
|
1889
|
+
* Tears down the mouse resource access and cleans up event listeners
|
|
1765
1890
|
*/
|
|
1766
|
-
|
|
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}`,
|
|
1907
|
+
const t = `button-${e.button}`, i = {
|
|
1783
1908
|
pressed: !0
|
|
1784
1909
|
};
|
|
1785
|
-
this._buttonState[t] =
|
|
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}`,
|
|
1922
|
+
const t = `button-${e.button}`, i = {
|
|
1798
1923
|
pressed: !1
|
|
1799
1924
|
};
|
|
1800
|
-
this._buttonState[t] =
|
|
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
|
|
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
|
|
1915
|
-
e[
|
|
2039
|
+
const i = Number(t), s = this._buttonStates[i] || {}, o = this._axesStates[i] || {};
|
|
2040
|
+
e[i] = {
|
|
1916
2041
|
type: "gamepad",
|
|
1917
|
-
buttons: { ...
|
|
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],
|
|
1938
|
-
return !t && !
|
|
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:
|
|
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
|
|
1955
|
-
if (!this._gamepadDevices[
|
|
2079
|
+
const i = t.index;
|
|
2080
|
+
if (!this._gamepadDevices[i]) {
|
|
1956
2081
|
this._handleGamepadConnected(t);
|
|
1957
2082
|
continue;
|
|
1958
2083
|
}
|
|
1959
|
-
const
|
|
1960
|
-
if (!
|
|
2084
|
+
const s = this._gamepadDevices[i];
|
|
2085
|
+
if (!s)
|
|
1961
2086
|
continue;
|
|
1962
|
-
const o = this._buttonStates[
|
|
2087
|
+
const o = this._buttonStates[i] || {}, c = this._axesStates[i] || {}, a = {};
|
|
1963
2088
|
let h = !1;
|
|
1964
|
-
t.buttons.forEach((
|
|
2089
|
+
t.buttons.forEach((u, p) => {
|
|
1965
2090
|
const l = `button-${p}`, f = {
|
|
1966
|
-
pressed:
|
|
1967
|
-
touched:
|
|
1968
|
-
value:
|
|
2091
|
+
pressed: u.pressed,
|
|
2092
|
+
touched: u.touched,
|
|
2093
|
+
value: u.value
|
|
1969
2094
|
};
|
|
1970
|
-
|
|
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
|
|
2099
|
+
const d = {};
|
|
1975
2100
|
let _ = !1;
|
|
1976
|
-
if (t.axes.forEach((
|
|
2101
|
+
if (t.axes.forEach((u, p) => {
|
|
1977
2102
|
const l = `axis-${p}`;
|
|
1978
|
-
|
|
1979
|
-
}), this._buttonStates[
|
|
1980
|
-
const
|
|
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: { ...
|
|
1983
|
-
axes: { ...
|
|
2107
|
+
buttons: { ...a },
|
|
2108
|
+
axes: { ...d }
|
|
1984
2109
|
};
|
|
1985
|
-
this._notifyInputChanged(
|
|
2110
|
+
this._notifyInputChanged(s, u);
|
|
1986
2111
|
}
|
|
1987
2112
|
}
|
|
1988
2113
|
}
|
|
1989
2114
|
/**
|
|
1990
|
-
*
|
|
2115
|
+
* Tears down the gamepad resource access and cleans up event listeners
|
|
1991
2116
|
*/
|
|
1992
|
-
|
|
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,
|
|
2013
|
-
id: `gamepad-${
|
|
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:
|
|
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[
|
|
2147
|
+
this._gamepadDevices[i] = s;
|
|
2023
2148
|
const o = {};
|
|
2024
|
-
Array.from(t.buttons).forEach((
|
|
2149
|
+
Array.from(t.buttons).forEach((a, h) => {
|
|
2025
2150
|
o[`button-${h}`] = {
|
|
2026
|
-
pressed:
|
|
2027
|
-
touched:
|
|
2028
|
-
value:
|
|
2151
|
+
pressed: a.pressed,
|
|
2152
|
+
touched: a.touched,
|
|
2153
|
+
value: a.value
|
|
2029
2154
|
};
|
|
2030
|
-
}), this._buttonStates[
|
|
2031
|
-
const
|
|
2032
|
-
Array.from(t.axes).forEach((
|
|
2033
|
-
|
|
2034
|
-
}), this._axesStates[
|
|
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: { ...
|
|
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
|
|
2046
|
-
|
|
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
|
|
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,
|
|
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 = (
|
|
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
|
|
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(
|
|
2248
|
+
this._eventBus.publish(i);
|
|
2124
2249
|
}
|
|
2125
2250
|
//------------------------------------------------------------------------------------------------------------------
|
|
2126
2251
|
// Internal methods
|
|
2127
2252
|
//------------------------------------------------------------------------------------------------------------------
|
|
2128
2253
|
/**
|
|
2129
|
-
*
|
|
2254
|
+
* Tears down the input manager and clean up event listeners
|
|
2130
2255
|
*/
|
|
2131
|
-
$
|
|
2132
|
-
this._log.info("
|
|
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
|
|
2165
|
-
if (
|
|
2166
|
-
return
|
|
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(
|
|
2178
|
-
const t = new K(
|
|
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(
|
|
2182
|
-
return new
|
|
2312
|
+
function v(r, e) {
|
|
2313
|
+
return new T(r, e.antialias, e.options, e.adaptToDeviceRatio);
|
|
2183
2314
|
}
|
|
2184
|
-
function ne(
|
|
2185
|
-
return new
|
|
2315
|
+
function ne(r) {
|
|
2316
|
+
return new L(r);
|
|
2186
2317
|
}
|
|
2187
|
-
async function oe(
|
|
2188
|
-
if (
|
|
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(
|
|
2195
|
-
} catch (
|
|
2196
|
-
throw console.error("Forced WebGPU initialization failed:",
|
|
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(
|
|
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(
|
|
2207
|
-
} catch (
|
|
2208
|
-
console.warn("WebGPU initialization failed, falling back to WebGL:",
|
|
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(
|
|
2343
|
+
return console.debug("Using WebGL"), v(r, e);
|
|
2213
2344
|
}
|
|
2214
2345
|
async function ae() {
|
|
2215
|
-
const
|
|
2216
|
-
return new
|
|
2346
|
+
const r = await R();
|
|
2347
|
+
return new U(!0, r);
|
|
2217
2348
|
}
|
|
2218
|
-
const
|
|
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(
|
|
2227
|
-
const
|
|
2228
|
-
|
|
2229
|
-
const o = await oe(
|
|
2230
|
-
|
|
2231
|
-
const
|
|
2232
|
-
|
|
2233
|
-
const
|
|
2234
|
-
|
|
2235
|
-
const h = new
|
|
2236
|
-
|
|
2237
|
-
const
|
|
2238
|
-
|
|
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
|
-
|
|
2241
|
-
if (
|
|
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
|
-
|
|
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:
|
|
2388
|
+
entityManager: u,
|
|
2258
2389
|
gameManager: p,
|
|
2259
|
-
inputManager:
|
|
2390
|
+
inputManager: d
|
|
2260
2391
|
}
|
|
2261
2392
|
);
|
|
2262
2393
|
}
|
|
2263
2394
|
export {
|
|
2264
|
-
|
|
2395
|
+
P as ConsoleBackend,
|
|
2265
2396
|
q as GameEntity,
|
|
2266
|
-
|
|
2267
|
-
|
|
2397
|
+
de as GameEntityBehavior,
|
|
2398
|
+
W as GameEventBus,
|
|
2268
2399
|
le as LogLevels,
|
|
2269
|
-
|
|
2270
|
-
|
|
2400
|
+
O as LoggingUtility,
|
|
2401
|
+
H as NullBackend,
|
|
2271
2402
|
g as SAGELogger,
|
|
2272
2403
|
z as SkewedAspectGameEngine,
|
|
2273
2404
|
m as VERSION,
|
|
2274
|
-
|
|
2405
|
+
N as bindingTypes,
|
|
2275
2406
|
ge as createGameEngine,
|
|
2276
|
-
|
|
2407
|
+
ue as validDeviceTypes
|
|
2277
2408
|
};
|
|
2278
2409
|
//# sourceMappingURL=sage.es.js.map
|