@yagejs/debug 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +219 -58
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +20 -5
- package/dist/index.d.ts +20 -5
- package/dist/index.js +218 -52
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -28,14 +28,15 @@ __export(index_exports, {
|
|
|
28
28
|
module.exports = __toCommonJS(index_exports);
|
|
29
29
|
|
|
30
30
|
// src/DebugPlugin.ts
|
|
31
|
-
var
|
|
31
|
+
var import_core4 = require("@yagejs/core");
|
|
32
32
|
|
|
33
33
|
// src/types.ts
|
|
34
34
|
var import_core = require("@yagejs/core");
|
|
35
35
|
var DebugRegistryKey = new import_core.ServiceKey("debugRegistry");
|
|
36
36
|
|
|
37
37
|
// src/DebugPlugin.ts
|
|
38
|
-
var
|
|
38
|
+
var import_renderer2 = require("@yagejs/renderer");
|
|
39
|
+
var import_renderer3 = require("@yagejs/renderer");
|
|
39
40
|
|
|
40
41
|
// src/DebugClock.ts
|
|
41
42
|
var DebugClock = class {
|
|
@@ -131,6 +132,44 @@ var DebugRegistryImpl = class {
|
|
|
131
132
|
}
|
|
132
133
|
};
|
|
133
134
|
|
|
135
|
+
// src/DebugScene.ts
|
|
136
|
+
var import_core2 = require("@yagejs/core");
|
|
137
|
+
var import_renderer = require("@yagejs/renderer");
|
|
138
|
+
var DebugScene = class extends import_core2.Scene {
|
|
139
|
+
static {
|
|
140
|
+
__name(this, "DebugScene");
|
|
141
|
+
}
|
|
142
|
+
name = "__debug__";
|
|
143
|
+
pauseBelow = false;
|
|
144
|
+
transparentBelow = true;
|
|
145
|
+
layers = [
|
|
146
|
+
{ name: "debug-world", order: 999999 },
|
|
147
|
+
{ name: "debug-hud", order: 999999 }
|
|
148
|
+
];
|
|
149
|
+
/** Called after `_mountDetached` has materialized the render tree. */
|
|
150
|
+
onReady;
|
|
151
|
+
/** Called by the plugin when the scene is unmounted. */
|
|
152
|
+
onTearDown;
|
|
153
|
+
onEnter() {
|
|
154
|
+
const tree = this._resolveScoped(import_renderer.SceneRenderTreeKey);
|
|
155
|
+
if (!tree) {
|
|
156
|
+
const logger = this.context.tryResolve(import_core2.LoggerKey);
|
|
157
|
+
const msg = "DebugScene.onEnter: SceneRenderTreeKey missing \u2014 debug overlay will not render. Is RendererPlugin registered?";
|
|
158
|
+
if (logger) logger.warn("debug", msg);
|
|
159
|
+
else console.warn(`[yage] ${msg}`);
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
const worldContainer = tree.get("debug-world").container;
|
|
163
|
+
const hudContainer = tree.get("debug-hud").container;
|
|
164
|
+
worldContainer.eventMode = "none";
|
|
165
|
+
hudContainer.eventMode = "none";
|
|
166
|
+
this.onReady?.(worldContainer, hudContainer);
|
|
167
|
+
}
|
|
168
|
+
onExit() {
|
|
169
|
+
this.onTearDown?.();
|
|
170
|
+
}
|
|
171
|
+
};
|
|
172
|
+
|
|
134
173
|
// src/StatsStore.ts
|
|
135
174
|
var WINDOW_SIZE = 120;
|
|
136
175
|
var StatsStore = class {
|
|
@@ -365,9 +404,9 @@ var HudDebugApiImpl = class {
|
|
|
365
404
|
};
|
|
366
405
|
|
|
367
406
|
// src/DebugRenderSystem.ts
|
|
368
|
-
var
|
|
369
|
-
var DebugRenderSystem = class extends
|
|
370
|
-
constructor(registry, graphicsPool, textPool, worldApi, hudApi, stats, worldContainer, hudContainer) {
|
|
407
|
+
var import_core3 = require("@yagejs/core");
|
|
408
|
+
var DebugRenderSystem = class extends import_core3.System {
|
|
409
|
+
constructor(registry, graphicsPool, textPool, worldApi, hudApi, stats, worldContainer, hudContainer, cameraAccessor) {
|
|
371
410
|
super();
|
|
372
411
|
this.registry = registry;
|
|
373
412
|
this.graphicsPool = graphicsPool;
|
|
@@ -377,6 +416,7 @@ var DebugRenderSystem = class extends import_core2.System {
|
|
|
377
416
|
this.stats = stats;
|
|
378
417
|
this.worldContainer = worldContainer;
|
|
379
418
|
this.hudContainer = hudContainer;
|
|
419
|
+
this.cameraAccessor = cameraAccessor;
|
|
380
420
|
}
|
|
381
421
|
registry;
|
|
382
422
|
graphicsPool;
|
|
@@ -386,10 +426,11 @@ var DebugRenderSystem = class extends import_core2.System {
|
|
|
386
426
|
stats;
|
|
387
427
|
worldContainer;
|
|
388
428
|
hudContainer;
|
|
429
|
+
cameraAccessor;
|
|
389
430
|
static {
|
|
390
431
|
__name(this, "DebugRenderSystem");
|
|
391
432
|
}
|
|
392
|
-
phase =
|
|
433
|
+
phase = import_core3.Phase.Render;
|
|
393
434
|
priority = 9999;
|
|
394
435
|
update(dt) {
|
|
395
436
|
if (!this.registry.enabled) {
|
|
@@ -399,6 +440,7 @@ var DebugRenderSystem = class extends import_core2.System {
|
|
|
399
440
|
}
|
|
400
441
|
this.worldContainer.visible = true;
|
|
401
442
|
this.hudContainer.visible = true;
|
|
443
|
+
this.syncWorldCamera();
|
|
402
444
|
this.graphicsPool.resetFrame();
|
|
403
445
|
this.textPool.resetFrame();
|
|
404
446
|
for (const [name, contributor] of this.registry.contributors) {
|
|
@@ -413,6 +455,22 @@ var DebugRenderSystem = class extends import_core2.System {
|
|
|
413
455
|
}
|
|
414
456
|
}
|
|
415
457
|
}
|
|
458
|
+
syncWorldCamera() {
|
|
459
|
+
const cam = this.cameraAccessor.findCamera();
|
|
460
|
+
if (!cam) {
|
|
461
|
+
this.worldContainer.position.set(0, 0);
|
|
462
|
+
this.worldContainer.scale.set(1, 1);
|
|
463
|
+
this.worldContainer.rotation = 0;
|
|
464
|
+
return;
|
|
465
|
+
}
|
|
466
|
+
const vw = this.cameraAccessor.viewportWidth;
|
|
467
|
+
const vh = this.cameraAccessor.viewportHeight;
|
|
468
|
+
const rotatedPos = cam.effectivePosition.scale(cam.zoom).rotate(-cam.rotation);
|
|
469
|
+
this.worldContainer.position.x = vw / 2 - rotatedPos.x;
|
|
470
|
+
this.worldContainer.position.y = vh / 2 - rotatedPos.y;
|
|
471
|
+
this.worldContainer.scale.set(cam.zoom);
|
|
472
|
+
this.worldContainer.rotation = -cam.rotation;
|
|
473
|
+
}
|
|
416
474
|
};
|
|
417
475
|
|
|
418
476
|
// src/contributors/FpsContributor.ts
|
|
@@ -493,42 +551,33 @@ var DebugPlugin = class {
|
|
|
493
551
|
__name(this, "DebugPlugin");
|
|
494
552
|
}
|
|
495
553
|
name = "debug";
|
|
496
|
-
version = "
|
|
554
|
+
version = "3.0.0";
|
|
497
555
|
dependencies = ["renderer"];
|
|
498
556
|
config;
|
|
499
557
|
registry;
|
|
500
558
|
stats;
|
|
501
|
-
graphicsPool;
|
|
502
|
-
textPool;
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
hudApi;
|
|
559
|
+
graphicsPool = null;
|
|
560
|
+
textPool = null;
|
|
561
|
+
worldApi = null;
|
|
562
|
+
hudApi = null;
|
|
563
|
+
renderSystem = null;
|
|
507
564
|
systemTimings = /* @__PURE__ */ new Map();
|
|
508
565
|
originalUpdates = /* @__PURE__ */ new Map();
|
|
509
566
|
keyListener = null;
|
|
510
567
|
context;
|
|
511
568
|
renderer;
|
|
569
|
+
scheduler;
|
|
570
|
+
sceneManager;
|
|
571
|
+
debugScene = null;
|
|
572
|
+
provider = null;
|
|
573
|
+
eventUnsubs = [];
|
|
512
574
|
clock = null;
|
|
513
575
|
constructor(config) {
|
|
514
576
|
this.config = config ?? {};
|
|
515
577
|
}
|
|
516
578
|
install(context) {
|
|
517
579
|
this.context = context;
|
|
518
|
-
this.renderer = context.resolve(
|
|
519
|
-
const camera = context.resolve(import_renderer.CameraKey);
|
|
520
|
-
const worldLayers = context.resolve(import_renderer.RenderLayerManagerKey);
|
|
521
|
-
const debugLayer = worldLayers.getOrCreate("debug", 999999);
|
|
522
|
-
this.worldContainer = debugLayer.container;
|
|
523
|
-
this.worldContainer.eventMode = "none";
|
|
524
|
-
const hudLayers = this.renderer.createScreenContainer("debug-hud");
|
|
525
|
-
this.hudContainer = hudLayers.defaultLayer.container;
|
|
526
|
-
this.hudContainer.eventMode = "none";
|
|
527
|
-
this.graphicsPool = new GraphicsPool(
|
|
528
|
-
this.worldContainer,
|
|
529
|
-
this.config.maxGraphics
|
|
530
|
-
);
|
|
531
|
-
this.textPool = new TextPool(this.hudContainer, this.config.maxHudLines);
|
|
580
|
+
this.renderer = context.resolve(import_renderer2.RendererKey);
|
|
532
581
|
this.registry = new DebugRegistryImpl();
|
|
533
582
|
this.registry.enabled = this.config.startEnabled ?? false;
|
|
534
583
|
if (this.config.flags) {
|
|
@@ -540,34 +589,14 @@ var DebugPlugin = class {
|
|
|
540
589
|
}
|
|
541
590
|
}
|
|
542
591
|
this.stats = new StatsStore();
|
|
543
|
-
this.worldApi = new WorldDebugApiImpl(
|
|
544
|
-
this.graphicsPool,
|
|
545
|
-
this.registry,
|
|
546
|
-
camera
|
|
547
|
-
);
|
|
548
|
-
this.hudApi = new HudDebugApiImpl(
|
|
549
|
-
this.textPool,
|
|
550
|
-
this.registry,
|
|
551
|
-
camera.viewportWidth,
|
|
552
|
-
camera.viewportHeight
|
|
553
|
-
);
|
|
554
592
|
context.register(DebugRegistryKey, this.registry);
|
|
555
593
|
}
|
|
556
594
|
registerSystems(scheduler) {
|
|
557
|
-
scheduler
|
|
558
|
-
new DebugRenderSystem(
|
|
559
|
-
this.registry,
|
|
560
|
-
this.graphicsPool,
|
|
561
|
-
this.textPool,
|
|
562
|
-
this.worldApi,
|
|
563
|
-
this.hudApi,
|
|
564
|
-
this.stats,
|
|
565
|
-
this.worldContainer,
|
|
566
|
-
this.hudContainer
|
|
567
|
-
)
|
|
568
|
-
);
|
|
595
|
+
this.scheduler = scheduler;
|
|
569
596
|
}
|
|
570
|
-
onStart() {
|
|
597
|
+
async onStart() {
|
|
598
|
+
this.sceneManager = this.context.resolve(import_core4.SceneManagerKey);
|
|
599
|
+
const bus = this.context.resolve(import_core4.EventBusKey);
|
|
571
600
|
const toggleKey = this.config.toggleKey ?? "Backquote";
|
|
572
601
|
const stepKey = this.config.stepKey ?? "Period";
|
|
573
602
|
this.keyListener = (e) => {
|
|
@@ -583,8 +612,7 @@ var DebugPlugin = class {
|
|
|
583
612
|
if (typeof window !== "undefined") {
|
|
584
613
|
window.addEventListener("keydown", this.keyListener);
|
|
585
614
|
}
|
|
586
|
-
const
|
|
587
|
-
for (const system of scheduler.getAllSystems()) {
|
|
615
|
+
for (const system of this.scheduler.getAllSystems()) {
|
|
588
616
|
if (system instanceof DebugRenderSystem) continue;
|
|
589
617
|
const name = system.constructor.name;
|
|
590
618
|
const original = system.update.bind(system);
|
|
@@ -595,11 +623,11 @@ var DebugPlugin = class {
|
|
|
595
623
|
this.systemTimings.set(name, performance.now() - t0);
|
|
596
624
|
};
|
|
597
625
|
}
|
|
598
|
-
const inspector = this.context.resolve(
|
|
626
|
+
const inspector = this.context.resolve(import_core4.InspectorKey);
|
|
599
627
|
this.registry.register(new FpsContributor());
|
|
600
628
|
this.registry.register(new EntityCountContributor(inspector));
|
|
601
629
|
this.registry.register(new SystemTimingContributor(this.systemTimings));
|
|
602
|
-
const gameLoop = this.context.resolve(
|
|
630
|
+
const gameLoop = this.context.resolve(import_core4.GameLoopKey);
|
|
603
631
|
const app = this.renderer.application;
|
|
604
632
|
this.clock = new DebugClock(
|
|
605
633
|
gameLoop,
|
|
@@ -611,8 +639,21 @@ var DebugPlugin = class {
|
|
|
611
639
|
this.clock.setManual(true);
|
|
612
640
|
}
|
|
613
641
|
this.attachToGlobal(this.clock);
|
|
642
|
+
this.provider = this.context.tryResolve(import_renderer3.SceneRenderTreeProviderKey) ?? null;
|
|
643
|
+
this.attachInspectorDiagnostics(inspector);
|
|
644
|
+
await this.materializeDebugScene();
|
|
645
|
+
const bringToFront = /* @__PURE__ */ __name(() => {
|
|
646
|
+
if (this.debugScene && this.provider?.bringSceneToFront) {
|
|
647
|
+
this.provider.bringSceneToFront(this.debugScene);
|
|
648
|
+
}
|
|
649
|
+
}, "bringToFront");
|
|
650
|
+
this.eventUnsubs.push(bus.on("scene:pushed", bringToFront));
|
|
651
|
+
this.eventUnsubs.push(bus.on("scene:popped", bringToFront));
|
|
652
|
+
this.eventUnsubs.push(bus.on("scene:replaced", bringToFront));
|
|
614
653
|
}
|
|
615
654
|
onDestroy() {
|
|
655
|
+
for (const unsub of this.eventUnsubs) unsub();
|
|
656
|
+
this.eventUnsubs.length = 0;
|
|
616
657
|
for (const [system, original] of this.originalUpdates) {
|
|
617
658
|
system.update = original;
|
|
618
659
|
}
|
|
@@ -629,9 +670,112 @@ var DebugPlugin = class {
|
|
|
629
670
|
contributor.dispose?.();
|
|
630
671
|
}
|
|
631
672
|
this.registry.contributors.clear();
|
|
632
|
-
this.
|
|
633
|
-
this.
|
|
634
|
-
|
|
673
|
+
this.tearDownDebugInfra();
|
|
674
|
+
this.teardownDebugScene();
|
|
675
|
+
}
|
|
676
|
+
async materializeDebugScene() {
|
|
677
|
+
const scene = new DebugScene();
|
|
678
|
+
scene.onReady = (worldContainer, hudContainer) => this.setUpDebugInfra(worldContainer, hudContainer);
|
|
679
|
+
scene.onTearDown = () => this.tearDownDebugInfra();
|
|
680
|
+
await this.sceneManager._mountDetached(scene);
|
|
681
|
+
this.debugScene = scene;
|
|
682
|
+
}
|
|
683
|
+
teardownDebugScene() {
|
|
684
|
+
if (!this.debugScene) return;
|
|
685
|
+
this.sceneManager._unmountDetached(this.debugScene);
|
|
686
|
+
this.debugScene = null;
|
|
687
|
+
this.provider = null;
|
|
688
|
+
}
|
|
689
|
+
findActiveCamera() {
|
|
690
|
+
return findTopmostCamera(this.sceneManager);
|
|
691
|
+
}
|
|
692
|
+
setUpDebugInfra(worldContainer, hudContainer) {
|
|
693
|
+
const vw = this.renderer.virtualSize.width;
|
|
694
|
+
const vh = this.renderer.virtualSize.height;
|
|
695
|
+
const self = this;
|
|
696
|
+
const cameraProxy = {
|
|
697
|
+
get zoom() {
|
|
698
|
+
return self.findActiveCamera()?.zoom ?? 1;
|
|
699
|
+
}
|
|
700
|
+
};
|
|
701
|
+
this.graphicsPool = new GraphicsPool(
|
|
702
|
+
worldContainer,
|
|
703
|
+
this.config.maxGraphics
|
|
704
|
+
);
|
|
705
|
+
this.textPool = new TextPool(hudContainer, this.config.maxHudLines);
|
|
706
|
+
this.worldApi = new WorldDebugApiImpl(
|
|
707
|
+
this.graphicsPool,
|
|
708
|
+
this.registry,
|
|
709
|
+
cameraProxy
|
|
710
|
+
);
|
|
711
|
+
this.hudApi = new HudDebugApiImpl(this.textPool, this.registry, vw, vh);
|
|
712
|
+
this.renderSystem = new DebugRenderSystem(
|
|
713
|
+
this.registry,
|
|
714
|
+
this.graphicsPool,
|
|
715
|
+
this.textPool,
|
|
716
|
+
this.worldApi,
|
|
717
|
+
this.hudApi,
|
|
718
|
+
this.stats,
|
|
719
|
+
worldContainer,
|
|
720
|
+
hudContainer,
|
|
721
|
+
{
|
|
722
|
+
findCamera: /* @__PURE__ */ __name(() => self.findActiveCamera(), "findCamera"),
|
|
723
|
+
viewportWidth: vw,
|
|
724
|
+
viewportHeight: vh
|
|
725
|
+
}
|
|
726
|
+
);
|
|
727
|
+
this.scheduler.add(this.renderSystem);
|
|
728
|
+
}
|
|
729
|
+
tearDownDebugInfra() {
|
|
730
|
+
if (this.renderSystem) {
|
|
731
|
+
this.scheduler.remove(this.renderSystem);
|
|
732
|
+
this.renderSystem = null;
|
|
733
|
+
}
|
|
734
|
+
this.graphicsPool?.destroy();
|
|
735
|
+
this.textPool?.destroy();
|
|
736
|
+
this.graphicsPool = null;
|
|
737
|
+
this.textPool = null;
|
|
738
|
+
this.worldApi = null;
|
|
739
|
+
this.hudApi = null;
|
|
740
|
+
}
|
|
741
|
+
attachInspectorDiagnostics(inspector) {
|
|
742
|
+
const g = globalThis["__yage__"];
|
|
743
|
+
if (!g || typeof g !== "object") return;
|
|
744
|
+
const debugSurface = g;
|
|
745
|
+
const diagnostics = inspector;
|
|
746
|
+
debugSurface["inspector"] = inspector;
|
|
747
|
+
diagnostics.getLayerTransform = (sceneName, layerName) => {
|
|
748
|
+
const scene = this.sceneManager.all.find(
|
|
749
|
+
(candidate) => candidate.name === sceneName
|
|
750
|
+
);
|
|
751
|
+
if (!scene) return void 0;
|
|
752
|
+
const layer = this.provider?.getTree(scene)?.tryGet(layerName);
|
|
753
|
+
if (!layer) return void 0;
|
|
754
|
+
const container = layer.container;
|
|
755
|
+
return {
|
|
756
|
+
x: container.position.x,
|
|
757
|
+
y: container.position.y,
|
|
758
|
+
scaleX: container.scale.x,
|
|
759
|
+
scaleY: container.scale.y,
|
|
760
|
+
rotation: container.rotation
|
|
761
|
+
};
|
|
762
|
+
};
|
|
763
|
+
diagnostics.getCameraStack = () => {
|
|
764
|
+
const cameras = [];
|
|
765
|
+
for (const scene of this.sceneManager.all) {
|
|
766
|
+
for (const entity of scene.getEntities()) {
|
|
767
|
+
const cam = entity.tryGet(import_renderer2.CameraComponent);
|
|
768
|
+
if (!cam) continue;
|
|
769
|
+
cameras.push({
|
|
770
|
+
scene: scene.name,
|
|
771
|
+
name: cam.cameraName,
|
|
772
|
+
priority: cam.priority,
|
|
773
|
+
enabled: cam.enabled
|
|
774
|
+
});
|
|
775
|
+
}
|
|
776
|
+
}
|
|
777
|
+
return cameras;
|
|
778
|
+
};
|
|
635
779
|
}
|
|
636
780
|
attachToGlobal(clock) {
|
|
637
781
|
const g = globalThis["__yage__"];
|
|
@@ -646,6 +790,23 @@ var DebugPlugin = class {
|
|
|
646
790
|
}
|
|
647
791
|
}
|
|
648
792
|
};
|
|
793
|
+
function findTopmostCamera(sceneManager) {
|
|
794
|
+
const stack = sceneManager.all;
|
|
795
|
+
for (let i = stack.length - 1; i >= 0; i--) {
|
|
796
|
+
const scene = stack[i];
|
|
797
|
+
if (!scene) continue;
|
|
798
|
+
let highestPriorityCamera;
|
|
799
|
+
for (const entity of scene.getEntities()) {
|
|
800
|
+
const cam = entity.tryGet(import_renderer2.CameraComponent);
|
|
801
|
+
if (cam && cam.enabled && (!highestPriorityCamera || cam.priority > highestPriorityCamera.priority)) {
|
|
802
|
+
highestPriorityCamera = cam;
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
if (highestPriorityCamera) return highestPriorityCamera;
|
|
806
|
+
}
|
|
807
|
+
return void 0;
|
|
808
|
+
}
|
|
809
|
+
__name(findTopmostCamera, "findTopmostCamera");
|
|
649
810
|
// Annotate the CommonJS export names for ESM import in node:
|
|
650
811
|
0 && (module.exports = {
|
|
651
812
|
DebugPlugin,
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/DebugPlugin.ts","../src/types.ts","../src/DebugClock.ts","../src/DebugRegistryImpl.ts","../src/StatsStore.ts","../src/GraphicsPool.ts","../src/TextPool.ts","../src/WorldDebugApiImpl.ts","../src/HudDebugApiImpl.ts","../src/DebugRenderSystem.ts","../src/contributors/FpsContributor.ts","../src/contributors/EntityCountContributor.ts","../src/contributors/SystemTimingContributor.ts"],"sourcesContent":["export { DebugPlugin } from \"./DebugPlugin.js\";\nexport type { DebugConfig } from \"./DebugPlugin.js\";\nexport type { IDebugClock } from \"./DebugClock.js\";\nexport { DebugRegistryImpl } from \"./DebugRegistryImpl.js\";\nexport { StatsStore } from \"./StatsStore.js\";\n","import { SystemSchedulerKey, InspectorKey, GameLoopKey } from \"@yagejs/core\";\nimport type {\n EngineContext,\n Plugin,\n SystemScheduler,\n System,\n} from \"@yagejs/core\";\nimport { DebugRegistryKey } from \"./types.js\";\nimport { RendererKey, RenderLayerManagerKey, CameraKey } from \"@yagejs/renderer\";\nimport type { RendererPlugin } from \"@yagejs/renderer\";\nimport { Container } from \"pixi.js\";\nimport { DebugClock } from \"./DebugClock.js\";\nimport type { IDebugClock } from \"./DebugClock.js\";\nimport { DebugRegistryImpl } from \"./DebugRegistryImpl.js\";\nimport { StatsStore } from \"./StatsStore.js\";\nimport { GraphicsPool } from \"./GraphicsPool.js\";\nimport { TextPool } from \"./TextPool.js\";\nimport { WorldDebugApiImpl } from \"./WorldDebugApiImpl.js\";\nimport { HudDebugApiImpl } from \"./HudDebugApiImpl.js\";\nimport { DebugRenderSystem } from \"./DebugRenderSystem.js\";\nimport { FpsContributor } from \"./contributors/FpsContributor.js\";\nimport { EntityCountContributor } from \"./contributors/EntityCountContributor.js\";\nimport { SystemTimingContributor } from \"./contributors/SystemTimingContributor.js\";\n\n/** Configuration for the DebugPlugin. */\nexport interface DebugConfig {\n /** Key code to toggle debug overlay. Default: \"Backquote\" */\n toggleKey?: string;\n /** When true, stop the renderer ticker and advance simulation manually via `window.__yage__.clock`. */\n manualClock?: boolean;\n /** Key code to advance one fixed-timestep frame while manual clock mode is active. Default: \"Period\" */\n stepKey?: string;\n /** Max pooled Graphics objects. Default: 256 */\n maxGraphics?: number;\n /** Max HUD text lines. Default: 32 */\n maxHudLines?: number;\n /** Whether the overlay starts enabled. Default: false */\n startEnabled?: boolean;\n /** Initial flag overrides, keyed by \"contributorName.flagName\". */\n flags?: Record<string, boolean>;\n}\n\n/** Debug overlay plugin. Depends on the renderer plugin. */\nexport class DebugPlugin implements Plugin {\n readonly name = \"debug\";\n readonly version = \"2.0.0\";\n readonly dependencies = [\"renderer\"] as const;\n\n private readonly config: DebugConfig;\n private registry!: DebugRegistryImpl;\n private stats!: StatsStore;\n private graphicsPool!: GraphicsPool;\n private textPool!: TextPool;\n private worldContainer!: Container;\n private hudContainer!: Container;\n private worldApi!: WorldDebugApiImpl;\n private hudApi!: HudDebugApiImpl;\n private systemTimings = new Map<string, number>();\n private originalUpdates = new Map<System, (dt: number) => void>();\n private keyListener: ((e: KeyboardEvent) => void) | null = null;\n private context!: EngineContext;\n private renderer!: RendererPlugin;\n private clock: DebugClock | null = null;\n\n constructor(config?: DebugConfig) {\n this.config = config ?? {};\n }\n\n install(context: EngineContext): void {\n this.context = context;\n\n this.renderer = context.resolve(RendererKey);\n const camera = context.resolve(CameraKey);\n\n // World-space debug layer (child of world container, drawn on top)\n const worldLayers = context.resolve(RenderLayerManagerKey);\n const debugLayer = worldLayers.getOrCreate(\"debug\", 999999);\n this.worldContainer = debugLayer.container;\n this.worldContainer.eventMode = \"none\";\n\n // Screen-space HUD container (sibling of world container, unaffected by camera)\n const hudLayers = this.renderer.createScreenContainer(\"debug-hud\");\n this.hudContainer = hudLayers.defaultLayer.container;\n this.hudContainer.eventMode = \"none\";\n\n this.graphicsPool = new GraphicsPool(\n this.worldContainer,\n this.config.maxGraphics,\n );\n this.textPool = new TextPool(this.hudContainer, this.config.maxHudLines);\n\n this.registry = new DebugRegistryImpl();\n this.registry.enabled = this.config.startEnabled ?? false;\n\n if (this.config.flags) {\n for (const [key, value] of Object.entries(this.config.flags)) {\n const dot = key.indexOf(\".\");\n if (dot > 0) {\n this.registry.setFlag(key.slice(0, dot), key.slice(dot + 1), value);\n }\n }\n }\n\n this.stats = new StatsStore();\n\n this.worldApi = new WorldDebugApiImpl(\n this.graphicsPool,\n this.registry,\n camera,\n );\n this.hudApi = new HudDebugApiImpl(\n this.textPool,\n this.registry,\n camera.viewportWidth,\n camera.viewportHeight,\n );\n\n context.register(DebugRegistryKey, this.registry);\n }\n\n registerSystems(scheduler: SystemScheduler): void {\n scheduler.add(\n new DebugRenderSystem(\n this.registry,\n this.graphicsPool,\n this.textPool,\n this.worldApi,\n this.hudApi,\n this.stats,\n this.worldContainer,\n this.hudContainer,\n ),\n );\n }\n\n onStart(): void {\n // Toggle / step key listener\n const toggleKey = this.config.toggleKey ?? \"Backquote\";\n const stepKey = this.config.stepKey ?? \"Period\";\n this.keyListener = (e: KeyboardEvent) => {\n if (e.code === toggleKey) {\n this.registry.toggle();\n return;\n }\n if (e.code === stepKey && this.clock?.isManual) {\n e.preventDefault();\n this.clock.step();\n }\n };\n if (typeof window !== \"undefined\") {\n window.addEventListener(\"keydown\", this.keyListener);\n }\n\n // Instrument system timings\n const scheduler = this.context.resolve(SystemSchedulerKey);\n for (const system of scheduler.getAllSystems()) {\n if (system instanceof DebugRenderSystem) continue;\n const name = system.constructor.name;\n const original = system.update.bind(system);\n this.originalUpdates.set(system, original);\n system.update = (dt: number) => {\n const t0 = performance.now();\n original(dt);\n this.systemTimings.set(name, performance.now() - t0);\n };\n }\n\n // Built-in contributors\n const inspector = this.context.resolve(InspectorKey);\n this.registry.register(new FpsContributor());\n this.registry.register(new EntityCountContributor(inspector));\n this.registry.register(new SystemTimingContributor(this.systemTimings));\n\n // Manual clock for deterministic stepping\n const gameLoop = this.context.resolve(GameLoopKey);\n const app = this.renderer.application;\n\n this.clock = new DebugClock(\n gameLoop,\n () => app.stop(),\n () => app.start(),\n () => app.render(),\n );\n\n if (this.config.manualClock) {\n this.clock.setManual(true);\n }\n\n this.attachToGlobal(this.clock);\n }\n\n onDestroy(): void {\n // Restore original system.update methods\n for (const [system, original] of this.originalUpdates) {\n system.update = original;\n }\n this.originalUpdates.clear();\n\n if (this.keyListener) {\n if (typeof window !== \"undefined\") {\n window.removeEventListener(\"keydown\", this.keyListener);\n }\n this.keyListener = null;\n }\n\n this.detachFromGlobal();\n this.clock = null;\n\n for (const contributor of this.registry.contributors.values()) {\n contributor.dispose?.();\n }\n this.registry.contributors.clear();\n\n this.graphicsPool.destroy();\n this.textPool.destroy();\n // worldContainer is owned by the world RenderLayerManager — don't destroy it\n this.renderer.destroyScreenContainer(\"debug-hud\");\n }\n\n private attachToGlobal(clock: IDebugClock): void {\n const g = (globalThis as Record<string, unknown>)[\"__yage__\"];\n if (g && typeof g === \"object\") {\n (g as Record<string, unknown>)[\"clock\"] = clock;\n }\n }\n\n private detachFromGlobal(): void {\n const g = (globalThis as Record<string, unknown>)[\"__yage__\"];\n if (\n g &&\n typeof g === \"object\" &&\n (g as Record<string, unknown>)[\"clock\"] === this.clock\n ) {\n delete (g as Record<string, unknown>)[\"clock\"];\n }\n }\n}\n","import { ServiceKey } from \"@yagejs/core\";\n\n/**\n * Minimal subset of PixiJS Graphics used by debug drawing.\n * Avoids a runtime pixi.js dependency in the ./api subpath.\n */\nexport interface DebugGraphics {\n position: { x: number; y: number };\n rotation: number;\n visible: boolean;\n clear(): DebugGraphics;\n rect(x: number, y: number, width: number, height: number): DebugGraphics;\n circle(x: number, y: number, radius: number): DebugGraphics;\n moveTo(x: number, y: number): DebugGraphics;\n lineTo(x: number, y: number): DebugGraphics;\n stroke(style: { width: number; color: number; alpha?: number }): DebugGraphics;\n fill(style: { color: number; alpha?: number }): DebugGraphics;\n}\n\n/** Camera-space drawing API passed to contributors. */\nexport interface WorldDebugApi {\n acquireGraphics(): DebugGraphics | undefined;\n isFlagEnabled(flag: string): boolean;\n readonly cameraZoom: number;\n}\n\n/** Screen-space HUD API passed to contributors. */\nexport interface HudDebugApi {\n addLine(text: string): void;\n isFlagEnabled(flag: string): boolean;\n readonly screenWidth: number;\n readonly screenHeight: number;\n}\n\n/** Rolling-window statistics collector. */\nexport interface StatsApi {\n push(key: string, value: number): void;\n average(key: string): number;\n latest(key: string): number;\n min(key: string): number;\n max(key: string): number;\n}\n\n/** A debug contributor that registers drawing/sampling callbacks. */\nexport interface DebugContributor {\n readonly name: string;\n readonly flags: readonly string[];\n drawWorld?(api: WorldDebugApi): void;\n drawHud?(api: HudDebugApi): void;\n sample?(stats: StatsApi, dt: number): void;\n dispose?(): void;\n}\n\n/** Service interface for the debug registry. */\nexport interface DebugRegistry {\n register(contributor: DebugContributor): void;\n isEnabled(): boolean;\n isFlagEnabled(contributorName: string, flag: string): boolean;\n}\n\n/** Service key for resolving the DebugRegistry via DI. */\nexport const DebugRegistryKey = new ServiceKey<DebugRegistry>(\"debugRegistry\");\n","/** Public interface for the manual debug clock, accessible via `window.__yage__.clock`. */\nexport interface IDebugClock {\n readonly isManual: boolean;\n startAuto(): void;\n stopAuto(): void;\n step(dtMs?: number): void;\n stepFrames(count: number, dtMs?: number): void;\n}\n\n/** Minimal view of a game loop needed by the debug clock. */\ninterface GameLoopLike {\n tick(dtMs: number): void;\n readonly fixedTimestep: number;\n}\n\n/**\n * Controls engine time-stepping for deterministic E2E tests.\n *\n * When manual mode is active the renderer ticker is paused and frames\n * advance only via explicit `step()` / `stepFrames()` calls.\n */\nexport class DebugClock implements IDebugClock {\n private _isManual = false;\n\n constructor(\n private readonly gameLoop: GameLoopLike,\n private readonly stopTicker: () => void,\n private readonly startTicker: () => void,\n private readonly render: () => void,\n ) {}\n\n get isManual(): boolean {\n return this._isManual;\n }\n\n startAuto(): void {\n if (!this._isManual) return;\n this.startTicker();\n this._isManual = false;\n }\n\n stopAuto(): void {\n if (this._isManual) return;\n this.stopTicker();\n this._isManual = true;\n }\n\n step(dtMs?: number): void {\n if (!this._isManual) {\n throw new Error(\n \"Manual clock is not active. Call clock.stopAuto() first.\",\n );\n }\n const dt = dtMs ?? this.gameLoop.fixedTimestep;\n this.gameLoop.tick(dt);\n this.render();\n }\n\n stepFrames(count: number, dtMs?: number): void {\n if (!Number.isInteger(count) || count < 0) {\n throw new Error(\n \"stepFrames(count) requires a non-negative integer count.\",\n );\n }\n for (let i = 0; i < count; i++) {\n this.step(dtMs);\n }\n }\n\n /** Enter or exit manual mode. Used by DebugPlugin for config-driven init. */\n setManual(enabled: boolean): void {\n if (enabled === this._isManual) return;\n if (enabled) {\n this.stopTicker();\n } else {\n this.startTicker();\n }\n this._isManual = enabled;\n }\n}\n","import type { DebugContributor, DebugRegistry } from \"./types.js\";\n\n/** Concrete implementation of the DebugRegistry interface. */\nexport class DebugRegistryImpl implements DebugRegistry {\n readonly contributors = new Map<string, DebugContributor>();\n enabled = false;\n private flags = new Map<string, boolean>();\n\n register(contributor: DebugContributor): void {\n if (this.contributors.has(contributor.name)) return;\n this.contributors.set(contributor.name, contributor);\n for (const flag of contributor.flags) {\n this.flags.set(`${contributor.name}.${flag}`, true);\n }\n }\n\n isEnabled(): boolean {\n return this.enabled;\n }\n\n isFlagEnabled(contributorName: string, flag: string): boolean {\n return this.flags.get(`${contributorName}.${flag}`) ?? true;\n }\n\n toggle(): void {\n this.enabled = !this.enabled;\n }\n\n toggleFlag(contributorName: string, flag: string): void {\n const key = `${contributorName}.${flag}`;\n this.flags.set(key, !(this.flags.get(key) ?? true));\n }\n\n setFlag(contributorName: string, flag: string, value: boolean): void {\n this.flags.set(`${contributorName}.${flag}`, value);\n }\n}\n","import type { StatsApi } from \"./types.js\";\n\nconst WINDOW_SIZE = 120;\n\ninterface RingBuffer {\n data: Float64Array;\n count: number;\n index: number;\n}\n\n/** Rolling-window statistics store backed by Float64Array ring buffers. */\nexport class StatsStore implements StatsApi {\n private rings = new Map<string, RingBuffer>();\n\n push(key: string, value: number): void {\n let ring = this.rings.get(key);\n if (!ring) {\n ring = { data: new Float64Array(WINDOW_SIZE), count: 0, index: 0 };\n this.rings.set(key, ring);\n }\n ring.data[ring.index] = value;\n ring.index = (ring.index + 1) % WINDOW_SIZE;\n if (ring.count < WINDOW_SIZE) ring.count++;\n }\n\n average(key: string): number {\n const ring = this.rings.get(key);\n if (!ring || ring.count === 0) return 0;\n const { data, count } = ring;\n let sum = 0;\n for (let i = 0; i < count; i++) sum += data[i] ?? 0;\n return sum / count;\n }\n\n latest(key: string): number {\n const ring = this.rings.get(key);\n if (!ring || ring.count === 0) return 0;\n return ring.data[(ring.index - 1 + WINDOW_SIZE) % WINDOW_SIZE] ?? 0;\n }\n\n min(key: string): number {\n const ring = this.rings.get(key);\n if (!ring || ring.count === 0) return 0;\n const { data, count } = ring;\n let m = Infinity;\n for (let i = 0; i < count; i++) {\n const v = data[i] ?? 0;\n if (v < m) m = v;\n }\n return m;\n }\n\n max(key: string): number {\n const ring = this.rings.get(key);\n if (!ring || ring.count === 0) return 0;\n const { data, count } = ring;\n let m = -Infinity;\n for (let i = 0; i < count; i++) {\n const v = data[i] ?? 0;\n if (v > m) m = v;\n }\n return m;\n }\n}\n","import { Graphics, Container } from \"pixi.js\";\n\n/** Allocation-free pool of PixiJS Graphics objects for debug drawing. */\nexport class GraphicsPool {\n private pool: Graphics[] | null = null;\n private index = 0;\n private readonly container: Container;\n private readonly maxSize: number;\n\n constructor(container: Container, maxSize = 256) {\n this.container = container;\n this.maxSize = maxSize;\n }\n\n /** Lazily create Graphics objects on first use (ensures PixiJS is fully ready). */\n private ensure(): Graphics[] {\n if (this.pool) return this.pool;\n this.pool = [];\n for (let i = 0; i < this.maxSize; i++) {\n const g = new Graphics();\n g.visible = false;\n g.eventMode = \"none\";\n this.container.addChild(g);\n this.pool.push(g);\n }\n return this.pool;\n }\n\n /** Return the next available Graphics, or undefined if the pool is exhausted. */\n acquire(): Graphics | undefined {\n const pool = this.ensure();\n if (this.index >= pool.length) return undefined;\n const g = pool[this.index]!;\n g.visible = true;\n this.index++;\n return g;\n }\n\n /** Clear and hide all previously acquired graphics, reset index. */\n resetFrame(): void {\n if (!this.pool) return;\n for (let i = 0; i < this.index; i++) {\n const g = this.pool[i]!;\n g.clear();\n g.visible = false;\n g.position.set(0, 0);\n g.rotation = 0;\n g.scale.set(1, 1);\n }\n this.index = 0;\n }\n\n destroy(): void {\n if (!this.pool) return;\n for (const g of this.pool) {\n g.destroy();\n }\n this.pool.length = 0;\n }\n}\n","import { Text, Container } from \"pixi.js\";\n\nconst LINE_HEIGHT = 16;\nconst FONT_SIZE = 14;\nconst PADDING = 4;\n\n/** Allocation-free pool of PixiJS Text objects for HUD debug lines. */\nexport class TextPool {\n private pool: Text[] | null = null;\n private index = 0;\n private readonly container: Container;\n private readonly maxLines: number;\n\n constructor(container: Container, maxLines = 32) {\n this.container = container;\n this.maxLines = maxLines;\n }\n\n /** Lazily create Text objects on first use (ensures PixiJS is fully ready). */\n private ensure(): Text[] {\n if (this.pool) return this.pool;\n this.pool = [];\n for (let i = 0; i < this.maxLines; i++) {\n const t = new Text({\n text: \"\",\n style: {\n fontFamily: \"monospace\",\n fontSize: FONT_SIZE,\n fill: 0xffffff,\n },\n });\n t.visible = false;\n t.eventMode = \"none\";\n this.container.addChild(t);\n this.pool.push(t);\n }\n return this.pool;\n }\n\n /** Show a text line at the next available slot. */\n addLine(text: string): void {\n const pool = this.ensure();\n if (this.index >= pool.length) return;\n const t = pool[this.index]!;\n t.text = text;\n t.visible = true;\n t.position.set(PADDING, PADDING + this.index * LINE_HEIGHT);\n this.index++;\n }\n\n /** Hide all lines and reset for the next frame. */\n resetFrame(): void {\n if (!this.pool) return;\n for (let i = 0; i < this.index; i++) {\n this.pool[i]!.visible = false;\n }\n this.index = 0;\n }\n\n destroy(): void {\n if (!this.pool) return;\n for (const t of this.pool) {\n t.destroy();\n }\n this.pool.length = 0;\n }\n}\n","import type { WorldDebugApi, DebugGraphics } from \"./types.js\";\nimport type { GraphicsPool } from \"./GraphicsPool.js\";\nimport type { DebugRegistryImpl } from \"./DebugRegistryImpl.js\";\n\n/** WorldDebugApi backed by a GraphicsPool. Contributor name is swapped per iteration. */\nexport class WorldDebugApiImpl implements WorldDebugApi {\n private _contributorName = \"\";\n\n constructor(\n private readonly pool: GraphicsPool,\n private readonly registry: DebugRegistryImpl,\n private readonly _camera: { zoom: number },\n ) {}\n\n /** Set the current contributor name (called before each contributor's drawWorld). */\n setContributor(name: string): void {\n this._contributorName = name;\n }\n\n acquireGraphics(): DebugGraphics | undefined {\n return this.pool.acquire() as unknown as DebugGraphics | undefined;\n }\n\n isFlagEnabled(flag: string): boolean {\n return this.registry.isFlagEnabled(this._contributorName, flag);\n }\n\n get cameraZoom(): number {\n return this._camera.zoom;\n }\n}\n","import type { HudDebugApi } from \"./types.js\";\nimport type { TextPool } from \"./TextPool.js\";\nimport type { DebugRegistryImpl } from \"./DebugRegistryImpl.js\";\n\n/** HudDebugApi backed by a TextPool. Contributor name is swapped per iteration. */\nexport class HudDebugApiImpl implements HudDebugApi {\n private _contributorName = \"\";\n\n constructor(\n private readonly textPool: TextPool,\n private readonly registry: DebugRegistryImpl,\n public readonly screenWidth: number,\n public readonly screenHeight: number,\n ) {}\n\n /** Set the current contributor name (called before each contributor's drawHud). */\n setContributor(name: string): void {\n this._contributorName = name;\n }\n\n addLine(text: string): void {\n this.textPool.addLine(text);\n }\n\n isFlagEnabled(flag: string): boolean {\n return this.registry.isFlagEnabled(this._contributorName, flag);\n }\n}\n","import { System, Phase } from \"@yagejs/core\";\nimport type { Container } from \"pixi.js\";\nimport type { DebugRegistryImpl } from \"./DebugRegistryImpl.js\";\nimport type { GraphicsPool } from \"./GraphicsPool.js\";\nimport type { TextPool } from \"./TextPool.js\";\nimport type { WorldDebugApiImpl } from \"./WorldDebugApiImpl.js\";\nimport type { HudDebugApiImpl } from \"./HudDebugApiImpl.js\";\nimport type { StatsStore } from \"./StatsStore.js\";\n\n/** Renders all debug contributors. Runs after DisplaySystem in the Render phase. */\nexport class DebugRenderSystem extends System {\n readonly phase = Phase.Render;\n readonly priority = 9999;\n\n constructor(\n private readonly registry: DebugRegistryImpl,\n private readonly graphicsPool: GraphicsPool,\n private readonly textPool: TextPool,\n private readonly worldApi: WorldDebugApiImpl,\n private readonly hudApi: HudDebugApiImpl,\n private readonly stats: StatsStore,\n private readonly worldContainer: Container,\n private readonly hudContainer: Container,\n ) {\n super();\n }\n\n update(dt: number): void {\n if (!this.registry.enabled) {\n this.worldContainer.visible = false;\n this.hudContainer.visible = false;\n return;\n }\n\n this.worldContainer.visible = true;\n this.hudContainer.visible = true;\n this.graphicsPool.resetFrame();\n this.textPool.resetFrame();\n\n for (const [name, contributor] of this.registry.contributors) {\n contributor.sample?.(this.stats, dt);\n\n if (contributor.drawWorld) {\n this.worldApi.setContributor(name);\n contributor.drawWorld(this.worldApi);\n }\n\n if (contributor.drawHud) {\n this.hudApi.setContributor(name);\n contributor.drawHud(this.hudApi);\n }\n }\n }\n}\n","import type { DebugContributor, StatsApi, HudDebugApi } from \"../types.js\";\n\nexport class FpsContributor implements DebugContributor {\n readonly name = \"fps\";\n readonly flags: readonly string[] = [];\n private stats: StatsApi | null = null;\n\n sample(stats: StatsApi, dt: number): void {\n this.stats = stats;\n if (dt > 0) stats.push(\"fps\", 1000 / dt);\n }\n\n drawHud(api: HudDebugApi): void {\n const avg = this.stats?.average(\"fps\") ?? 0;\n api.addLine(`FPS: ${Math.round(avg)}`);\n }\n}\n","import type { DebugContributor, HudDebugApi } from \"../types.js\";\nimport type { Inspector } from \"@yagejs/core\";\n\nexport class EntityCountContributor implements DebugContributor {\n readonly name = \"entities\";\n readonly flags: readonly string[] = [];\n\n constructor(private readonly inspector: Inspector) {}\n\n drawHud(api: HudDebugApi): void {\n const count = this.inspector.snapshot().entityCount;\n api.addLine(`Entities: ${count}`);\n }\n}\n","import type { DebugContributor, StatsApi, HudDebugApi } from \"../types.js\";\n\nexport class SystemTimingContributor implements DebugContributor {\n readonly name = \"timing\";\n readonly flags = [\"breakdown\"] as const;\n private stats: StatsApi | null = null;\n\n constructor(private readonly timings: Map<string, number>) {}\n\n sample(stats: StatsApi): void {\n this.stats = stats;\n for (const [name, ms] of this.timings) {\n stats.push(`system.${name}`, ms);\n }\n }\n\n drawHud(api: HudDebugApi): void {\n if (!this.stats) return;\n\n let total = 0;\n const entries: Array<[string, number]> = [];\n for (const name of this.timings.keys()) {\n const avg = this.stats.average(`system.${name}`);\n total += avg;\n entries.push([name, avg]);\n }\n\n api.addLine(`Systems: ${total.toFixed(2)}ms`);\n\n if (api.isFlagEnabled(\"breakdown\")) {\n entries.sort((a, b) => b[1] - a[1]);\n for (const [name, avg] of entries) {\n api.addLine(` ${name}: ${avg.toFixed(2)}ms`);\n }\n }\n }\n}\n"],"mappings":"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","names":["import_core","import_pixi","import_core"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/DebugPlugin.ts","../src/types.ts","../src/DebugClock.ts","../src/DebugRegistryImpl.ts","../src/DebugScene.ts","../src/StatsStore.ts","../src/GraphicsPool.ts","../src/TextPool.ts","../src/WorldDebugApiImpl.ts","../src/HudDebugApiImpl.ts","../src/DebugRenderSystem.ts","../src/contributors/FpsContributor.ts","../src/contributors/EntityCountContributor.ts","../src/contributors/SystemTimingContributor.ts"],"sourcesContent":["export { DebugPlugin } from \"./DebugPlugin.js\";\nexport type { DebugConfig } from \"./DebugPlugin.js\";\nexport type { IDebugClock } from \"./DebugClock.js\";\nexport { DebugRegistryImpl } from \"./DebugRegistryImpl.js\";\nexport { StatsStore } from \"./StatsStore.js\";\n","import {\n EventBusKey,\n GameLoopKey,\n InspectorKey,\n SceneManagerKey,\n} from \"@yagejs/core\";\nimport type {\n EngineContext,\n EventBus,\n EngineEvents,\n Inspector,\n Plugin,\n SceneManager,\n System,\n SystemScheduler,\n} from \"@yagejs/core\";\nimport { DebugRegistryKey } from \"./types.js\";\nimport { CameraComponent, RendererKey } from \"@yagejs/renderer\";\nimport type { RendererPlugin, SceneRenderTreeProvider } from \"@yagejs/renderer\";\nimport { SceneRenderTreeProviderKey } from \"@yagejs/renderer\";\nimport type { Container } from \"pixi.js\";\nimport { DebugClock } from \"./DebugClock.js\";\nimport type { IDebugClock } from \"./DebugClock.js\";\nimport { DebugRegistryImpl } from \"./DebugRegistryImpl.js\";\nimport { DebugScene } from \"./DebugScene.js\";\nimport { StatsStore } from \"./StatsStore.js\";\nimport { GraphicsPool } from \"./GraphicsPool.js\";\nimport { TextPool } from \"./TextPool.js\";\nimport { WorldDebugApiImpl } from \"./WorldDebugApiImpl.js\";\nimport { HudDebugApiImpl } from \"./HudDebugApiImpl.js\";\nimport { DebugRenderSystem } from \"./DebugRenderSystem.js\";\nimport { FpsContributor } from \"./contributors/FpsContributor.js\";\nimport { EntityCountContributor } from \"./contributors/EntityCountContributor.js\";\nimport { SystemTimingContributor } from \"./contributors/SystemTimingContributor.js\";\n\n/** Configuration for the DebugPlugin. */\nexport interface DebugConfig {\n /** Key code to toggle debug overlay. Default: \"Backquote\" */\n toggleKey?: string;\n /** When true, stop the renderer ticker and advance simulation manually via `window.__yage__.clock`. */\n manualClock?: boolean;\n /** Key code to advance one fixed-timestep frame while manual clock mode is active. Default: \"Period\" */\n stepKey?: string;\n /** Max pooled Graphics objects. Default: 256 */\n maxGraphics?: number;\n /** Max HUD text lines. Default: 32 */\n maxHudLines?: number;\n /** Whether the overlay starts enabled. Default: false */\n startEnabled?: boolean;\n /** Initial flag overrides, keyed by \"contributorName.flagName\". */\n flags?: Record<string, boolean>;\n}\n\ninterface LayerTransformSnapshot {\n x: number;\n y: number;\n scaleX: number;\n scaleY: number;\n rotation: number;\n}\n\ninterface CameraStackSnapshot {\n scene: string;\n name: string | undefined;\n priority: number;\n enabled: boolean;\n}\n\ninterface InspectorDiagnostics {\n getLayerTransform(\n sceneName: string,\n layerName: string,\n ): LayerTransformSnapshot | undefined;\n getCameraStack(): CameraStackSnapshot[];\n}\n\n/**\n * Debug overlay plugin. Mounts a private `DebugScene` through\n * `SceneManager._mountDetached` so it goes through the same scoped-DI\n * lifecycle as stacked scenes (the renderer's `beforeEnter` hook creates\n * its render tree) while staying off the user-visible scene stack.\n */\nexport class DebugPlugin implements Plugin {\n readonly name = \"debug\";\n readonly version = \"3.0.0\";\n readonly dependencies = [\"renderer\"] as const;\n\n private readonly config: DebugConfig;\n private registry!: DebugRegistryImpl;\n private stats!: StatsStore;\n private graphicsPool: GraphicsPool | null = null;\n private textPool: TextPool | null = null;\n private worldApi: WorldDebugApiImpl | null = null;\n private hudApi: HudDebugApiImpl | null = null;\n private renderSystem: DebugRenderSystem | null = null;\n private systemTimings = new Map<string, number>();\n private originalUpdates = new Map<System, (dt: number) => void>();\n private keyListener: ((e: KeyboardEvent) => void) | null = null;\n private context!: EngineContext;\n private renderer!: RendererPlugin;\n private scheduler!: SystemScheduler;\n private sceneManager!: SceneManager;\n private debugScene: DebugScene | null = null;\n private provider: SceneRenderTreeProvider | null = null;\n private eventUnsubs: Array<() => void> = [];\n private clock: DebugClock | null = null;\n\n constructor(config?: DebugConfig) {\n this.config = config ?? {};\n }\n\n install(context: EngineContext): void {\n this.context = context;\n this.renderer = context.resolve(RendererKey);\n\n this.registry = new DebugRegistryImpl();\n this.registry.enabled = this.config.startEnabled ?? false;\n\n if (this.config.flags) {\n for (const [key, value] of Object.entries(this.config.flags)) {\n const dot = key.indexOf(\".\");\n if (dot > 0) {\n this.registry.setFlag(key.slice(0, dot), key.slice(dot + 1), value);\n }\n }\n }\n\n this.stats = new StatsStore();\n\n context.register(DebugRegistryKey, this.registry);\n }\n\n registerSystems(scheduler: SystemScheduler): void {\n // DebugRenderSystem is registered lazily once the debug scene is ready —\n // its constructor needs the scene's layer containers.\n this.scheduler = scheduler;\n }\n\n async onStart(): Promise<void> {\n this.sceneManager = this.context.resolve(SceneManagerKey);\n const bus = this.context.resolve(EventBusKey) as EventBus<EngineEvents>;\n\n // Key listeners (toggle, manual-clock step)\n const toggleKey = this.config.toggleKey ?? \"Backquote\";\n const stepKey = this.config.stepKey ?? \"Period\";\n this.keyListener = (e: KeyboardEvent) => {\n if (e.code === toggleKey) {\n this.registry.toggle();\n return;\n }\n if (e.code === stepKey && this.clock?.isManual) {\n e.preventDefault();\n this.clock.step();\n }\n };\n if (typeof window !== \"undefined\") {\n window.addEventListener(\"keydown\", this.keyListener);\n }\n\n // Instrument system timings — reuse the scheduler captured in\n // `registerSystems`, which ran before `onStart`.\n for (const system of this.scheduler.getAllSystems()) {\n if (system instanceof DebugRenderSystem) continue;\n const name = system.constructor.name;\n const original = system.update.bind(system);\n this.originalUpdates.set(system, original);\n system.update = (dt: number) => {\n const t0 = performance.now();\n original(dt);\n this.systemTimings.set(name, performance.now() - t0);\n };\n }\n\n // Built-in contributors\n const inspector = this.context.resolve(InspectorKey);\n this.registry.register(new FpsContributor());\n this.registry.register(new EntityCountContributor(inspector));\n this.registry.register(new SystemTimingContributor(this.systemTimings));\n\n // Manual clock for deterministic stepping\n const gameLoop = this.context.resolve(GameLoopKey);\n const app = this.renderer.application;\n this.clock = new DebugClock(\n gameLoop,\n () => app.stop(),\n () => app.start(),\n () => app.render(),\n );\n if (this.config.manualClock) {\n this.clock.setManual(true);\n }\n this.attachToGlobal(this.clock);\n\n // Materialize the debug scene off-stack. `_mountDetached` routes through\n // the same beforeEnter hooks as `push`, so the renderer materializes the\n // debug scene's tree and registers SceneRenderTreeKey on its scope.\n this.provider = this.context.tryResolve(SceneRenderTreeProviderKey) ?? null;\n this.attachInspectorDiagnostics(inspector);\n await this.materializeDebugScene();\n\n // Keep the debug scene visually on top of the user stack after any\n // push/pop/replace by reordering its root containers.\n const bringToFront = () => {\n if (this.debugScene && this.provider?.bringSceneToFront) {\n this.provider.bringSceneToFront(this.debugScene);\n }\n };\n this.eventUnsubs.push(bus.on(\"scene:pushed\", bringToFront));\n this.eventUnsubs.push(bus.on(\"scene:popped\", bringToFront));\n this.eventUnsubs.push(bus.on(\"scene:replaced\", bringToFront));\n }\n\n onDestroy(): void {\n for (const unsub of this.eventUnsubs) unsub();\n this.eventUnsubs.length = 0;\n\n for (const [system, original] of this.originalUpdates) {\n system.update = original;\n }\n this.originalUpdates.clear();\n\n if (this.keyListener) {\n if (typeof window !== \"undefined\") {\n window.removeEventListener(\"keydown\", this.keyListener);\n }\n this.keyListener = null;\n }\n\n this.detachFromGlobal();\n this.clock = null;\n\n for (const contributor of this.registry.contributors.values()) {\n contributor.dispose?.();\n }\n this.registry.contributors.clear();\n\n this.tearDownDebugInfra();\n this.teardownDebugScene();\n }\n\n private async materializeDebugScene(): Promise<void> {\n const scene = new DebugScene();\n scene.onReady = (worldContainer, hudContainer) =>\n this.setUpDebugInfra(worldContainer, hudContainer);\n scene.onTearDown = () => this.tearDownDebugInfra();\n await this.sceneManager._mountDetached(scene);\n this.debugScene = scene;\n }\n\n private teardownDebugScene(): void {\n // If destroy is called while `_mountDetached` is still pending, we don't\n // yet hold a reference to the partially-mounted scene. Skipping unmount\n // here is safe: onDestroy still runs `tearDownDebugInfra` below, and the\n // engine teardown tears down the renderer next which destroys any\n // half-created provider entries.\n if (!this.debugScene) return;\n this.sceneManager._unmountDetached(this.debugScene);\n this.debugScene = null;\n this.provider = null;\n }\n\n private findActiveCamera(): CameraComponent | undefined {\n return findTopmostCamera(this.sceneManager);\n }\n\n private setUpDebugInfra(\n worldContainer: Container,\n hudContainer: Container,\n ): void {\n const vw = this.renderer.virtualSize.width;\n const vh = this.renderer.virtualSize.height;\n\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const self = this;\n // Lazy camera accessor — reads from whichever stacked scene has a camera\n const cameraProxy = {\n get zoom() {\n return self.findActiveCamera()?.zoom ?? 1;\n },\n };\n\n this.graphicsPool = new GraphicsPool(\n worldContainer,\n this.config.maxGraphics,\n );\n this.textPool = new TextPool(hudContainer, this.config.maxHudLines);\n\n this.worldApi = new WorldDebugApiImpl(\n this.graphicsPool,\n this.registry,\n cameraProxy,\n );\n this.hudApi = new HudDebugApiImpl(this.textPool, this.registry, vw, vh);\n\n this.renderSystem = new DebugRenderSystem(\n this.registry,\n this.graphicsPool,\n this.textPool,\n this.worldApi,\n this.hudApi,\n this.stats,\n worldContainer,\n hudContainer,\n {\n findCamera: () => self.findActiveCamera(),\n viewportWidth: vw,\n viewportHeight: vh,\n },\n );\n this.scheduler.add(this.renderSystem);\n }\n\n private tearDownDebugInfra(): void {\n if (this.renderSystem) {\n this.scheduler.remove(this.renderSystem);\n this.renderSystem = null;\n }\n this.graphicsPool?.destroy();\n this.textPool?.destroy();\n this.graphicsPool = null;\n this.textPool = null;\n this.worldApi = null;\n this.hudApi = null;\n }\n\n private attachInspectorDiagnostics(inspector: Inspector): void {\n const g = (globalThis as Record<string, unknown>)[\"__yage__\"];\n if (!g || typeof g !== \"object\") return;\n\n const debugSurface = g as Record<string, unknown>;\n const diagnostics = inspector as Inspector & InspectorDiagnostics;\n debugSurface[\"inspector\"] = inspector;\n\n diagnostics.getLayerTransform = (sceneName, layerName) => {\n const scene = this.sceneManager.all.find(\n (candidate) => candidate.name === sceneName,\n );\n if (!scene) return undefined;\n\n const layer = this.provider?.getTree(scene)?.tryGet(layerName);\n if (!layer) return undefined;\n\n const container = layer.container;\n return {\n x: container.position.x,\n y: container.position.y,\n scaleX: container.scale.x,\n scaleY: container.scale.y,\n rotation: container.rotation,\n };\n };\n\n diagnostics.getCameraStack = () => {\n const cameras: CameraStackSnapshot[] = [];\n for (const scene of this.sceneManager.all) {\n for (const entity of scene.getEntities()) {\n const cam = entity.tryGet(CameraComponent);\n if (!cam) continue;\n cameras.push({\n scene: scene.name,\n name: cam.cameraName,\n priority: cam.priority,\n enabled: cam.enabled,\n });\n }\n }\n return cameras;\n };\n }\n\n private attachToGlobal(clock: IDebugClock): void {\n const g = (globalThis as Record<string, unknown>)[\"__yage__\"];\n if (g && typeof g === \"object\") {\n (g as Record<string, unknown>)[\"clock\"] = clock;\n }\n }\n\n private detachFromGlobal(): void {\n const g = (globalThis as Record<string, unknown>)[\"__yage__\"];\n if (\n g &&\n typeof g === \"object\" &&\n (g as Record<string, unknown>)[\"clock\"] === this.clock\n ) {\n delete (g as Record<string, unknown>)[\"clock\"];\n }\n }\n}\n\n/**\n * Find the highest-priority enabled camera on the topmost scene that has one.\n * `sceneManager.all` is bottom→top, so we walk in reverse — a pause/HUD\n * scene's camera wins over a frozen scene beneath it.\n */\nexport function findTopmostCamera(\n sceneManager: SceneManager,\n): CameraComponent | undefined {\n const stack = sceneManager.all;\n for (let i = stack.length - 1; i >= 0; i--) {\n const scene = stack[i];\n if (!scene) continue;\n let highestPriorityCamera: CameraComponent | undefined;\n for (const entity of scene.getEntities()) {\n const cam = entity.tryGet(CameraComponent);\n if (\n cam &&\n cam.enabled &&\n (!highestPriorityCamera ||\n cam.priority > highestPriorityCamera.priority)\n ) {\n highestPriorityCamera = cam;\n }\n }\n if (highestPriorityCamera) return highestPriorityCamera;\n }\n return undefined;\n}\n","import { ServiceKey } from \"@yagejs/core\";\n\n/**\n * Minimal subset of PixiJS Graphics used by debug drawing.\n * Avoids a runtime pixi.js dependency in the ./api subpath.\n */\nexport interface DebugGraphics {\n position: { x: number; y: number };\n rotation: number;\n visible: boolean;\n clear(): DebugGraphics;\n rect(x: number, y: number, width: number, height: number): DebugGraphics;\n circle(x: number, y: number, radius: number): DebugGraphics;\n moveTo(x: number, y: number): DebugGraphics;\n lineTo(x: number, y: number): DebugGraphics;\n stroke(style: { width: number; color: number; alpha?: number }): DebugGraphics;\n fill(style: { color: number; alpha?: number }): DebugGraphics;\n}\n\n/** Camera-space drawing API passed to contributors. */\nexport interface WorldDebugApi {\n acquireGraphics(): DebugGraphics | undefined;\n isFlagEnabled(flag: string): boolean;\n readonly cameraZoom: number;\n}\n\n/** Screen-space HUD API passed to contributors. */\nexport interface HudDebugApi {\n addLine(text: string): void;\n isFlagEnabled(flag: string): boolean;\n readonly screenWidth: number;\n readonly screenHeight: number;\n}\n\n/** Rolling-window statistics collector. */\nexport interface StatsApi {\n push(key: string, value: number): void;\n average(key: string): number;\n latest(key: string): number;\n min(key: string): number;\n max(key: string): number;\n}\n\n/** A debug contributor that registers drawing/sampling callbacks. */\nexport interface DebugContributor {\n readonly name: string;\n readonly flags: readonly string[];\n drawWorld?(api: WorldDebugApi): void;\n drawHud?(api: HudDebugApi): void;\n sample?(stats: StatsApi, dt: number): void;\n dispose?(): void;\n}\n\n/** Service interface for the debug registry. */\nexport interface DebugRegistry {\n register(contributor: DebugContributor): void;\n isEnabled(): boolean;\n isFlagEnabled(contributorName: string, flag: string): boolean;\n}\n\n/** Service key for resolving the DebugRegistry via DI. */\nexport const DebugRegistryKey = new ServiceKey<DebugRegistry>(\"debugRegistry\");\n","/** Public interface for the manual debug clock, accessible via `window.__yage__.clock`. */\nexport interface IDebugClock {\n readonly isManual: boolean;\n startAuto(): void;\n stopAuto(): void;\n step(dtMs?: number): void;\n stepFrames(count: number, dtMs?: number): void;\n}\n\n/** Minimal view of a game loop needed by the debug clock. */\ninterface GameLoopLike {\n tick(dtMs: number): void;\n readonly fixedTimestep: number;\n}\n\n/**\n * Controls engine time-stepping for deterministic E2E tests.\n *\n * When manual mode is active the renderer ticker is paused and frames\n * advance only via explicit `step()` / `stepFrames()` calls.\n */\nexport class DebugClock implements IDebugClock {\n private _isManual = false;\n\n constructor(\n private readonly gameLoop: GameLoopLike,\n private readonly stopTicker: () => void,\n private readonly startTicker: () => void,\n private readonly render: () => void,\n ) {}\n\n get isManual(): boolean {\n return this._isManual;\n }\n\n startAuto(): void {\n if (!this._isManual) return;\n this.startTicker();\n this._isManual = false;\n }\n\n stopAuto(): void {\n if (this._isManual) return;\n this.stopTicker();\n this._isManual = true;\n }\n\n step(dtMs?: number): void {\n if (!this._isManual) {\n throw new Error(\n \"Manual clock is not active. Call clock.stopAuto() first.\",\n );\n }\n const dt = dtMs ?? this.gameLoop.fixedTimestep;\n this.gameLoop.tick(dt);\n this.render();\n }\n\n stepFrames(count: number, dtMs?: number): void {\n if (!Number.isInteger(count) || count < 0) {\n throw new Error(\n \"stepFrames(count) requires a non-negative integer count.\",\n );\n }\n for (let i = 0; i < count; i++) {\n this.step(dtMs);\n }\n }\n\n /** Enter or exit manual mode. Used by DebugPlugin for config-driven init. */\n setManual(enabled: boolean): void {\n if (enabled === this._isManual) return;\n if (enabled) {\n this.stopTicker();\n } else {\n this.startTicker();\n }\n this._isManual = enabled;\n }\n}\n","import type { DebugContributor, DebugRegistry } from \"./types.js\";\n\n/** Concrete implementation of the DebugRegistry interface. */\nexport class DebugRegistryImpl implements DebugRegistry {\n readonly contributors = new Map<string, DebugContributor>();\n enabled = false;\n private flags = new Map<string, boolean>();\n\n register(contributor: DebugContributor): void {\n if (this.contributors.has(contributor.name)) return;\n this.contributors.set(contributor.name, contributor);\n for (const flag of contributor.flags) {\n this.flags.set(`${contributor.name}.${flag}`, true);\n }\n }\n\n isEnabled(): boolean {\n return this.enabled;\n }\n\n isFlagEnabled(contributorName: string, flag: string): boolean {\n return this.flags.get(`${contributorName}.${flag}`) ?? true;\n }\n\n toggle(): void {\n this.enabled = !this.enabled;\n }\n\n toggleFlag(contributorName: string, flag: string): void {\n const key = `${contributorName}.${flag}`;\n this.flags.set(key, !(this.flags.get(key) ?? true));\n }\n\n setFlag(contributorName: string, flag: string, value: boolean): void {\n this.flags.set(`${contributorName}.${flag}`, value);\n }\n}\n","import { LoggerKey, Scene } from \"@yagejs/core\";\nimport type { Logger } from \"@yagejs/core\";\nimport type { LayerDef } from \"@yagejs/renderer\";\nimport { SceneRenderTreeKey } from \"@yagejs/renderer\";\nimport type { Container } from \"pixi.js\";\n\n/**\n * Scene mounted by the debug plugin via `SceneManager._mountDetached`.\n * Declares two layers:\n * - `\"debug-world\"` — world-space, rides the camera (for collision shapes).\n * - `\"debug-hud\"` — screen-space, fixed overlay (text readouts).\n *\n * `pauseBelow: false` / `transparentBelow: true` so the underlying game\n * keeps running and rendering behind the overlay.\n */\nexport class DebugScene extends Scene {\n readonly name = \"__debug__\";\n override readonly pauseBelow = false;\n override readonly transparentBelow = true;\n readonly layers: readonly LayerDef[] = [\n { name: \"debug-world\", order: 999999 },\n { name: \"debug-hud\", order: 999999 },\n ];\n\n /** Called after `_mountDetached` has materialized the render tree. */\n onReady?: (worldContainer: Container, hudContainer: Container) => void;\n\n /** Called by the plugin when the scene is unmounted. */\n onTearDown?: () => void;\n\n onEnter(): void {\n const tree = this._resolveScoped(SceneRenderTreeKey);\n if (!tree) {\n // Shouldn't happen — DebugPlugin declares `renderer` as a dependency\n // so the renderer's `beforeEnter` hook should have materialized a\n // tree before this runs. Surface it rather than silently skipping\n // the overlay wiring.\n const logger = this.context.tryResolve(LoggerKey) as Logger | undefined;\n const msg =\n \"DebugScene.onEnter: SceneRenderTreeKey missing — debug overlay will not render. Is RendererPlugin registered?\";\n if (logger) logger.warn(\"debug\", msg);\n else console.warn(`[yage] ${msg}`);\n return;\n }\n const worldContainer = tree.get(\"debug-world\").container;\n const hudContainer = tree.get(\"debug-hud\").container;\n worldContainer.eventMode = \"none\";\n hudContainer.eventMode = \"none\";\n this.onReady?.(worldContainer, hudContainer);\n }\n\n onExit(): void {\n this.onTearDown?.();\n }\n}\n","import type { StatsApi } from \"./types.js\";\n\nconst WINDOW_SIZE = 120;\n\ninterface RingBuffer {\n data: Float64Array;\n count: number;\n index: number;\n}\n\n/** Rolling-window statistics store backed by Float64Array ring buffers. */\nexport class StatsStore implements StatsApi {\n private rings = new Map<string, RingBuffer>();\n\n push(key: string, value: number): void {\n let ring = this.rings.get(key);\n if (!ring) {\n ring = { data: new Float64Array(WINDOW_SIZE), count: 0, index: 0 };\n this.rings.set(key, ring);\n }\n ring.data[ring.index] = value;\n ring.index = (ring.index + 1) % WINDOW_SIZE;\n if (ring.count < WINDOW_SIZE) ring.count++;\n }\n\n average(key: string): number {\n const ring = this.rings.get(key);\n if (!ring || ring.count === 0) return 0;\n const { data, count } = ring;\n let sum = 0;\n for (let i = 0; i < count; i++) sum += data[i] ?? 0;\n return sum / count;\n }\n\n latest(key: string): number {\n const ring = this.rings.get(key);\n if (!ring || ring.count === 0) return 0;\n return ring.data[(ring.index - 1 + WINDOW_SIZE) % WINDOW_SIZE] ?? 0;\n }\n\n min(key: string): number {\n const ring = this.rings.get(key);\n if (!ring || ring.count === 0) return 0;\n const { data, count } = ring;\n let m = Infinity;\n for (let i = 0; i < count; i++) {\n const v = data[i] ?? 0;\n if (v < m) m = v;\n }\n return m;\n }\n\n max(key: string): number {\n const ring = this.rings.get(key);\n if (!ring || ring.count === 0) return 0;\n const { data, count } = ring;\n let m = -Infinity;\n for (let i = 0; i < count; i++) {\n const v = data[i] ?? 0;\n if (v > m) m = v;\n }\n return m;\n }\n}\n","import { Graphics, Container } from \"pixi.js\";\n\n/** Allocation-free pool of PixiJS Graphics objects for debug drawing. */\nexport class GraphicsPool {\n private pool: Graphics[] | null = null;\n private index = 0;\n private readonly container: Container;\n private readonly maxSize: number;\n\n constructor(container: Container, maxSize = 256) {\n this.container = container;\n this.maxSize = maxSize;\n }\n\n /** Lazily create Graphics objects on first use (ensures PixiJS is fully ready). */\n private ensure(): Graphics[] {\n if (this.pool) return this.pool;\n this.pool = [];\n for (let i = 0; i < this.maxSize; i++) {\n const g = new Graphics();\n g.visible = false;\n g.eventMode = \"none\";\n this.container.addChild(g);\n this.pool.push(g);\n }\n return this.pool;\n }\n\n /** Return the next available Graphics, or undefined if the pool is exhausted. */\n acquire(): Graphics | undefined {\n const pool = this.ensure();\n if (this.index >= pool.length) return undefined;\n const g = pool[this.index]!;\n g.visible = true;\n this.index++;\n return g;\n }\n\n /** Clear and hide all previously acquired graphics, reset index. */\n resetFrame(): void {\n if (!this.pool) return;\n for (let i = 0; i < this.index; i++) {\n const g = this.pool[i]!;\n g.clear();\n g.visible = false;\n g.position.set(0, 0);\n g.rotation = 0;\n g.scale.set(1, 1);\n }\n this.index = 0;\n }\n\n destroy(): void {\n if (!this.pool) return;\n for (const g of this.pool) {\n g.destroy();\n }\n this.pool.length = 0;\n }\n}\n","import { Text, Container } from \"pixi.js\";\n\nconst LINE_HEIGHT = 16;\nconst FONT_SIZE = 14;\nconst PADDING = 4;\n\n/** Allocation-free pool of PixiJS Text objects for HUD debug lines. */\nexport class TextPool {\n private pool: Text[] | null = null;\n private index = 0;\n private readonly container: Container;\n private readonly maxLines: number;\n\n constructor(container: Container, maxLines = 32) {\n this.container = container;\n this.maxLines = maxLines;\n }\n\n /** Lazily create Text objects on first use (ensures PixiJS is fully ready). */\n private ensure(): Text[] {\n if (this.pool) return this.pool;\n this.pool = [];\n for (let i = 0; i < this.maxLines; i++) {\n const t = new Text({\n text: \"\",\n style: {\n fontFamily: \"monospace\",\n fontSize: FONT_SIZE,\n fill: 0xffffff,\n },\n });\n t.visible = false;\n t.eventMode = \"none\";\n this.container.addChild(t);\n this.pool.push(t);\n }\n return this.pool;\n }\n\n /** Show a text line at the next available slot. */\n addLine(text: string): void {\n const pool = this.ensure();\n if (this.index >= pool.length) return;\n const t = pool[this.index]!;\n t.text = text;\n t.visible = true;\n t.position.set(PADDING, PADDING + this.index * LINE_HEIGHT);\n this.index++;\n }\n\n /** Hide all lines and reset for the next frame. */\n resetFrame(): void {\n if (!this.pool) return;\n for (let i = 0; i < this.index; i++) {\n this.pool[i]!.visible = false;\n }\n this.index = 0;\n }\n\n destroy(): void {\n if (!this.pool) return;\n for (const t of this.pool) {\n t.destroy();\n }\n this.pool.length = 0;\n }\n}\n","import type { WorldDebugApi, DebugGraphics } from \"./types.js\";\nimport type { GraphicsPool } from \"./GraphicsPool.js\";\nimport type { DebugRegistryImpl } from \"./DebugRegistryImpl.js\";\n\n/** WorldDebugApi backed by a GraphicsPool. Contributor name is swapped per iteration. */\nexport class WorldDebugApiImpl implements WorldDebugApi {\n private _contributorName = \"\";\n\n constructor(\n private readonly pool: GraphicsPool,\n private readonly registry: DebugRegistryImpl,\n private readonly _camera: { zoom: number },\n ) {}\n\n /** Set the current contributor name (called before each contributor's drawWorld). */\n setContributor(name: string): void {\n this._contributorName = name;\n }\n\n acquireGraphics(): DebugGraphics | undefined {\n return this.pool.acquire() as unknown as DebugGraphics | undefined;\n }\n\n isFlagEnabled(flag: string): boolean {\n return this.registry.isFlagEnabled(this._contributorName, flag);\n }\n\n get cameraZoom(): number {\n return this._camera.zoom;\n }\n}\n","import type { HudDebugApi } from \"./types.js\";\nimport type { TextPool } from \"./TextPool.js\";\nimport type { DebugRegistryImpl } from \"./DebugRegistryImpl.js\";\n\n/** HudDebugApi backed by a TextPool. Contributor name is swapped per iteration. */\nexport class HudDebugApiImpl implements HudDebugApi {\n private _contributorName = \"\";\n\n constructor(\n private readonly textPool: TextPool,\n private readonly registry: DebugRegistryImpl,\n public readonly screenWidth: number,\n public readonly screenHeight: number,\n ) {}\n\n /** Set the current contributor name (called before each contributor's drawHud). */\n setContributor(name: string): void {\n this._contributorName = name;\n }\n\n addLine(text: string): void {\n this.textPool.addLine(text);\n }\n\n isFlagEnabled(flag: string): boolean {\n return this.registry.isFlagEnabled(this._contributorName, flag);\n }\n}\n","import { System, Phase } from \"@yagejs/core\";\nimport type { Container } from \"pixi.js\";\nimport type { CameraComponent } from \"@yagejs/renderer\";\nimport type { DebugRegistryImpl } from \"./DebugRegistryImpl.js\";\nimport type { GraphicsPool } from \"./GraphicsPool.js\";\nimport type { TextPool } from \"./TextPool.js\";\nimport type { WorldDebugApiImpl } from \"./WorldDebugApiImpl.js\";\nimport type { HudDebugApiImpl } from \"./HudDebugApiImpl.js\";\nimport type { StatsStore } from \"./StatsStore.js\";\n\nexport interface DebugCameraAccessor {\n findCamera(): CameraComponent | undefined;\n viewportWidth: number;\n viewportHeight: number;\n}\n\n/** Renders all debug contributors. Runs after DisplaySystem in the Render phase. */\nexport class DebugRenderSystem extends System {\n readonly phase = Phase.Render;\n readonly priority = 9999;\n\n constructor(\n private readonly registry: DebugRegistryImpl,\n private readonly graphicsPool: GraphicsPool,\n private readonly textPool: TextPool,\n private readonly worldApi: WorldDebugApiImpl,\n private readonly hudApi: HudDebugApiImpl,\n private readonly stats: StatsStore,\n private readonly worldContainer: Container,\n private readonly hudContainer: Container,\n private readonly cameraAccessor: DebugCameraAccessor,\n ) {\n super();\n }\n\n update(dt: number): void {\n if (!this.registry.enabled) {\n this.worldContainer.visible = false;\n this.hudContainer.visible = false;\n return;\n }\n\n this.worldContainer.visible = true;\n this.hudContainer.visible = true;\n\n // Apply camera transform to the debug world container so that\n // world-space debug drawing (collision shapes, etc.) aligns with\n // the active scene's camera.\n this.syncWorldCamera();\n\n this.graphicsPool.resetFrame();\n this.textPool.resetFrame();\n\n for (const [name, contributor] of this.registry.contributors) {\n contributor.sample?.(this.stats, dt);\n\n if (contributor.drawWorld) {\n this.worldApi.setContributor(name);\n contributor.drawWorld(this.worldApi);\n }\n\n if (contributor.drawHud) {\n this.hudApi.setContributor(name);\n contributor.drawHud(this.hudApi);\n }\n }\n }\n\n private syncWorldCamera(): void {\n const cam = this.cameraAccessor.findCamera();\n if (!cam) {\n this.worldContainer.position.set(0, 0);\n this.worldContainer.scale.set(1, 1);\n this.worldContainer.rotation = 0;\n return;\n }\n\n const vw = this.cameraAccessor.viewportWidth;\n const vh = this.cameraAccessor.viewportHeight;\n const rotatedPos = cam.effectivePosition\n .scale(cam.zoom)\n .rotate(-cam.rotation);\n this.worldContainer.position.x = vw / 2 - rotatedPos.x;\n this.worldContainer.position.y = vh / 2 - rotatedPos.y;\n this.worldContainer.scale.set(cam.zoom);\n this.worldContainer.rotation = -cam.rotation;\n }\n}\n","import type { DebugContributor, StatsApi, HudDebugApi } from \"../types.js\";\n\nexport class FpsContributor implements DebugContributor {\n readonly name = \"fps\";\n readonly flags: readonly string[] = [];\n private stats: StatsApi | null = null;\n\n sample(stats: StatsApi, dt: number): void {\n this.stats = stats;\n if (dt > 0) stats.push(\"fps\", 1000 / dt);\n }\n\n drawHud(api: HudDebugApi): void {\n const avg = this.stats?.average(\"fps\") ?? 0;\n api.addLine(`FPS: ${Math.round(avg)}`);\n }\n}\n","import type { DebugContributor, HudDebugApi } from \"../types.js\";\nimport type { Inspector } from \"@yagejs/core\";\n\nexport class EntityCountContributor implements DebugContributor {\n readonly name = \"entities\";\n readonly flags: readonly string[] = [];\n\n constructor(private readonly inspector: Inspector) {}\n\n drawHud(api: HudDebugApi): void {\n const count = this.inspector.snapshot().entityCount;\n api.addLine(`Entities: ${count}`);\n }\n}\n","import type { DebugContributor, StatsApi, HudDebugApi } from \"../types.js\";\n\nexport class SystemTimingContributor implements DebugContributor {\n readonly name = \"timing\";\n readonly flags = [\"breakdown\"] as const;\n private stats: StatsApi | null = null;\n\n constructor(private readonly timings: Map<string, number>) {}\n\n sample(stats: StatsApi): void {\n this.stats = stats;\n for (const [name, ms] of this.timings) {\n stats.push(`system.${name}`, ms);\n }\n }\n\n drawHud(api: HudDebugApi): void {\n if (!this.stats) return;\n\n let total = 0;\n const entries: Array<[string, number]> = [];\n for (const name of this.timings.keys()) {\n const avg = this.stats.average(`system.${name}`);\n total += avg;\n entries.push([name, avg]);\n }\n\n api.addLine(`Systems: ${total.toFixed(2)}ms`);\n\n if (api.isFlagEnabled(\"breakdown\")) {\n entries.sort((a, b) => b[1] - a[1]);\n for (const [name, avg] of entries) {\n api.addLine(` ${name}: ${avg.toFixed(2)}ms`);\n }\n }\n }\n}\n"],"mappings":"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","names":["import_core","import_renderer","import_core","import_pixi","import_core"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -18,31 +18,46 @@ interface DebugConfig {
|
|
|
18
18
|
/** Initial flag overrides, keyed by "contributorName.flagName". */
|
|
19
19
|
flags?: Record<string, boolean>;
|
|
20
20
|
}
|
|
21
|
-
/**
|
|
21
|
+
/**
|
|
22
|
+
* Debug overlay plugin. Mounts a private `DebugScene` through
|
|
23
|
+
* `SceneManager._mountDetached` so it goes through the same scoped-DI
|
|
24
|
+
* lifecycle as stacked scenes (the renderer's `beforeEnter` hook creates
|
|
25
|
+
* its render tree) while staying off the user-visible scene stack.
|
|
26
|
+
*/
|
|
22
27
|
declare class DebugPlugin implements Plugin {
|
|
23
28
|
readonly name = "debug";
|
|
24
|
-
readonly version = "
|
|
29
|
+
readonly version = "3.0.0";
|
|
25
30
|
readonly dependencies: readonly ["renderer"];
|
|
26
31
|
private readonly config;
|
|
27
32
|
private registry;
|
|
28
33
|
private stats;
|
|
29
34
|
private graphicsPool;
|
|
30
35
|
private textPool;
|
|
31
|
-
private worldContainer;
|
|
32
|
-
private hudContainer;
|
|
33
36
|
private worldApi;
|
|
34
37
|
private hudApi;
|
|
38
|
+
private renderSystem;
|
|
35
39
|
private systemTimings;
|
|
36
40
|
private originalUpdates;
|
|
37
41
|
private keyListener;
|
|
38
42
|
private context;
|
|
39
43
|
private renderer;
|
|
44
|
+
private scheduler;
|
|
45
|
+
private sceneManager;
|
|
46
|
+
private debugScene;
|
|
47
|
+
private provider;
|
|
48
|
+
private eventUnsubs;
|
|
40
49
|
private clock;
|
|
41
50
|
constructor(config?: DebugConfig);
|
|
42
51
|
install(context: EngineContext): void;
|
|
43
52
|
registerSystems(scheduler: SystemScheduler): void;
|
|
44
|
-
onStart(): void
|
|
53
|
+
onStart(): Promise<void>;
|
|
45
54
|
onDestroy(): void;
|
|
55
|
+
private materializeDebugScene;
|
|
56
|
+
private teardownDebugScene;
|
|
57
|
+
private findActiveCamera;
|
|
58
|
+
private setUpDebugInfra;
|
|
59
|
+
private tearDownDebugInfra;
|
|
60
|
+
private attachInspectorDiagnostics;
|
|
46
61
|
private attachToGlobal;
|
|
47
62
|
private detachFromGlobal;
|
|
48
63
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -18,31 +18,46 @@ interface DebugConfig {
|
|
|
18
18
|
/** Initial flag overrides, keyed by "contributorName.flagName". */
|
|
19
19
|
flags?: Record<string, boolean>;
|
|
20
20
|
}
|
|
21
|
-
/**
|
|
21
|
+
/**
|
|
22
|
+
* Debug overlay plugin. Mounts a private `DebugScene` through
|
|
23
|
+
* `SceneManager._mountDetached` so it goes through the same scoped-DI
|
|
24
|
+
* lifecycle as stacked scenes (the renderer's `beforeEnter` hook creates
|
|
25
|
+
* its render tree) while staying off the user-visible scene stack.
|
|
26
|
+
*/
|
|
22
27
|
declare class DebugPlugin implements Plugin {
|
|
23
28
|
readonly name = "debug";
|
|
24
|
-
readonly version = "
|
|
29
|
+
readonly version = "3.0.0";
|
|
25
30
|
readonly dependencies: readonly ["renderer"];
|
|
26
31
|
private readonly config;
|
|
27
32
|
private registry;
|
|
28
33
|
private stats;
|
|
29
34
|
private graphicsPool;
|
|
30
35
|
private textPool;
|
|
31
|
-
private worldContainer;
|
|
32
|
-
private hudContainer;
|
|
33
36
|
private worldApi;
|
|
34
37
|
private hudApi;
|
|
38
|
+
private renderSystem;
|
|
35
39
|
private systemTimings;
|
|
36
40
|
private originalUpdates;
|
|
37
41
|
private keyListener;
|
|
38
42
|
private context;
|
|
39
43
|
private renderer;
|
|
44
|
+
private scheduler;
|
|
45
|
+
private sceneManager;
|
|
46
|
+
private debugScene;
|
|
47
|
+
private provider;
|
|
48
|
+
private eventUnsubs;
|
|
40
49
|
private clock;
|
|
41
50
|
constructor(config?: DebugConfig);
|
|
42
51
|
install(context: EngineContext): void;
|
|
43
52
|
registerSystems(scheduler: SystemScheduler): void;
|
|
44
|
-
onStart(): void
|
|
53
|
+
onStart(): Promise<void>;
|
|
45
54
|
onDestroy(): void;
|
|
55
|
+
private materializeDebugScene;
|
|
56
|
+
private teardownDebugScene;
|
|
57
|
+
private findActiveCamera;
|
|
58
|
+
private setUpDebugInfra;
|
|
59
|
+
private tearDownDebugInfra;
|
|
60
|
+
private attachInspectorDiagnostics;
|
|
46
61
|
private attachToGlobal;
|
|
47
62
|
private detachFromGlobal;
|
|
48
63
|
}
|
package/dist/index.js
CHANGED
|
@@ -4,8 +4,14 @@ import {
|
|
|
4
4
|
} from "./chunk-QSE3OVXA.js";
|
|
5
5
|
|
|
6
6
|
// src/DebugPlugin.ts
|
|
7
|
-
import {
|
|
8
|
-
|
|
7
|
+
import {
|
|
8
|
+
EventBusKey,
|
|
9
|
+
GameLoopKey,
|
|
10
|
+
InspectorKey,
|
|
11
|
+
SceneManagerKey
|
|
12
|
+
} from "@yagejs/core";
|
|
13
|
+
import { CameraComponent, RendererKey } from "@yagejs/renderer";
|
|
14
|
+
import { SceneRenderTreeProviderKey } from "@yagejs/renderer";
|
|
9
15
|
|
|
10
16
|
// src/DebugClock.ts
|
|
11
17
|
var DebugClock = class {
|
|
@@ -101,6 +107,44 @@ var DebugRegistryImpl = class {
|
|
|
101
107
|
}
|
|
102
108
|
};
|
|
103
109
|
|
|
110
|
+
// src/DebugScene.ts
|
|
111
|
+
import { LoggerKey, Scene } from "@yagejs/core";
|
|
112
|
+
import { SceneRenderTreeKey } from "@yagejs/renderer";
|
|
113
|
+
var DebugScene = class extends Scene {
|
|
114
|
+
static {
|
|
115
|
+
__name(this, "DebugScene");
|
|
116
|
+
}
|
|
117
|
+
name = "__debug__";
|
|
118
|
+
pauseBelow = false;
|
|
119
|
+
transparentBelow = true;
|
|
120
|
+
layers = [
|
|
121
|
+
{ name: "debug-world", order: 999999 },
|
|
122
|
+
{ name: "debug-hud", order: 999999 }
|
|
123
|
+
];
|
|
124
|
+
/** Called after `_mountDetached` has materialized the render tree. */
|
|
125
|
+
onReady;
|
|
126
|
+
/** Called by the plugin when the scene is unmounted. */
|
|
127
|
+
onTearDown;
|
|
128
|
+
onEnter() {
|
|
129
|
+
const tree = this._resolveScoped(SceneRenderTreeKey);
|
|
130
|
+
if (!tree) {
|
|
131
|
+
const logger = this.context.tryResolve(LoggerKey);
|
|
132
|
+
const msg = "DebugScene.onEnter: SceneRenderTreeKey missing \u2014 debug overlay will not render. Is RendererPlugin registered?";
|
|
133
|
+
if (logger) logger.warn("debug", msg);
|
|
134
|
+
else console.warn(`[yage] ${msg}`);
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
const worldContainer = tree.get("debug-world").container;
|
|
138
|
+
const hudContainer = tree.get("debug-hud").container;
|
|
139
|
+
worldContainer.eventMode = "none";
|
|
140
|
+
hudContainer.eventMode = "none";
|
|
141
|
+
this.onReady?.(worldContainer, hudContainer);
|
|
142
|
+
}
|
|
143
|
+
onExit() {
|
|
144
|
+
this.onTearDown?.();
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
|
|
104
148
|
// src/StatsStore.ts
|
|
105
149
|
var WINDOW_SIZE = 120;
|
|
106
150
|
var StatsStore = class {
|
|
@@ -337,7 +381,7 @@ var HudDebugApiImpl = class {
|
|
|
337
381
|
// src/DebugRenderSystem.ts
|
|
338
382
|
import { System, Phase } from "@yagejs/core";
|
|
339
383
|
var DebugRenderSystem = class extends System {
|
|
340
|
-
constructor(registry, graphicsPool, textPool, worldApi, hudApi, stats, worldContainer, hudContainer) {
|
|
384
|
+
constructor(registry, graphicsPool, textPool, worldApi, hudApi, stats, worldContainer, hudContainer, cameraAccessor) {
|
|
341
385
|
super();
|
|
342
386
|
this.registry = registry;
|
|
343
387
|
this.graphicsPool = graphicsPool;
|
|
@@ -347,6 +391,7 @@ var DebugRenderSystem = class extends System {
|
|
|
347
391
|
this.stats = stats;
|
|
348
392
|
this.worldContainer = worldContainer;
|
|
349
393
|
this.hudContainer = hudContainer;
|
|
394
|
+
this.cameraAccessor = cameraAccessor;
|
|
350
395
|
}
|
|
351
396
|
registry;
|
|
352
397
|
graphicsPool;
|
|
@@ -356,6 +401,7 @@ var DebugRenderSystem = class extends System {
|
|
|
356
401
|
stats;
|
|
357
402
|
worldContainer;
|
|
358
403
|
hudContainer;
|
|
404
|
+
cameraAccessor;
|
|
359
405
|
static {
|
|
360
406
|
__name(this, "DebugRenderSystem");
|
|
361
407
|
}
|
|
@@ -369,6 +415,7 @@ var DebugRenderSystem = class extends System {
|
|
|
369
415
|
}
|
|
370
416
|
this.worldContainer.visible = true;
|
|
371
417
|
this.hudContainer.visible = true;
|
|
418
|
+
this.syncWorldCamera();
|
|
372
419
|
this.graphicsPool.resetFrame();
|
|
373
420
|
this.textPool.resetFrame();
|
|
374
421
|
for (const [name, contributor] of this.registry.contributors) {
|
|
@@ -383,6 +430,22 @@ var DebugRenderSystem = class extends System {
|
|
|
383
430
|
}
|
|
384
431
|
}
|
|
385
432
|
}
|
|
433
|
+
syncWorldCamera() {
|
|
434
|
+
const cam = this.cameraAccessor.findCamera();
|
|
435
|
+
if (!cam) {
|
|
436
|
+
this.worldContainer.position.set(0, 0);
|
|
437
|
+
this.worldContainer.scale.set(1, 1);
|
|
438
|
+
this.worldContainer.rotation = 0;
|
|
439
|
+
return;
|
|
440
|
+
}
|
|
441
|
+
const vw = this.cameraAccessor.viewportWidth;
|
|
442
|
+
const vh = this.cameraAccessor.viewportHeight;
|
|
443
|
+
const rotatedPos = cam.effectivePosition.scale(cam.zoom).rotate(-cam.rotation);
|
|
444
|
+
this.worldContainer.position.x = vw / 2 - rotatedPos.x;
|
|
445
|
+
this.worldContainer.position.y = vh / 2 - rotatedPos.y;
|
|
446
|
+
this.worldContainer.scale.set(cam.zoom);
|
|
447
|
+
this.worldContainer.rotation = -cam.rotation;
|
|
448
|
+
}
|
|
386
449
|
};
|
|
387
450
|
|
|
388
451
|
// src/contributors/FpsContributor.ts
|
|
@@ -463,22 +526,26 @@ var DebugPlugin = class {
|
|
|
463
526
|
__name(this, "DebugPlugin");
|
|
464
527
|
}
|
|
465
528
|
name = "debug";
|
|
466
|
-
version = "
|
|
529
|
+
version = "3.0.0";
|
|
467
530
|
dependencies = ["renderer"];
|
|
468
531
|
config;
|
|
469
532
|
registry;
|
|
470
533
|
stats;
|
|
471
|
-
graphicsPool;
|
|
472
|
-
textPool;
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
hudApi;
|
|
534
|
+
graphicsPool = null;
|
|
535
|
+
textPool = null;
|
|
536
|
+
worldApi = null;
|
|
537
|
+
hudApi = null;
|
|
538
|
+
renderSystem = null;
|
|
477
539
|
systemTimings = /* @__PURE__ */ new Map();
|
|
478
540
|
originalUpdates = /* @__PURE__ */ new Map();
|
|
479
541
|
keyListener = null;
|
|
480
542
|
context;
|
|
481
543
|
renderer;
|
|
544
|
+
scheduler;
|
|
545
|
+
sceneManager;
|
|
546
|
+
debugScene = null;
|
|
547
|
+
provider = null;
|
|
548
|
+
eventUnsubs = [];
|
|
482
549
|
clock = null;
|
|
483
550
|
constructor(config) {
|
|
484
551
|
this.config = config ?? {};
|
|
@@ -486,19 +553,6 @@ var DebugPlugin = class {
|
|
|
486
553
|
install(context) {
|
|
487
554
|
this.context = context;
|
|
488
555
|
this.renderer = context.resolve(RendererKey);
|
|
489
|
-
const camera = context.resolve(CameraKey);
|
|
490
|
-
const worldLayers = context.resolve(RenderLayerManagerKey);
|
|
491
|
-
const debugLayer = worldLayers.getOrCreate("debug", 999999);
|
|
492
|
-
this.worldContainer = debugLayer.container;
|
|
493
|
-
this.worldContainer.eventMode = "none";
|
|
494
|
-
const hudLayers = this.renderer.createScreenContainer("debug-hud");
|
|
495
|
-
this.hudContainer = hudLayers.defaultLayer.container;
|
|
496
|
-
this.hudContainer.eventMode = "none";
|
|
497
|
-
this.graphicsPool = new GraphicsPool(
|
|
498
|
-
this.worldContainer,
|
|
499
|
-
this.config.maxGraphics
|
|
500
|
-
);
|
|
501
|
-
this.textPool = new TextPool(this.hudContainer, this.config.maxHudLines);
|
|
502
556
|
this.registry = new DebugRegistryImpl();
|
|
503
557
|
this.registry.enabled = this.config.startEnabled ?? false;
|
|
504
558
|
if (this.config.flags) {
|
|
@@ -510,34 +564,14 @@ var DebugPlugin = class {
|
|
|
510
564
|
}
|
|
511
565
|
}
|
|
512
566
|
this.stats = new StatsStore();
|
|
513
|
-
this.worldApi = new WorldDebugApiImpl(
|
|
514
|
-
this.graphicsPool,
|
|
515
|
-
this.registry,
|
|
516
|
-
camera
|
|
517
|
-
);
|
|
518
|
-
this.hudApi = new HudDebugApiImpl(
|
|
519
|
-
this.textPool,
|
|
520
|
-
this.registry,
|
|
521
|
-
camera.viewportWidth,
|
|
522
|
-
camera.viewportHeight
|
|
523
|
-
);
|
|
524
567
|
context.register(DebugRegistryKey, this.registry);
|
|
525
568
|
}
|
|
526
569
|
registerSystems(scheduler) {
|
|
527
|
-
scheduler
|
|
528
|
-
new DebugRenderSystem(
|
|
529
|
-
this.registry,
|
|
530
|
-
this.graphicsPool,
|
|
531
|
-
this.textPool,
|
|
532
|
-
this.worldApi,
|
|
533
|
-
this.hudApi,
|
|
534
|
-
this.stats,
|
|
535
|
-
this.worldContainer,
|
|
536
|
-
this.hudContainer
|
|
537
|
-
)
|
|
538
|
-
);
|
|
570
|
+
this.scheduler = scheduler;
|
|
539
571
|
}
|
|
540
|
-
onStart() {
|
|
572
|
+
async onStart() {
|
|
573
|
+
this.sceneManager = this.context.resolve(SceneManagerKey);
|
|
574
|
+
const bus = this.context.resolve(EventBusKey);
|
|
541
575
|
const toggleKey = this.config.toggleKey ?? "Backquote";
|
|
542
576
|
const stepKey = this.config.stepKey ?? "Period";
|
|
543
577
|
this.keyListener = (e) => {
|
|
@@ -553,8 +587,7 @@ var DebugPlugin = class {
|
|
|
553
587
|
if (typeof window !== "undefined") {
|
|
554
588
|
window.addEventListener("keydown", this.keyListener);
|
|
555
589
|
}
|
|
556
|
-
const
|
|
557
|
-
for (const system of scheduler.getAllSystems()) {
|
|
590
|
+
for (const system of this.scheduler.getAllSystems()) {
|
|
558
591
|
if (system instanceof DebugRenderSystem) continue;
|
|
559
592
|
const name = system.constructor.name;
|
|
560
593
|
const original = system.update.bind(system);
|
|
@@ -581,8 +614,21 @@ var DebugPlugin = class {
|
|
|
581
614
|
this.clock.setManual(true);
|
|
582
615
|
}
|
|
583
616
|
this.attachToGlobal(this.clock);
|
|
617
|
+
this.provider = this.context.tryResolve(SceneRenderTreeProviderKey) ?? null;
|
|
618
|
+
this.attachInspectorDiagnostics(inspector);
|
|
619
|
+
await this.materializeDebugScene();
|
|
620
|
+
const bringToFront = /* @__PURE__ */ __name(() => {
|
|
621
|
+
if (this.debugScene && this.provider?.bringSceneToFront) {
|
|
622
|
+
this.provider.bringSceneToFront(this.debugScene);
|
|
623
|
+
}
|
|
624
|
+
}, "bringToFront");
|
|
625
|
+
this.eventUnsubs.push(bus.on("scene:pushed", bringToFront));
|
|
626
|
+
this.eventUnsubs.push(bus.on("scene:popped", bringToFront));
|
|
627
|
+
this.eventUnsubs.push(bus.on("scene:replaced", bringToFront));
|
|
584
628
|
}
|
|
585
629
|
onDestroy() {
|
|
630
|
+
for (const unsub of this.eventUnsubs) unsub();
|
|
631
|
+
this.eventUnsubs.length = 0;
|
|
586
632
|
for (const [system, original] of this.originalUpdates) {
|
|
587
633
|
system.update = original;
|
|
588
634
|
}
|
|
@@ -599,9 +645,112 @@ var DebugPlugin = class {
|
|
|
599
645
|
contributor.dispose?.();
|
|
600
646
|
}
|
|
601
647
|
this.registry.contributors.clear();
|
|
602
|
-
this.
|
|
603
|
-
this.
|
|
604
|
-
|
|
648
|
+
this.tearDownDebugInfra();
|
|
649
|
+
this.teardownDebugScene();
|
|
650
|
+
}
|
|
651
|
+
async materializeDebugScene() {
|
|
652
|
+
const scene = new DebugScene();
|
|
653
|
+
scene.onReady = (worldContainer, hudContainer) => this.setUpDebugInfra(worldContainer, hudContainer);
|
|
654
|
+
scene.onTearDown = () => this.tearDownDebugInfra();
|
|
655
|
+
await this.sceneManager._mountDetached(scene);
|
|
656
|
+
this.debugScene = scene;
|
|
657
|
+
}
|
|
658
|
+
teardownDebugScene() {
|
|
659
|
+
if (!this.debugScene) return;
|
|
660
|
+
this.sceneManager._unmountDetached(this.debugScene);
|
|
661
|
+
this.debugScene = null;
|
|
662
|
+
this.provider = null;
|
|
663
|
+
}
|
|
664
|
+
findActiveCamera() {
|
|
665
|
+
return findTopmostCamera(this.sceneManager);
|
|
666
|
+
}
|
|
667
|
+
setUpDebugInfra(worldContainer, hudContainer) {
|
|
668
|
+
const vw = this.renderer.virtualSize.width;
|
|
669
|
+
const vh = this.renderer.virtualSize.height;
|
|
670
|
+
const self = this;
|
|
671
|
+
const cameraProxy = {
|
|
672
|
+
get zoom() {
|
|
673
|
+
return self.findActiveCamera()?.zoom ?? 1;
|
|
674
|
+
}
|
|
675
|
+
};
|
|
676
|
+
this.graphicsPool = new GraphicsPool(
|
|
677
|
+
worldContainer,
|
|
678
|
+
this.config.maxGraphics
|
|
679
|
+
);
|
|
680
|
+
this.textPool = new TextPool(hudContainer, this.config.maxHudLines);
|
|
681
|
+
this.worldApi = new WorldDebugApiImpl(
|
|
682
|
+
this.graphicsPool,
|
|
683
|
+
this.registry,
|
|
684
|
+
cameraProxy
|
|
685
|
+
);
|
|
686
|
+
this.hudApi = new HudDebugApiImpl(this.textPool, this.registry, vw, vh);
|
|
687
|
+
this.renderSystem = new DebugRenderSystem(
|
|
688
|
+
this.registry,
|
|
689
|
+
this.graphicsPool,
|
|
690
|
+
this.textPool,
|
|
691
|
+
this.worldApi,
|
|
692
|
+
this.hudApi,
|
|
693
|
+
this.stats,
|
|
694
|
+
worldContainer,
|
|
695
|
+
hudContainer,
|
|
696
|
+
{
|
|
697
|
+
findCamera: /* @__PURE__ */ __name(() => self.findActiveCamera(), "findCamera"),
|
|
698
|
+
viewportWidth: vw,
|
|
699
|
+
viewportHeight: vh
|
|
700
|
+
}
|
|
701
|
+
);
|
|
702
|
+
this.scheduler.add(this.renderSystem);
|
|
703
|
+
}
|
|
704
|
+
tearDownDebugInfra() {
|
|
705
|
+
if (this.renderSystem) {
|
|
706
|
+
this.scheduler.remove(this.renderSystem);
|
|
707
|
+
this.renderSystem = null;
|
|
708
|
+
}
|
|
709
|
+
this.graphicsPool?.destroy();
|
|
710
|
+
this.textPool?.destroy();
|
|
711
|
+
this.graphicsPool = null;
|
|
712
|
+
this.textPool = null;
|
|
713
|
+
this.worldApi = null;
|
|
714
|
+
this.hudApi = null;
|
|
715
|
+
}
|
|
716
|
+
attachInspectorDiagnostics(inspector) {
|
|
717
|
+
const g = globalThis["__yage__"];
|
|
718
|
+
if (!g || typeof g !== "object") return;
|
|
719
|
+
const debugSurface = g;
|
|
720
|
+
const diagnostics = inspector;
|
|
721
|
+
debugSurface["inspector"] = inspector;
|
|
722
|
+
diagnostics.getLayerTransform = (sceneName, layerName) => {
|
|
723
|
+
const scene = this.sceneManager.all.find(
|
|
724
|
+
(candidate) => candidate.name === sceneName
|
|
725
|
+
);
|
|
726
|
+
if (!scene) return void 0;
|
|
727
|
+
const layer = this.provider?.getTree(scene)?.tryGet(layerName);
|
|
728
|
+
if (!layer) return void 0;
|
|
729
|
+
const container = layer.container;
|
|
730
|
+
return {
|
|
731
|
+
x: container.position.x,
|
|
732
|
+
y: container.position.y,
|
|
733
|
+
scaleX: container.scale.x,
|
|
734
|
+
scaleY: container.scale.y,
|
|
735
|
+
rotation: container.rotation
|
|
736
|
+
};
|
|
737
|
+
};
|
|
738
|
+
diagnostics.getCameraStack = () => {
|
|
739
|
+
const cameras = [];
|
|
740
|
+
for (const scene of this.sceneManager.all) {
|
|
741
|
+
for (const entity of scene.getEntities()) {
|
|
742
|
+
const cam = entity.tryGet(CameraComponent);
|
|
743
|
+
if (!cam) continue;
|
|
744
|
+
cameras.push({
|
|
745
|
+
scene: scene.name,
|
|
746
|
+
name: cam.cameraName,
|
|
747
|
+
priority: cam.priority,
|
|
748
|
+
enabled: cam.enabled
|
|
749
|
+
});
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
return cameras;
|
|
753
|
+
};
|
|
605
754
|
}
|
|
606
755
|
attachToGlobal(clock) {
|
|
607
756
|
const g = globalThis["__yage__"];
|
|
@@ -616,6 +765,23 @@ var DebugPlugin = class {
|
|
|
616
765
|
}
|
|
617
766
|
}
|
|
618
767
|
};
|
|
768
|
+
function findTopmostCamera(sceneManager) {
|
|
769
|
+
const stack = sceneManager.all;
|
|
770
|
+
for (let i = stack.length - 1; i >= 0; i--) {
|
|
771
|
+
const scene = stack[i];
|
|
772
|
+
if (!scene) continue;
|
|
773
|
+
let highestPriorityCamera;
|
|
774
|
+
for (const entity of scene.getEntities()) {
|
|
775
|
+
const cam = entity.tryGet(CameraComponent);
|
|
776
|
+
if (cam && cam.enabled && (!highestPriorityCamera || cam.priority > highestPriorityCamera.priority)) {
|
|
777
|
+
highestPriorityCamera = cam;
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
if (highestPriorityCamera) return highestPriorityCamera;
|
|
781
|
+
}
|
|
782
|
+
return void 0;
|
|
783
|
+
}
|
|
784
|
+
__name(findTopmostCamera, "findTopmostCamera");
|
|
619
785
|
export {
|
|
620
786
|
DebugPlugin,
|
|
621
787
|
DebugRegistryImpl,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/DebugPlugin.ts","../src/DebugClock.ts","../src/DebugRegistryImpl.ts","../src/StatsStore.ts","../src/GraphicsPool.ts","../src/TextPool.ts","../src/WorldDebugApiImpl.ts","../src/HudDebugApiImpl.ts","../src/DebugRenderSystem.ts","../src/contributors/FpsContributor.ts","../src/contributors/EntityCountContributor.ts","../src/contributors/SystemTimingContributor.ts"],"sourcesContent":["import { SystemSchedulerKey, InspectorKey, GameLoopKey } from \"@yagejs/core\";\nimport type {\n EngineContext,\n Plugin,\n SystemScheduler,\n System,\n} from \"@yagejs/core\";\nimport { DebugRegistryKey } from \"./types.js\";\nimport { RendererKey, RenderLayerManagerKey, CameraKey } from \"@yagejs/renderer\";\nimport type { RendererPlugin } from \"@yagejs/renderer\";\nimport { Container } from \"pixi.js\";\nimport { DebugClock } from \"./DebugClock.js\";\nimport type { IDebugClock } from \"./DebugClock.js\";\nimport { DebugRegistryImpl } from \"./DebugRegistryImpl.js\";\nimport { StatsStore } from \"./StatsStore.js\";\nimport { GraphicsPool } from \"./GraphicsPool.js\";\nimport { TextPool } from \"./TextPool.js\";\nimport { WorldDebugApiImpl } from \"./WorldDebugApiImpl.js\";\nimport { HudDebugApiImpl } from \"./HudDebugApiImpl.js\";\nimport { DebugRenderSystem } from \"./DebugRenderSystem.js\";\nimport { FpsContributor } from \"./contributors/FpsContributor.js\";\nimport { EntityCountContributor } from \"./contributors/EntityCountContributor.js\";\nimport { SystemTimingContributor } from \"./contributors/SystemTimingContributor.js\";\n\n/** Configuration for the DebugPlugin. */\nexport interface DebugConfig {\n /** Key code to toggle debug overlay. Default: \"Backquote\" */\n toggleKey?: string;\n /** When true, stop the renderer ticker and advance simulation manually via `window.__yage__.clock`. */\n manualClock?: boolean;\n /** Key code to advance one fixed-timestep frame while manual clock mode is active. Default: \"Period\" */\n stepKey?: string;\n /** Max pooled Graphics objects. Default: 256 */\n maxGraphics?: number;\n /** Max HUD text lines. Default: 32 */\n maxHudLines?: number;\n /** Whether the overlay starts enabled. Default: false */\n startEnabled?: boolean;\n /** Initial flag overrides, keyed by \"contributorName.flagName\". */\n flags?: Record<string, boolean>;\n}\n\n/** Debug overlay plugin. Depends on the renderer plugin. */\nexport class DebugPlugin implements Plugin {\n readonly name = \"debug\";\n readonly version = \"2.0.0\";\n readonly dependencies = [\"renderer\"] as const;\n\n private readonly config: DebugConfig;\n private registry!: DebugRegistryImpl;\n private stats!: StatsStore;\n private graphicsPool!: GraphicsPool;\n private textPool!: TextPool;\n private worldContainer!: Container;\n private hudContainer!: Container;\n private worldApi!: WorldDebugApiImpl;\n private hudApi!: HudDebugApiImpl;\n private systemTimings = new Map<string, number>();\n private originalUpdates = new Map<System, (dt: number) => void>();\n private keyListener: ((e: KeyboardEvent) => void) | null = null;\n private context!: EngineContext;\n private renderer!: RendererPlugin;\n private clock: DebugClock | null = null;\n\n constructor(config?: DebugConfig) {\n this.config = config ?? {};\n }\n\n install(context: EngineContext): void {\n this.context = context;\n\n this.renderer = context.resolve(RendererKey);\n const camera = context.resolve(CameraKey);\n\n // World-space debug layer (child of world container, drawn on top)\n const worldLayers = context.resolve(RenderLayerManagerKey);\n const debugLayer = worldLayers.getOrCreate(\"debug\", 999999);\n this.worldContainer = debugLayer.container;\n this.worldContainer.eventMode = \"none\";\n\n // Screen-space HUD container (sibling of world container, unaffected by camera)\n const hudLayers = this.renderer.createScreenContainer(\"debug-hud\");\n this.hudContainer = hudLayers.defaultLayer.container;\n this.hudContainer.eventMode = \"none\";\n\n this.graphicsPool = new GraphicsPool(\n this.worldContainer,\n this.config.maxGraphics,\n );\n this.textPool = new TextPool(this.hudContainer, this.config.maxHudLines);\n\n this.registry = new DebugRegistryImpl();\n this.registry.enabled = this.config.startEnabled ?? false;\n\n if (this.config.flags) {\n for (const [key, value] of Object.entries(this.config.flags)) {\n const dot = key.indexOf(\".\");\n if (dot > 0) {\n this.registry.setFlag(key.slice(0, dot), key.slice(dot + 1), value);\n }\n }\n }\n\n this.stats = new StatsStore();\n\n this.worldApi = new WorldDebugApiImpl(\n this.graphicsPool,\n this.registry,\n camera,\n );\n this.hudApi = new HudDebugApiImpl(\n this.textPool,\n this.registry,\n camera.viewportWidth,\n camera.viewportHeight,\n );\n\n context.register(DebugRegistryKey, this.registry);\n }\n\n registerSystems(scheduler: SystemScheduler): void {\n scheduler.add(\n new DebugRenderSystem(\n this.registry,\n this.graphicsPool,\n this.textPool,\n this.worldApi,\n this.hudApi,\n this.stats,\n this.worldContainer,\n this.hudContainer,\n ),\n );\n }\n\n onStart(): void {\n // Toggle / step key listener\n const toggleKey = this.config.toggleKey ?? \"Backquote\";\n const stepKey = this.config.stepKey ?? \"Period\";\n this.keyListener = (e: KeyboardEvent) => {\n if (e.code === toggleKey) {\n this.registry.toggle();\n return;\n }\n if (e.code === stepKey && this.clock?.isManual) {\n e.preventDefault();\n this.clock.step();\n }\n };\n if (typeof window !== \"undefined\") {\n window.addEventListener(\"keydown\", this.keyListener);\n }\n\n // Instrument system timings\n const scheduler = this.context.resolve(SystemSchedulerKey);\n for (const system of scheduler.getAllSystems()) {\n if (system instanceof DebugRenderSystem) continue;\n const name = system.constructor.name;\n const original = system.update.bind(system);\n this.originalUpdates.set(system, original);\n system.update = (dt: number) => {\n const t0 = performance.now();\n original(dt);\n this.systemTimings.set(name, performance.now() - t0);\n };\n }\n\n // Built-in contributors\n const inspector = this.context.resolve(InspectorKey);\n this.registry.register(new FpsContributor());\n this.registry.register(new EntityCountContributor(inspector));\n this.registry.register(new SystemTimingContributor(this.systemTimings));\n\n // Manual clock for deterministic stepping\n const gameLoop = this.context.resolve(GameLoopKey);\n const app = this.renderer.application;\n\n this.clock = new DebugClock(\n gameLoop,\n () => app.stop(),\n () => app.start(),\n () => app.render(),\n );\n\n if (this.config.manualClock) {\n this.clock.setManual(true);\n }\n\n this.attachToGlobal(this.clock);\n }\n\n onDestroy(): void {\n // Restore original system.update methods\n for (const [system, original] of this.originalUpdates) {\n system.update = original;\n }\n this.originalUpdates.clear();\n\n if (this.keyListener) {\n if (typeof window !== \"undefined\") {\n window.removeEventListener(\"keydown\", this.keyListener);\n }\n this.keyListener = null;\n }\n\n this.detachFromGlobal();\n this.clock = null;\n\n for (const contributor of this.registry.contributors.values()) {\n contributor.dispose?.();\n }\n this.registry.contributors.clear();\n\n this.graphicsPool.destroy();\n this.textPool.destroy();\n // worldContainer is owned by the world RenderLayerManager — don't destroy it\n this.renderer.destroyScreenContainer(\"debug-hud\");\n }\n\n private attachToGlobal(clock: IDebugClock): void {\n const g = (globalThis as Record<string, unknown>)[\"__yage__\"];\n if (g && typeof g === \"object\") {\n (g as Record<string, unknown>)[\"clock\"] = clock;\n }\n }\n\n private detachFromGlobal(): void {\n const g = (globalThis as Record<string, unknown>)[\"__yage__\"];\n if (\n g &&\n typeof g === \"object\" &&\n (g as Record<string, unknown>)[\"clock\"] === this.clock\n ) {\n delete (g as Record<string, unknown>)[\"clock\"];\n }\n }\n}\n","/** Public interface for the manual debug clock, accessible via `window.__yage__.clock`. */\nexport interface IDebugClock {\n readonly isManual: boolean;\n startAuto(): void;\n stopAuto(): void;\n step(dtMs?: number): void;\n stepFrames(count: number, dtMs?: number): void;\n}\n\n/** Minimal view of a game loop needed by the debug clock. */\ninterface GameLoopLike {\n tick(dtMs: number): void;\n readonly fixedTimestep: number;\n}\n\n/**\n * Controls engine time-stepping for deterministic E2E tests.\n *\n * When manual mode is active the renderer ticker is paused and frames\n * advance only via explicit `step()` / `stepFrames()` calls.\n */\nexport class DebugClock implements IDebugClock {\n private _isManual = false;\n\n constructor(\n private readonly gameLoop: GameLoopLike,\n private readonly stopTicker: () => void,\n private readonly startTicker: () => void,\n private readonly render: () => void,\n ) {}\n\n get isManual(): boolean {\n return this._isManual;\n }\n\n startAuto(): void {\n if (!this._isManual) return;\n this.startTicker();\n this._isManual = false;\n }\n\n stopAuto(): void {\n if (this._isManual) return;\n this.stopTicker();\n this._isManual = true;\n }\n\n step(dtMs?: number): void {\n if (!this._isManual) {\n throw new Error(\n \"Manual clock is not active. Call clock.stopAuto() first.\",\n );\n }\n const dt = dtMs ?? this.gameLoop.fixedTimestep;\n this.gameLoop.tick(dt);\n this.render();\n }\n\n stepFrames(count: number, dtMs?: number): void {\n if (!Number.isInteger(count) || count < 0) {\n throw new Error(\n \"stepFrames(count) requires a non-negative integer count.\",\n );\n }\n for (let i = 0; i < count; i++) {\n this.step(dtMs);\n }\n }\n\n /** Enter or exit manual mode. Used by DebugPlugin for config-driven init. */\n setManual(enabled: boolean): void {\n if (enabled === this._isManual) return;\n if (enabled) {\n this.stopTicker();\n } else {\n this.startTicker();\n }\n this._isManual = enabled;\n }\n}\n","import type { DebugContributor, DebugRegistry } from \"./types.js\";\n\n/** Concrete implementation of the DebugRegistry interface. */\nexport class DebugRegistryImpl implements DebugRegistry {\n readonly contributors = new Map<string, DebugContributor>();\n enabled = false;\n private flags = new Map<string, boolean>();\n\n register(contributor: DebugContributor): void {\n if (this.contributors.has(contributor.name)) return;\n this.contributors.set(contributor.name, contributor);\n for (const flag of contributor.flags) {\n this.flags.set(`${contributor.name}.${flag}`, true);\n }\n }\n\n isEnabled(): boolean {\n return this.enabled;\n }\n\n isFlagEnabled(contributorName: string, flag: string): boolean {\n return this.flags.get(`${contributorName}.${flag}`) ?? true;\n }\n\n toggle(): void {\n this.enabled = !this.enabled;\n }\n\n toggleFlag(contributorName: string, flag: string): void {\n const key = `${contributorName}.${flag}`;\n this.flags.set(key, !(this.flags.get(key) ?? true));\n }\n\n setFlag(contributorName: string, flag: string, value: boolean): void {\n this.flags.set(`${contributorName}.${flag}`, value);\n }\n}\n","import type { StatsApi } from \"./types.js\";\n\nconst WINDOW_SIZE = 120;\n\ninterface RingBuffer {\n data: Float64Array;\n count: number;\n index: number;\n}\n\n/** Rolling-window statistics store backed by Float64Array ring buffers. */\nexport class StatsStore implements StatsApi {\n private rings = new Map<string, RingBuffer>();\n\n push(key: string, value: number): void {\n let ring = this.rings.get(key);\n if (!ring) {\n ring = { data: new Float64Array(WINDOW_SIZE), count: 0, index: 0 };\n this.rings.set(key, ring);\n }\n ring.data[ring.index] = value;\n ring.index = (ring.index + 1) % WINDOW_SIZE;\n if (ring.count < WINDOW_SIZE) ring.count++;\n }\n\n average(key: string): number {\n const ring = this.rings.get(key);\n if (!ring || ring.count === 0) return 0;\n const { data, count } = ring;\n let sum = 0;\n for (let i = 0; i < count; i++) sum += data[i] ?? 0;\n return sum / count;\n }\n\n latest(key: string): number {\n const ring = this.rings.get(key);\n if (!ring || ring.count === 0) return 0;\n return ring.data[(ring.index - 1 + WINDOW_SIZE) % WINDOW_SIZE] ?? 0;\n }\n\n min(key: string): number {\n const ring = this.rings.get(key);\n if (!ring || ring.count === 0) return 0;\n const { data, count } = ring;\n let m = Infinity;\n for (let i = 0; i < count; i++) {\n const v = data[i] ?? 0;\n if (v < m) m = v;\n }\n return m;\n }\n\n max(key: string): number {\n const ring = this.rings.get(key);\n if (!ring || ring.count === 0) return 0;\n const { data, count } = ring;\n let m = -Infinity;\n for (let i = 0; i < count; i++) {\n const v = data[i] ?? 0;\n if (v > m) m = v;\n }\n return m;\n }\n}\n","import { Graphics, Container } from \"pixi.js\";\n\n/** Allocation-free pool of PixiJS Graphics objects for debug drawing. */\nexport class GraphicsPool {\n private pool: Graphics[] | null = null;\n private index = 0;\n private readonly container: Container;\n private readonly maxSize: number;\n\n constructor(container: Container, maxSize = 256) {\n this.container = container;\n this.maxSize = maxSize;\n }\n\n /** Lazily create Graphics objects on first use (ensures PixiJS is fully ready). */\n private ensure(): Graphics[] {\n if (this.pool) return this.pool;\n this.pool = [];\n for (let i = 0; i < this.maxSize; i++) {\n const g = new Graphics();\n g.visible = false;\n g.eventMode = \"none\";\n this.container.addChild(g);\n this.pool.push(g);\n }\n return this.pool;\n }\n\n /** Return the next available Graphics, or undefined if the pool is exhausted. */\n acquire(): Graphics | undefined {\n const pool = this.ensure();\n if (this.index >= pool.length) return undefined;\n const g = pool[this.index]!;\n g.visible = true;\n this.index++;\n return g;\n }\n\n /** Clear and hide all previously acquired graphics, reset index. */\n resetFrame(): void {\n if (!this.pool) return;\n for (let i = 0; i < this.index; i++) {\n const g = this.pool[i]!;\n g.clear();\n g.visible = false;\n g.position.set(0, 0);\n g.rotation = 0;\n g.scale.set(1, 1);\n }\n this.index = 0;\n }\n\n destroy(): void {\n if (!this.pool) return;\n for (const g of this.pool) {\n g.destroy();\n }\n this.pool.length = 0;\n }\n}\n","import { Text, Container } from \"pixi.js\";\n\nconst LINE_HEIGHT = 16;\nconst FONT_SIZE = 14;\nconst PADDING = 4;\n\n/** Allocation-free pool of PixiJS Text objects for HUD debug lines. */\nexport class TextPool {\n private pool: Text[] | null = null;\n private index = 0;\n private readonly container: Container;\n private readonly maxLines: number;\n\n constructor(container: Container, maxLines = 32) {\n this.container = container;\n this.maxLines = maxLines;\n }\n\n /** Lazily create Text objects on first use (ensures PixiJS is fully ready). */\n private ensure(): Text[] {\n if (this.pool) return this.pool;\n this.pool = [];\n for (let i = 0; i < this.maxLines; i++) {\n const t = new Text({\n text: \"\",\n style: {\n fontFamily: \"monospace\",\n fontSize: FONT_SIZE,\n fill: 0xffffff,\n },\n });\n t.visible = false;\n t.eventMode = \"none\";\n this.container.addChild(t);\n this.pool.push(t);\n }\n return this.pool;\n }\n\n /** Show a text line at the next available slot. */\n addLine(text: string): void {\n const pool = this.ensure();\n if (this.index >= pool.length) return;\n const t = pool[this.index]!;\n t.text = text;\n t.visible = true;\n t.position.set(PADDING, PADDING + this.index * LINE_HEIGHT);\n this.index++;\n }\n\n /** Hide all lines and reset for the next frame. */\n resetFrame(): void {\n if (!this.pool) return;\n for (let i = 0; i < this.index; i++) {\n this.pool[i]!.visible = false;\n }\n this.index = 0;\n }\n\n destroy(): void {\n if (!this.pool) return;\n for (const t of this.pool) {\n t.destroy();\n }\n this.pool.length = 0;\n }\n}\n","import type { WorldDebugApi, DebugGraphics } from \"./types.js\";\nimport type { GraphicsPool } from \"./GraphicsPool.js\";\nimport type { DebugRegistryImpl } from \"./DebugRegistryImpl.js\";\n\n/** WorldDebugApi backed by a GraphicsPool. Contributor name is swapped per iteration. */\nexport class WorldDebugApiImpl implements WorldDebugApi {\n private _contributorName = \"\";\n\n constructor(\n private readonly pool: GraphicsPool,\n private readonly registry: DebugRegistryImpl,\n private readonly _camera: { zoom: number },\n ) {}\n\n /** Set the current contributor name (called before each contributor's drawWorld). */\n setContributor(name: string): void {\n this._contributorName = name;\n }\n\n acquireGraphics(): DebugGraphics | undefined {\n return this.pool.acquire() as unknown as DebugGraphics | undefined;\n }\n\n isFlagEnabled(flag: string): boolean {\n return this.registry.isFlagEnabled(this._contributorName, flag);\n }\n\n get cameraZoom(): number {\n return this._camera.zoom;\n }\n}\n","import type { HudDebugApi } from \"./types.js\";\nimport type { TextPool } from \"./TextPool.js\";\nimport type { DebugRegistryImpl } from \"./DebugRegistryImpl.js\";\n\n/** HudDebugApi backed by a TextPool. Contributor name is swapped per iteration. */\nexport class HudDebugApiImpl implements HudDebugApi {\n private _contributorName = \"\";\n\n constructor(\n private readonly textPool: TextPool,\n private readonly registry: DebugRegistryImpl,\n public readonly screenWidth: number,\n public readonly screenHeight: number,\n ) {}\n\n /** Set the current contributor name (called before each contributor's drawHud). */\n setContributor(name: string): void {\n this._contributorName = name;\n }\n\n addLine(text: string): void {\n this.textPool.addLine(text);\n }\n\n isFlagEnabled(flag: string): boolean {\n return this.registry.isFlagEnabled(this._contributorName, flag);\n }\n}\n","import { System, Phase } from \"@yagejs/core\";\nimport type { Container } from \"pixi.js\";\nimport type { DebugRegistryImpl } from \"./DebugRegistryImpl.js\";\nimport type { GraphicsPool } from \"./GraphicsPool.js\";\nimport type { TextPool } from \"./TextPool.js\";\nimport type { WorldDebugApiImpl } from \"./WorldDebugApiImpl.js\";\nimport type { HudDebugApiImpl } from \"./HudDebugApiImpl.js\";\nimport type { StatsStore } from \"./StatsStore.js\";\n\n/** Renders all debug contributors. Runs after DisplaySystem in the Render phase. */\nexport class DebugRenderSystem extends System {\n readonly phase = Phase.Render;\n readonly priority = 9999;\n\n constructor(\n private readonly registry: DebugRegistryImpl,\n private readonly graphicsPool: GraphicsPool,\n private readonly textPool: TextPool,\n private readonly worldApi: WorldDebugApiImpl,\n private readonly hudApi: HudDebugApiImpl,\n private readonly stats: StatsStore,\n private readonly worldContainer: Container,\n private readonly hudContainer: Container,\n ) {\n super();\n }\n\n update(dt: number): void {\n if (!this.registry.enabled) {\n this.worldContainer.visible = false;\n this.hudContainer.visible = false;\n return;\n }\n\n this.worldContainer.visible = true;\n this.hudContainer.visible = true;\n this.graphicsPool.resetFrame();\n this.textPool.resetFrame();\n\n for (const [name, contributor] of this.registry.contributors) {\n contributor.sample?.(this.stats, dt);\n\n if (contributor.drawWorld) {\n this.worldApi.setContributor(name);\n contributor.drawWorld(this.worldApi);\n }\n\n if (contributor.drawHud) {\n this.hudApi.setContributor(name);\n contributor.drawHud(this.hudApi);\n }\n }\n }\n}\n","import type { DebugContributor, StatsApi, HudDebugApi } from \"../types.js\";\n\nexport class FpsContributor implements DebugContributor {\n readonly name = \"fps\";\n readonly flags: readonly string[] = [];\n private stats: StatsApi | null = null;\n\n sample(stats: StatsApi, dt: number): void {\n this.stats = stats;\n if (dt > 0) stats.push(\"fps\", 1000 / dt);\n }\n\n drawHud(api: HudDebugApi): void {\n const avg = this.stats?.average(\"fps\") ?? 0;\n api.addLine(`FPS: ${Math.round(avg)}`);\n }\n}\n","import type { DebugContributor, HudDebugApi } from \"../types.js\";\nimport type { Inspector } from \"@yagejs/core\";\n\nexport class EntityCountContributor implements DebugContributor {\n readonly name = \"entities\";\n readonly flags: readonly string[] = [];\n\n constructor(private readonly inspector: Inspector) {}\n\n drawHud(api: HudDebugApi): void {\n const count = this.inspector.snapshot().entityCount;\n api.addLine(`Entities: ${count}`);\n }\n}\n","import type { DebugContributor, StatsApi, HudDebugApi } from \"../types.js\";\n\nexport class SystemTimingContributor implements DebugContributor {\n readonly name = \"timing\";\n readonly flags = [\"breakdown\"] as const;\n private stats: StatsApi | null = null;\n\n constructor(private readonly timings: Map<string, number>) {}\n\n sample(stats: StatsApi): void {\n this.stats = stats;\n for (const [name, ms] of this.timings) {\n stats.push(`system.${name}`, ms);\n }\n }\n\n drawHud(api: HudDebugApi): void {\n if (!this.stats) return;\n\n let total = 0;\n const entries: Array<[string, number]> = [];\n for (const name of this.timings.keys()) {\n const avg = this.stats.average(`system.${name}`);\n total += avg;\n entries.push([name, avg]);\n }\n\n api.addLine(`Systems: ${total.toFixed(2)}ms`);\n\n if (api.isFlagEnabled(\"breakdown\")) {\n entries.sort((a, b) => b[1] - a[1]);\n for (const [name, avg] of entries) {\n api.addLine(` ${name}: ${avg.toFixed(2)}ms`);\n }\n }\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/DebugPlugin.ts","../src/DebugClock.ts","../src/DebugRegistryImpl.ts","../src/DebugScene.ts","../src/StatsStore.ts","../src/GraphicsPool.ts","../src/TextPool.ts","../src/WorldDebugApiImpl.ts","../src/HudDebugApiImpl.ts","../src/DebugRenderSystem.ts","../src/contributors/FpsContributor.ts","../src/contributors/EntityCountContributor.ts","../src/contributors/SystemTimingContributor.ts"],"sourcesContent":["import {\n EventBusKey,\n GameLoopKey,\n InspectorKey,\n SceneManagerKey,\n} from \"@yagejs/core\";\nimport type {\n EngineContext,\n EventBus,\n EngineEvents,\n Inspector,\n Plugin,\n SceneManager,\n System,\n SystemScheduler,\n} from \"@yagejs/core\";\nimport { DebugRegistryKey } from \"./types.js\";\nimport { CameraComponent, RendererKey } from \"@yagejs/renderer\";\nimport type { RendererPlugin, SceneRenderTreeProvider } from \"@yagejs/renderer\";\nimport { SceneRenderTreeProviderKey } from \"@yagejs/renderer\";\nimport type { Container } from \"pixi.js\";\nimport { DebugClock } from \"./DebugClock.js\";\nimport type { IDebugClock } from \"./DebugClock.js\";\nimport { DebugRegistryImpl } from \"./DebugRegistryImpl.js\";\nimport { DebugScene } from \"./DebugScene.js\";\nimport { StatsStore } from \"./StatsStore.js\";\nimport { GraphicsPool } from \"./GraphicsPool.js\";\nimport { TextPool } from \"./TextPool.js\";\nimport { WorldDebugApiImpl } from \"./WorldDebugApiImpl.js\";\nimport { HudDebugApiImpl } from \"./HudDebugApiImpl.js\";\nimport { DebugRenderSystem } from \"./DebugRenderSystem.js\";\nimport { FpsContributor } from \"./contributors/FpsContributor.js\";\nimport { EntityCountContributor } from \"./contributors/EntityCountContributor.js\";\nimport { SystemTimingContributor } from \"./contributors/SystemTimingContributor.js\";\n\n/** Configuration for the DebugPlugin. */\nexport interface DebugConfig {\n /** Key code to toggle debug overlay. Default: \"Backquote\" */\n toggleKey?: string;\n /** When true, stop the renderer ticker and advance simulation manually via `window.__yage__.clock`. */\n manualClock?: boolean;\n /** Key code to advance one fixed-timestep frame while manual clock mode is active. Default: \"Period\" */\n stepKey?: string;\n /** Max pooled Graphics objects. Default: 256 */\n maxGraphics?: number;\n /** Max HUD text lines. Default: 32 */\n maxHudLines?: number;\n /** Whether the overlay starts enabled. Default: false */\n startEnabled?: boolean;\n /** Initial flag overrides, keyed by \"contributorName.flagName\". */\n flags?: Record<string, boolean>;\n}\n\ninterface LayerTransformSnapshot {\n x: number;\n y: number;\n scaleX: number;\n scaleY: number;\n rotation: number;\n}\n\ninterface CameraStackSnapshot {\n scene: string;\n name: string | undefined;\n priority: number;\n enabled: boolean;\n}\n\ninterface InspectorDiagnostics {\n getLayerTransform(\n sceneName: string,\n layerName: string,\n ): LayerTransformSnapshot | undefined;\n getCameraStack(): CameraStackSnapshot[];\n}\n\n/**\n * Debug overlay plugin. Mounts a private `DebugScene` through\n * `SceneManager._mountDetached` so it goes through the same scoped-DI\n * lifecycle as stacked scenes (the renderer's `beforeEnter` hook creates\n * its render tree) while staying off the user-visible scene stack.\n */\nexport class DebugPlugin implements Plugin {\n readonly name = \"debug\";\n readonly version = \"3.0.0\";\n readonly dependencies = [\"renderer\"] as const;\n\n private readonly config: DebugConfig;\n private registry!: DebugRegistryImpl;\n private stats!: StatsStore;\n private graphicsPool: GraphicsPool | null = null;\n private textPool: TextPool | null = null;\n private worldApi: WorldDebugApiImpl | null = null;\n private hudApi: HudDebugApiImpl | null = null;\n private renderSystem: DebugRenderSystem | null = null;\n private systemTimings = new Map<string, number>();\n private originalUpdates = new Map<System, (dt: number) => void>();\n private keyListener: ((e: KeyboardEvent) => void) | null = null;\n private context!: EngineContext;\n private renderer!: RendererPlugin;\n private scheduler!: SystemScheduler;\n private sceneManager!: SceneManager;\n private debugScene: DebugScene | null = null;\n private provider: SceneRenderTreeProvider | null = null;\n private eventUnsubs: Array<() => void> = [];\n private clock: DebugClock | null = null;\n\n constructor(config?: DebugConfig) {\n this.config = config ?? {};\n }\n\n install(context: EngineContext): void {\n this.context = context;\n this.renderer = context.resolve(RendererKey);\n\n this.registry = new DebugRegistryImpl();\n this.registry.enabled = this.config.startEnabled ?? false;\n\n if (this.config.flags) {\n for (const [key, value] of Object.entries(this.config.flags)) {\n const dot = key.indexOf(\".\");\n if (dot > 0) {\n this.registry.setFlag(key.slice(0, dot), key.slice(dot + 1), value);\n }\n }\n }\n\n this.stats = new StatsStore();\n\n context.register(DebugRegistryKey, this.registry);\n }\n\n registerSystems(scheduler: SystemScheduler): void {\n // DebugRenderSystem is registered lazily once the debug scene is ready —\n // its constructor needs the scene's layer containers.\n this.scheduler = scheduler;\n }\n\n async onStart(): Promise<void> {\n this.sceneManager = this.context.resolve(SceneManagerKey);\n const bus = this.context.resolve(EventBusKey) as EventBus<EngineEvents>;\n\n // Key listeners (toggle, manual-clock step)\n const toggleKey = this.config.toggleKey ?? \"Backquote\";\n const stepKey = this.config.stepKey ?? \"Period\";\n this.keyListener = (e: KeyboardEvent) => {\n if (e.code === toggleKey) {\n this.registry.toggle();\n return;\n }\n if (e.code === stepKey && this.clock?.isManual) {\n e.preventDefault();\n this.clock.step();\n }\n };\n if (typeof window !== \"undefined\") {\n window.addEventListener(\"keydown\", this.keyListener);\n }\n\n // Instrument system timings — reuse the scheduler captured in\n // `registerSystems`, which ran before `onStart`.\n for (const system of this.scheduler.getAllSystems()) {\n if (system instanceof DebugRenderSystem) continue;\n const name = system.constructor.name;\n const original = system.update.bind(system);\n this.originalUpdates.set(system, original);\n system.update = (dt: number) => {\n const t0 = performance.now();\n original(dt);\n this.systemTimings.set(name, performance.now() - t0);\n };\n }\n\n // Built-in contributors\n const inspector = this.context.resolve(InspectorKey);\n this.registry.register(new FpsContributor());\n this.registry.register(new EntityCountContributor(inspector));\n this.registry.register(new SystemTimingContributor(this.systemTimings));\n\n // Manual clock for deterministic stepping\n const gameLoop = this.context.resolve(GameLoopKey);\n const app = this.renderer.application;\n this.clock = new DebugClock(\n gameLoop,\n () => app.stop(),\n () => app.start(),\n () => app.render(),\n );\n if (this.config.manualClock) {\n this.clock.setManual(true);\n }\n this.attachToGlobal(this.clock);\n\n // Materialize the debug scene off-stack. `_mountDetached` routes through\n // the same beforeEnter hooks as `push`, so the renderer materializes the\n // debug scene's tree and registers SceneRenderTreeKey on its scope.\n this.provider = this.context.tryResolve(SceneRenderTreeProviderKey) ?? null;\n this.attachInspectorDiagnostics(inspector);\n await this.materializeDebugScene();\n\n // Keep the debug scene visually on top of the user stack after any\n // push/pop/replace by reordering its root containers.\n const bringToFront = () => {\n if (this.debugScene && this.provider?.bringSceneToFront) {\n this.provider.bringSceneToFront(this.debugScene);\n }\n };\n this.eventUnsubs.push(bus.on(\"scene:pushed\", bringToFront));\n this.eventUnsubs.push(bus.on(\"scene:popped\", bringToFront));\n this.eventUnsubs.push(bus.on(\"scene:replaced\", bringToFront));\n }\n\n onDestroy(): void {\n for (const unsub of this.eventUnsubs) unsub();\n this.eventUnsubs.length = 0;\n\n for (const [system, original] of this.originalUpdates) {\n system.update = original;\n }\n this.originalUpdates.clear();\n\n if (this.keyListener) {\n if (typeof window !== \"undefined\") {\n window.removeEventListener(\"keydown\", this.keyListener);\n }\n this.keyListener = null;\n }\n\n this.detachFromGlobal();\n this.clock = null;\n\n for (const contributor of this.registry.contributors.values()) {\n contributor.dispose?.();\n }\n this.registry.contributors.clear();\n\n this.tearDownDebugInfra();\n this.teardownDebugScene();\n }\n\n private async materializeDebugScene(): Promise<void> {\n const scene = new DebugScene();\n scene.onReady = (worldContainer, hudContainer) =>\n this.setUpDebugInfra(worldContainer, hudContainer);\n scene.onTearDown = () => this.tearDownDebugInfra();\n await this.sceneManager._mountDetached(scene);\n this.debugScene = scene;\n }\n\n private teardownDebugScene(): void {\n // If destroy is called while `_mountDetached` is still pending, we don't\n // yet hold a reference to the partially-mounted scene. Skipping unmount\n // here is safe: onDestroy still runs `tearDownDebugInfra` below, and the\n // engine teardown tears down the renderer next which destroys any\n // half-created provider entries.\n if (!this.debugScene) return;\n this.sceneManager._unmountDetached(this.debugScene);\n this.debugScene = null;\n this.provider = null;\n }\n\n private findActiveCamera(): CameraComponent | undefined {\n return findTopmostCamera(this.sceneManager);\n }\n\n private setUpDebugInfra(\n worldContainer: Container,\n hudContainer: Container,\n ): void {\n const vw = this.renderer.virtualSize.width;\n const vh = this.renderer.virtualSize.height;\n\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const self = this;\n // Lazy camera accessor — reads from whichever stacked scene has a camera\n const cameraProxy = {\n get zoom() {\n return self.findActiveCamera()?.zoom ?? 1;\n },\n };\n\n this.graphicsPool = new GraphicsPool(\n worldContainer,\n this.config.maxGraphics,\n );\n this.textPool = new TextPool(hudContainer, this.config.maxHudLines);\n\n this.worldApi = new WorldDebugApiImpl(\n this.graphicsPool,\n this.registry,\n cameraProxy,\n );\n this.hudApi = new HudDebugApiImpl(this.textPool, this.registry, vw, vh);\n\n this.renderSystem = new DebugRenderSystem(\n this.registry,\n this.graphicsPool,\n this.textPool,\n this.worldApi,\n this.hudApi,\n this.stats,\n worldContainer,\n hudContainer,\n {\n findCamera: () => self.findActiveCamera(),\n viewportWidth: vw,\n viewportHeight: vh,\n },\n );\n this.scheduler.add(this.renderSystem);\n }\n\n private tearDownDebugInfra(): void {\n if (this.renderSystem) {\n this.scheduler.remove(this.renderSystem);\n this.renderSystem = null;\n }\n this.graphicsPool?.destroy();\n this.textPool?.destroy();\n this.graphicsPool = null;\n this.textPool = null;\n this.worldApi = null;\n this.hudApi = null;\n }\n\n private attachInspectorDiagnostics(inspector: Inspector): void {\n const g = (globalThis as Record<string, unknown>)[\"__yage__\"];\n if (!g || typeof g !== \"object\") return;\n\n const debugSurface = g as Record<string, unknown>;\n const diagnostics = inspector as Inspector & InspectorDiagnostics;\n debugSurface[\"inspector\"] = inspector;\n\n diagnostics.getLayerTransform = (sceneName, layerName) => {\n const scene = this.sceneManager.all.find(\n (candidate) => candidate.name === sceneName,\n );\n if (!scene) return undefined;\n\n const layer = this.provider?.getTree(scene)?.tryGet(layerName);\n if (!layer) return undefined;\n\n const container = layer.container;\n return {\n x: container.position.x,\n y: container.position.y,\n scaleX: container.scale.x,\n scaleY: container.scale.y,\n rotation: container.rotation,\n };\n };\n\n diagnostics.getCameraStack = () => {\n const cameras: CameraStackSnapshot[] = [];\n for (const scene of this.sceneManager.all) {\n for (const entity of scene.getEntities()) {\n const cam = entity.tryGet(CameraComponent);\n if (!cam) continue;\n cameras.push({\n scene: scene.name,\n name: cam.cameraName,\n priority: cam.priority,\n enabled: cam.enabled,\n });\n }\n }\n return cameras;\n };\n }\n\n private attachToGlobal(clock: IDebugClock): void {\n const g = (globalThis as Record<string, unknown>)[\"__yage__\"];\n if (g && typeof g === \"object\") {\n (g as Record<string, unknown>)[\"clock\"] = clock;\n }\n }\n\n private detachFromGlobal(): void {\n const g = (globalThis as Record<string, unknown>)[\"__yage__\"];\n if (\n g &&\n typeof g === \"object\" &&\n (g as Record<string, unknown>)[\"clock\"] === this.clock\n ) {\n delete (g as Record<string, unknown>)[\"clock\"];\n }\n }\n}\n\n/**\n * Find the highest-priority enabled camera on the topmost scene that has one.\n * `sceneManager.all` is bottom→top, so we walk in reverse — a pause/HUD\n * scene's camera wins over a frozen scene beneath it.\n */\nexport function findTopmostCamera(\n sceneManager: SceneManager,\n): CameraComponent | undefined {\n const stack = sceneManager.all;\n for (let i = stack.length - 1; i >= 0; i--) {\n const scene = stack[i];\n if (!scene) continue;\n let highestPriorityCamera: CameraComponent | undefined;\n for (const entity of scene.getEntities()) {\n const cam = entity.tryGet(CameraComponent);\n if (\n cam &&\n cam.enabled &&\n (!highestPriorityCamera ||\n cam.priority > highestPriorityCamera.priority)\n ) {\n highestPriorityCamera = cam;\n }\n }\n if (highestPriorityCamera) return highestPriorityCamera;\n }\n return undefined;\n}\n","/** Public interface for the manual debug clock, accessible via `window.__yage__.clock`. */\nexport interface IDebugClock {\n readonly isManual: boolean;\n startAuto(): void;\n stopAuto(): void;\n step(dtMs?: number): void;\n stepFrames(count: number, dtMs?: number): void;\n}\n\n/** Minimal view of a game loop needed by the debug clock. */\ninterface GameLoopLike {\n tick(dtMs: number): void;\n readonly fixedTimestep: number;\n}\n\n/**\n * Controls engine time-stepping for deterministic E2E tests.\n *\n * When manual mode is active the renderer ticker is paused and frames\n * advance only via explicit `step()` / `stepFrames()` calls.\n */\nexport class DebugClock implements IDebugClock {\n private _isManual = false;\n\n constructor(\n private readonly gameLoop: GameLoopLike,\n private readonly stopTicker: () => void,\n private readonly startTicker: () => void,\n private readonly render: () => void,\n ) {}\n\n get isManual(): boolean {\n return this._isManual;\n }\n\n startAuto(): void {\n if (!this._isManual) return;\n this.startTicker();\n this._isManual = false;\n }\n\n stopAuto(): void {\n if (this._isManual) return;\n this.stopTicker();\n this._isManual = true;\n }\n\n step(dtMs?: number): void {\n if (!this._isManual) {\n throw new Error(\n \"Manual clock is not active. Call clock.stopAuto() first.\",\n );\n }\n const dt = dtMs ?? this.gameLoop.fixedTimestep;\n this.gameLoop.tick(dt);\n this.render();\n }\n\n stepFrames(count: number, dtMs?: number): void {\n if (!Number.isInteger(count) || count < 0) {\n throw new Error(\n \"stepFrames(count) requires a non-negative integer count.\",\n );\n }\n for (let i = 0; i < count; i++) {\n this.step(dtMs);\n }\n }\n\n /** Enter or exit manual mode. Used by DebugPlugin for config-driven init. */\n setManual(enabled: boolean): void {\n if (enabled === this._isManual) return;\n if (enabled) {\n this.stopTicker();\n } else {\n this.startTicker();\n }\n this._isManual = enabled;\n }\n}\n","import type { DebugContributor, DebugRegistry } from \"./types.js\";\n\n/** Concrete implementation of the DebugRegistry interface. */\nexport class DebugRegistryImpl implements DebugRegistry {\n readonly contributors = new Map<string, DebugContributor>();\n enabled = false;\n private flags = new Map<string, boolean>();\n\n register(contributor: DebugContributor): void {\n if (this.contributors.has(contributor.name)) return;\n this.contributors.set(contributor.name, contributor);\n for (const flag of contributor.flags) {\n this.flags.set(`${contributor.name}.${flag}`, true);\n }\n }\n\n isEnabled(): boolean {\n return this.enabled;\n }\n\n isFlagEnabled(contributorName: string, flag: string): boolean {\n return this.flags.get(`${contributorName}.${flag}`) ?? true;\n }\n\n toggle(): void {\n this.enabled = !this.enabled;\n }\n\n toggleFlag(contributorName: string, flag: string): void {\n const key = `${contributorName}.${flag}`;\n this.flags.set(key, !(this.flags.get(key) ?? true));\n }\n\n setFlag(contributorName: string, flag: string, value: boolean): void {\n this.flags.set(`${contributorName}.${flag}`, value);\n }\n}\n","import { LoggerKey, Scene } from \"@yagejs/core\";\nimport type { Logger } from \"@yagejs/core\";\nimport type { LayerDef } from \"@yagejs/renderer\";\nimport { SceneRenderTreeKey } from \"@yagejs/renderer\";\nimport type { Container } from \"pixi.js\";\n\n/**\n * Scene mounted by the debug plugin via `SceneManager._mountDetached`.\n * Declares two layers:\n * - `\"debug-world\"` — world-space, rides the camera (for collision shapes).\n * - `\"debug-hud\"` — screen-space, fixed overlay (text readouts).\n *\n * `pauseBelow: false` / `transparentBelow: true` so the underlying game\n * keeps running and rendering behind the overlay.\n */\nexport class DebugScene extends Scene {\n readonly name = \"__debug__\";\n override readonly pauseBelow = false;\n override readonly transparentBelow = true;\n readonly layers: readonly LayerDef[] = [\n { name: \"debug-world\", order: 999999 },\n { name: \"debug-hud\", order: 999999 },\n ];\n\n /** Called after `_mountDetached` has materialized the render tree. */\n onReady?: (worldContainer: Container, hudContainer: Container) => void;\n\n /** Called by the plugin when the scene is unmounted. */\n onTearDown?: () => void;\n\n onEnter(): void {\n const tree = this._resolveScoped(SceneRenderTreeKey);\n if (!tree) {\n // Shouldn't happen — DebugPlugin declares `renderer` as a dependency\n // so the renderer's `beforeEnter` hook should have materialized a\n // tree before this runs. Surface it rather than silently skipping\n // the overlay wiring.\n const logger = this.context.tryResolve(LoggerKey) as Logger | undefined;\n const msg =\n \"DebugScene.onEnter: SceneRenderTreeKey missing — debug overlay will not render. Is RendererPlugin registered?\";\n if (logger) logger.warn(\"debug\", msg);\n else console.warn(`[yage] ${msg}`);\n return;\n }\n const worldContainer = tree.get(\"debug-world\").container;\n const hudContainer = tree.get(\"debug-hud\").container;\n worldContainer.eventMode = \"none\";\n hudContainer.eventMode = \"none\";\n this.onReady?.(worldContainer, hudContainer);\n }\n\n onExit(): void {\n this.onTearDown?.();\n }\n}\n","import type { StatsApi } from \"./types.js\";\n\nconst WINDOW_SIZE = 120;\n\ninterface RingBuffer {\n data: Float64Array;\n count: number;\n index: number;\n}\n\n/** Rolling-window statistics store backed by Float64Array ring buffers. */\nexport class StatsStore implements StatsApi {\n private rings = new Map<string, RingBuffer>();\n\n push(key: string, value: number): void {\n let ring = this.rings.get(key);\n if (!ring) {\n ring = { data: new Float64Array(WINDOW_SIZE), count: 0, index: 0 };\n this.rings.set(key, ring);\n }\n ring.data[ring.index] = value;\n ring.index = (ring.index + 1) % WINDOW_SIZE;\n if (ring.count < WINDOW_SIZE) ring.count++;\n }\n\n average(key: string): number {\n const ring = this.rings.get(key);\n if (!ring || ring.count === 0) return 0;\n const { data, count } = ring;\n let sum = 0;\n for (let i = 0; i < count; i++) sum += data[i] ?? 0;\n return sum / count;\n }\n\n latest(key: string): number {\n const ring = this.rings.get(key);\n if (!ring || ring.count === 0) return 0;\n return ring.data[(ring.index - 1 + WINDOW_SIZE) % WINDOW_SIZE] ?? 0;\n }\n\n min(key: string): number {\n const ring = this.rings.get(key);\n if (!ring || ring.count === 0) return 0;\n const { data, count } = ring;\n let m = Infinity;\n for (let i = 0; i < count; i++) {\n const v = data[i] ?? 0;\n if (v < m) m = v;\n }\n return m;\n }\n\n max(key: string): number {\n const ring = this.rings.get(key);\n if (!ring || ring.count === 0) return 0;\n const { data, count } = ring;\n let m = -Infinity;\n for (let i = 0; i < count; i++) {\n const v = data[i] ?? 0;\n if (v > m) m = v;\n }\n return m;\n }\n}\n","import { Graphics, Container } from \"pixi.js\";\n\n/** Allocation-free pool of PixiJS Graphics objects for debug drawing. */\nexport class GraphicsPool {\n private pool: Graphics[] | null = null;\n private index = 0;\n private readonly container: Container;\n private readonly maxSize: number;\n\n constructor(container: Container, maxSize = 256) {\n this.container = container;\n this.maxSize = maxSize;\n }\n\n /** Lazily create Graphics objects on first use (ensures PixiJS is fully ready). */\n private ensure(): Graphics[] {\n if (this.pool) return this.pool;\n this.pool = [];\n for (let i = 0; i < this.maxSize; i++) {\n const g = new Graphics();\n g.visible = false;\n g.eventMode = \"none\";\n this.container.addChild(g);\n this.pool.push(g);\n }\n return this.pool;\n }\n\n /** Return the next available Graphics, or undefined if the pool is exhausted. */\n acquire(): Graphics | undefined {\n const pool = this.ensure();\n if (this.index >= pool.length) return undefined;\n const g = pool[this.index]!;\n g.visible = true;\n this.index++;\n return g;\n }\n\n /** Clear and hide all previously acquired graphics, reset index. */\n resetFrame(): void {\n if (!this.pool) return;\n for (let i = 0; i < this.index; i++) {\n const g = this.pool[i]!;\n g.clear();\n g.visible = false;\n g.position.set(0, 0);\n g.rotation = 0;\n g.scale.set(1, 1);\n }\n this.index = 0;\n }\n\n destroy(): void {\n if (!this.pool) return;\n for (const g of this.pool) {\n g.destroy();\n }\n this.pool.length = 0;\n }\n}\n","import { Text, Container } from \"pixi.js\";\n\nconst LINE_HEIGHT = 16;\nconst FONT_SIZE = 14;\nconst PADDING = 4;\n\n/** Allocation-free pool of PixiJS Text objects for HUD debug lines. */\nexport class TextPool {\n private pool: Text[] | null = null;\n private index = 0;\n private readonly container: Container;\n private readonly maxLines: number;\n\n constructor(container: Container, maxLines = 32) {\n this.container = container;\n this.maxLines = maxLines;\n }\n\n /** Lazily create Text objects on first use (ensures PixiJS is fully ready). */\n private ensure(): Text[] {\n if (this.pool) return this.pool;\n this.pool = [];\n for (let i = 0; i < this.maxLines; i++) {\n const t = new Text({\n text: \"\",\n style: {\n fontFamily: \"monospace\",\n fontSize: FONT_SIZE,\n fill: 0xffffff,\n },\n });\n t.visible = false;\n t.eventMode = \"none\";\n this.container.addChild(t);\n this.pool.push(t);\n }\n return this.pool;\n }\n\n /** Show a text line at the next available slot. */\n addLine(text: string): void {\n const pool = this.ensure();\n if (this.index >= pool.length) return;\n const t = pool[this.index]!;\n t.text = text;\n t.visible = true;\n t.position.set(PADDING, PADDING + this.index * LINE_HEIGHT);\n this.index++;\n }\n\n /** Hide all lines and reset for the next frame. */\n resetFrame(): void {\n if (!this.pool) return;\n for (let i = 0; i < this.index; i++) {\n this.pool[i]!.visible = false;\n }\n this.index = 0;\n }\n\n destroy(): void {\n if (!this.pool) return;\n for (const t of this.pool) {\n t.destroy();\n }\n this.pool.length = 0;\n }\n}\n","import type { WorldDebugApi, DebugGraphics } from \"./types.js\";\nimport type { GraphicsPool } from \"./GraphicsPool.js\";\nimport type { DebugRegistryImpl } from \"./DebugRegistryImpl.js\";\n\n/** WorldDebugApi backed by a GraphicsPool. Contributor name is swapped per iteration. */\nexport class WorldDebugApiImpl implements WorldDebugApi {\n private _contributorName = \"\";\n\n constructor(\n private readonly pool: GraphicsPool,\n private readonly registry: DebugRegistryImpl,\n private readonly _camera: { zoom: number },\n ) {}\n\n /** Set the current contributor name (called before each contributor's drawWorld). */\n setContributor(name: string): void {\n this._contributorName = name;\n }\n\n acquireGraphics(): DebugGraphics | undefined {\n return this.pool.acquire() as unknown as DebugGraphics | undefined;\n }\n\n isFlagEnabled(flag: string): boolean {\n return this.registry.isFlagEnabled(this._contributorName, flag);\n }\n\n get cameraZoom(): number {\n return this._camera.zoom;\n }\n}\n","import type { HudDebugApi } from \"./types.js\";\nimport type { TextPool } from \"./TextPool.js\";\nimport type { DebugRegistryImpl } from \"./DebugRegistryImpl.js\";\n\n/** HudDebugApi backed by a TextPool. Contributor name is swapped per iteration. */\nexport class HudDebugApiImpl implements HudDebugApi {\n private _contributorName = \"\";\n\n constructor(\n private readonly textPool: TextPool,\n private readonly registry: DebugRegistryImpl,\n public readonly screenWidth: number,\n public readonly screenHeight: number,\n ) {}\n\n /** Set the current contributor name (called before each contributor's drawHud). */\n setContributor(name: string): void {\n this._contributorName = name;\n }\n\n addLine(text: string): void {\n this.textPool.addLine(text);\n }\n\n isFlagEnabled(flag: string): boolean {\n return this.registry.isFlagEnabled(this._contributorName, flag);\n }\n}\n","import { System, Phase } from \"@yagejs/core\";\nimport type { Container } from \"pixi.js\";\nimport type { CameraComponent } from \"@yagejs/renderer\";\nimport type { DebugRegistryImpl } from \"./DebugRegistryImpl.js\";\nimport type { GraphicsPool } from \"./GraphicsPool.js\";\nimport type { TextPool } from \"./TextPool.js\";\nimport type { WorldDebugApiImpl } from \"./WorldDebugApiImpl.js\";\nimport type { HudDebugApiImpl } from \"./HudDebugApiImpl.js\";\nimport type { StatsStore } from \"./StatsStore.js\";\n\nexport interface DebugCameraAccessor {\n findCamera(): CameraComponent | undefined;\n viewportWidth: number;\n viewportHeight: number;\n}\n\n/** Renders all debug contributors. Runs after DisplaySystem in the Render phase. */\nexport class DebugRenderSystem extends System {\n readonly phase = Phase.Render;\n readonly priority = 9999;\n\n constructor(\n private readonly registry: DebugRegistryImpl,\n private readonly graphicsPool: GraphicsPool,\n private readonly textPool: TextPool,\n private readonly worldApi: WorldDebugApiImpl,\n private readonly hudApi: HudDebugApiImpl,\n private readonly stats: StatsStore,\n private readonly worldContainer: Container,\n private readonly hudContainer: Container,\n private readonly cameraAccessor: DebugCameraAccessor,\n ) {\n super();\n }\n\n update(dt: number): void {\n if (!this.registry.enabled) {\n this.worldContainer.visible = false;\n this.hudContainer.visible = false;\n return;\n }\n\n this.worldContainer.visible = true;\n this.hudContainer.visible = true;\n\n // Apply camera transform to the debug world container so that\n // world-space debug drawing (collision shapes, etc.) aligns with\n // the active scene's camera.\n this.syncWorldCamera();\n\n this.graphicsPool.resetFrame();\n this.textPool.resetFrame();\n\n for (const [name, contributor] of this.registry.contributors) {\n contributor.sample?.(this.stats, dt);\n\n if (contributor.drawWorld) {\n this.worldApi.setContributor(name);\n contributor.drawWorld(this.worldApi);\n }\n\n if (contributor.drawHud) {\n this.hudApi.setContributor(name);\n contributor.drawHud(this.hudApi);\n }\n }\n }\n\n private syncWorldCamera(): void {\n const cam = this.cameraAccessor.findCamera();\n if (!cam) {\n this.worldContainer.position.set(0, 0);\n this.worldContainer.scale.set(1, 1);\n this.worldContainer.rotation = 0;\n return;\n }\n\n const vw = this.cameraAccessor.viewportWidth;\n const vh = this.cameraAccessor.viewportHeight;\n const rotatedPos = cam.effectivePosition\n .scale(cam.zoom)\n .rotate(-cam.rotation);\n this.worldContainer.position.x = vw / 2 - rotatedPos.x;\n this.worldContainer.position.y = vh / 2 - rotatedPos.y;\n this.worldContainer.scale.set(cam.zoom);\n this.worldContainer.rotation = -cam.rotation;\n }\n}\n","import type { DebugContributor, StatsApi, HudDebugApi } from \"../types.js\";\n\nexport class FpsContributor implements DebugContributor {\n readonly name = \"fps\";\n readonly flags: readonly string[] = [];\n private stats: StatsApi | null = null;\n\n sample(stats: StatsApi, dt: number): void {\n this.stats = stats;\n if (dt > 0) stats.push(\"fps\", 1000 / dt);\n }\n\n drawHud(api: HudDebugApi): void {\n const avg = this.stats?.average(\"fps\") ?? 0;\n api.addLine(`FPS: ${Math.round(avg)}`);\n }\n}\n","import type { DebugContributor, HudDebugApi } from \"../types.js\";\nimport type { Inspector } from \"@yagejs/core\";\n\nexport class EntityCountContributor implements DebugContributor {\n readonly name = \"entities\";\n readonly flags: readonly string[] = [];\n\n constructor(private readonly inspector: Inspector) {}\n\n drawHud(api: HudDebugApi): void {\n const count = this.inspector.snapshot().entityCount;\n api.addLine(`Entities: ${count}`);\n }\n}\n","import type { DebugContributor, StatsApi, HudDebugApi } from \"../types.js\";\n\nexport class SystemTimingContributor implements DebugContributor {\n readonly name = \"timing\";\n readonly flags = [\"breakdown\"] as const;\n private stats: StatsApi | null = null;\n\n constructor(private readonly timings: Map<string, number>) {}\n\n sample(stats: StatsApi): void {\n this.stats = stats;\n for (const [name, ms] of this.timings) {\n stats.push(`system.${name}`, ms);\n }\n }\n\n drawHud(api: HudDebugApi): void {\n if (!this.stats) return;\n\n let total = 0;\n const entries: Array<[string, number]> = [];\n for (const name of this.timings.keys()) {\n const avg = this.stats.average(`system.${name}`);\n total += avg;\n entries.push([name, avg]);\n }\n\n api.addLine(`Systems: ${total.toFixed(2)}ms`);\n\n if (api.isFlagEnabled(\"breakdown\")) {\n entries.sort((a, b) => b[1] - a[1]);\n for (const [name, avg] of entries) {\n api.addLine(` ${name}: ${avg.toFixed(2)}ms`);\n }\n }\n }\n}\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yagejs/debug",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "FPS counter, entity inspector, and dev overlays for YAGE",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"yage",
|
|
@@ -58,8 +58,8 @@
|
|
|
58
58
|
"clean": "rm -rf dist"
|
|
59
59
|
},
|
|
60
60
|
"dependencies": {
|
|
61
|
-
"@yagejs/core": "^0.
|
|
62
|
-
"@yagejs/renderer": "^0.
|
|
61
|
+
"@yagejs/core": "^0.2.0",
|
|
62
|
+
"@yagejs/renderer": "^0.2.0",
|
|
63
63
|
"pixi.js": "^8.5.0"
|
|
64
64
|
}
|
|
65
65
|
}
|