move single-unit warship selection box to WebGL SelectionBoxPass

UnitSelectionEvent now forwards to view.setSelectedUnit(unit.id()) in
mountWebGLDebugRenderer; the renderer's SelectionBoxPass draws the
animated stippled outline on the GPU. UILayer still tracks
selectedUnit for game-logic readers (the click handlers) but no longer
paints to canvas2D for it.

Drops drawSelectionBox + lastSelectionBoxCenter (~50 LOC) plus the
per-tick single-unit redraw in tick(). Multi-selection stays on
canvas2D — SelectionBoxPass is single-unit only.

Test update: replaces the now-dead drawSelectionBox spy with a
selectedUnit state assertion + a deselect case.
This commit is contained in:
evanpelle
2026-05-16 19:53:13 -07:00
parent d1651017ea
commit ede0fb7668
3 changed files with 61 additions and 91 deletions
+22 -3
View File
@@ -36,7 +36,7 @@ describe("UILayer", () => {
expect(ui["context"]).not.toBeNull();
});
it("should handle unit selection event", () => {
it("tracks the selected unit on single-unit selection (rendering is WebGL)", () => {
const ui = new UILayer(game, eventBus, transformHandler);
ui.redraw();
const unit = {
@@ -46,8 +46,27 @@ describe("UILayer", () => {
owner: () => ({}),
};
const event = { isSelected: true, unit };
ui.drawSelectionBox = vi.fn();
ui["onUnitSelection"](event as UnitSelectionEvent);
expect(ui.drawSelectionBox).toHaveBeenCalledWith(unit);
// selectedUnit is held for game-logic callers (the click handlers). The
// visual selection box is now drawn by WebGL SelectionBoxPass — wired
// from ClientGameRunner via view.setSelectedUnit(unit.id()).
expect(ui["selectedUnit"]).toBe(unit);
});
it("clears selection on deselect", () => {
const ui = new UILayer(game, eventBus, transformHandler);
ui.redraw();
const unit = {
type: () => "Warship",
isActive: () => true,
tile: () => ({}),
owner: () => ({}),
};
ui["onUnitSelection"]({ isSelected: true, unit } as UnitSelectionEvent);
ui["onUnitSelection"]({
isSelected: false,
unit: null,
} as unknown as UnitSelectionEvent);
expect(ui["selectedUnit"]).toBeNull();
});
});