Skip to content

Commit 8eb62d4

Browse files
author
DavidQ
committed
Rebuild Input Mapping V2 from template using engine input sources - PR_26140_087-rebuild-input-mapping-v2-from-template
1 parent 0926021 commit 8eb62d4

26 files changed

Lines changed: 1600 additions & 747 deletions
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# Input Mapping V2 Template Rebuild Report
2+
3+
Task: PR_26140_087-rebuild-input-mapping-v2-from-template
4+
5+
## Summary
6+
- Removed the prior hand-built Input Mapping V2 app structure and rebuilt the tool shell from the current `tools/templates-v2/` template.
7+
- Kept the template header, menus, accordion, panel, and status conventions with external JS/CSS only.
8+
- Added the Input Mapping V2 feature layer on top of the copied template instead of hand-rolling the shell.
9+
- Preserved Workspace Manager V2 launch behavior and workspace header return behavior.
10+
11+
## Engine Input Alignment
12+
- `EngineInputSourceService` imports existing engine sources from `/src/engine/input/`:
13+
- `InputService`
14+
- `GamepadInputAdapter`
15+
- `InputMappingState` imports the existing engine `InputMap` model.
16+
- Surfaced supported source groups represented by engine input code:
17+
- Keyboard via `InputService` / `KeyboardState`
18+
- Mouse via `InputService` / `MouseState`
19+
- Gamepad buttons via `InputService` / `GamepadState` / `GamepadInputAdapter`
20+
- Gamepad axes via `GamepadInputAdapter`
21+
- No duplicate standalone input model was introduced.
22+
23+
## Behavior Updates
24+
- Expanded default actions to generic engine-style actions for movement, confirm/cancel, menu, interaction, jump/fire/thrust, and rotation.
25+
- Removed `Pause` from the default action list.
26+
- Keyboard capture records labels such as `Keyboard KeyA`.
27+
- Captured input chips are buttons; clicking a chip removes that captured input.
28+
- Gamepad capture uses the engine gamepad adapter when live browser gamepad data is available.
29+
- If the browser cannot provide a live gamepad value, the tool logs an actionable WARN explaining the unavailable capture reason.
30+
- Mapping JSON export/import uses the current template command/status flow.
31+
32+
## State/Storage Inspector Audit
33+
- Storage Inspector V2 and State Inspector references were not changed by this PR.
34+
- This PR is limited to rebuilding Input Mapping V2 from the template and validating its launch and capture behavior.
35+
36+
## Scope Guardrails
37+
- No schema files were changed.
38+
- No sample JSON files were changed.
39+
- Full samples smoke test was not run, per request.
40+
41+
## Validation
42+
- Targeted syntax/import validation for changed Input Mapping V2 files: PASS.
43+
- Focused Playwright validation for Input Mapping V2 launch/capture/delete/gamepad-WARN behavior: PASS.
44+
- `npm run test:workspace-v2`: PASS, 60 tests.

docs/tools/input-mapping-v2/uat.md

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,24 @@
1010

1111
- Select `Move Left`.
1212
- Click `Capture Keyboard`.
13-
- Press `ArrowLeft`.
14-
- Confirm the mapping list and JSON output include `moveLeft` with `ArrowLeft`.
13+
- Press `KeyA`.
14+
- Confirm the mapping list and JSON output include `moveLeft` with `Keyboard KeyA`.
15+
- Click the `Keyboard KeyA` captured input token.
16+
- Confirm the mapping is deleted.
17+
18+
## Default Actions
19+
20+
- Confirm the default actions include movement, confirm/cancel, fire, thrust, and rotation actions.
21+
- Confirm `Pause` is not present in the default action dropdown.
1522

1623
## Gamepad Capture
1724

1825
- Connect a gamepad.
1926
- Press or hold a button or axis.
2027
- Click `Capture Gamepad`.
2128
- Confirm the mapping list and JSON output include the detected gamepad input.
29+
- If the browser does not expose a live gamepad value, confirm the Status log shows an actionable WARN.
2230

2331
## Device Refresh
2432

25-
- Click `Refresh Devices`.
26-
- Confirm keyboard availability is shown.
27-
- Confirm connected gamepads are listed with button and axis counts.
33+
- Confirm Engine Input Sources lists `InputService + KeyboardState`, `InputService + MouseState`, `InputService + GamepadState + GamepadInputAdapter`, and `GamepadInputAdapter`.

tests/playwright/tools/WorkspaceManagerV2.spec.mjs

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1400,20 +1400,30 @@ test.describe("Workspace Manager V2 bootstrap", () => {
14001400

14011401
try {
14021402
await expect(page.locator("body[data-tool-id='input-mapping-v2']")).toBeVisible();
1403-
await expect(page.locator("[data-input-mapping-v2-summary]")).toContainText("Input Mapping V2");
1404-
await expect(page.locator(".input-mapping-v2__tool-menu")).toBeVisible();
1405-
await expect(page.locator(".input-mapping-v2__workspace-menu")).toBeHidden();
1406-
await expect(page.locator("#inputMappingV2ActionSelect")).toContainText("Move Left");
1403+
await expect(page.locator("[data-tool-starter-summary]")).toBeVisible();
1404+
await expect(page.locator(".tools-platform-frame__title[data-tool-id='input-mapping-v2']")).toHaveText("Input Mapping V2");
1405+
await expect(page.locator(".tool-starter__tool__menu")).toBeVisible();
1406+
await expect(page.locator(".tool-starter__workspace__menu")).toBeHidden();
1407+
await expect(page.locator("#inputMappingV2SourceList")).toContainText("InputService + KeyboardState");
1408+
await expect(page.locator("#inputMappingV2SourceList")).toContainText("InputService + MouseState");
1409+
await expect(page.locator("#inputMappingV2SourceList")).toContainText("InputService + GamepadState + GamepadInputAdapter");
1410+
await expect(page.locator("#inputMappingV2SourceList")).toContainText("GamepadInputAdapter");
1411+
const actionOptions = await page.locator("#inputMappingV2ActionSelect option").allTextContents();
1412+
expect(actionOptions).toEqual(expect.arrayContaining(["Move Left", "Confirm", "Cancel", "Fire", "Thrust", "Rotate Left", "Rotate Right"]));
1413+
expect(actionOptions).not.toContain("Pause");
14071414
await page.locator("#inputMappingV2ActionSelect").selectOption("moveLeft");
14081415
await page.locator("#inputMappingV2CaptureKeyboardButton").click();
1409-
await expect(page.locator("[data-input-mapping-v2-banner]")).toContainText("Press a keyboard key");
1410-
await page.keyboard.press("ArrowLeft");
1411-
await expect(page.locator("#inputMappingV2MappingList")).toContainText("Move Left");
1412-
await expect(page.locator("#inputMappingV2MappingList")).toContainText("Keyboard ArrowLeft");
1413-
await expect(page.locator("#inputMappingV2JsonOutput")).toContainText('"action": "moveLeft"');
1414-
await expect(page.locator("#inputMappingV2JsonOutput")).toContainText('"code": "ArrowLeft"');
1415-
await expect(page.locator("#inputMappingV2LastInput")).toContainText('"type": "keyboard"');
1416-
await expect(page.locator("#inputMappingV2DeviceList")).toContainText("Keyboard");
1416+
await expect(page.locator("#inputMappingV2CaptureMessage")).toContainText("Press a keyboard key");
1417+
await page.keyboard.press("KeyA");
1418+
await expect(page.locator("#previewOutput")).toContainText("Move Left");
1419+
await expect(page.locator("#previewOutput")).toContainText("Keyboard KeyA");
1420+
await expect(page.locator("#inspectorOutput")).toContainText('"action": "moveLeft"');
1421+
await expect(page.locator("#inspectorOutput")).toContainText('"binding": "KeyA"');
1422+
await page.locator(".input-mapping-v2__input-token", { hasText: "Keyboard KeyA" }).click();
1423+
await expect(page.locator(".input-mapping-v2__input-token", { hasText: "Keyboard KeyA" })).toHaveCount(0);
1424+
await expect(page.locator("#previewOutput")).toContainText("No inputs captured yet.");
1425+
await page.locator("#inputMappingV2CaptureGamepadButton").click();
1426+
await expect(page.locator("#statusLog")).toHaveValue(/WARN Gamepad capture unavailable:/);
14171427
await page.evaluate(() => {
14181428
Object.defineProperty(navigator, "clipboard", {
14191429
configurable: true,
@@ -1424,9 +1434,9 @@ test.describe("Workspace Manager V2 bootstrap", () => {
14241434
}
14251435
});
14261436
});
1427-
await page.locator("#inputMappingV2CopyJsonButton").click();
1437+
await page.locator("#toolCopyJsonButton").click();
14281438
expect(await page.evaluate(() => window.__inputMappingV2Clipboard)).toContain('"toolId": "input-mapping-v2"');
1429-
await expect(page.locator("#statusLog")).toContainText("[OK] Copied mapping JSON to clipboard.");
1439+
await expect(page.locator("#statusLog")).toHaveValue(/OK Mapping JSON copied\./);
14301440
expect(pageErrors).toEqual([]);
14311441
} finally {
14321442
await workspaceV2CoverageReporter.stop(page);
@@ -11226,7 +11236,7 @@ test.describe("Workspace Manager V2 bootstrap", () => {
1122611236
await expect(page.locator("#statusLog")).toHaveValue(/OK Restored repo destination from workspace\.repo\.reference for HTML-JavaScript-Gaming\./);
1122711237
await inputMappingTile.click();
1122811238
await expect(page).toHaveURL(/input-mapping-v2\/index\.html.*launch=workspace/);
11229-
await expect(page.locator(".input-mapping-v2__workspace-menu")).toBeVisible();
11239+
await expect(page.locator(".tool-starter__workspace__menu")).toBeVisible();
1123011240
await expect(page.locator("#inputMappingV2CaptureKeyboardButton")).toBeVisible();
1123111241
await page.locator("#returnToWorkspaceButton").click();
1123211242
await expect(page).toHaveURL(/workspace-manager-v2\/index\.html\?.*hostContextId=workspace-manager-v2-/);

tools/input-mapping-v2/README.md

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
# Input Mapping V2
22

3-
Input Mapping V2 is a generic keyboard and gamepad binding tool for games, tools, and samples.
3+
Input Mapping V2 is a First-Class Tool V2 surface for mapping keyboard, mouse, and gamepad inputs to reusable actions.
44

55
## Scope
66

7-
- Captures keyboard keys for named actions.
8-
- Captures currently pressed gamepad buttons or axes.
9-
- Shows live device availability, current mappings, and exportable mapping JSON.
10-
- Supports workspace-launched return behavior.
7+
- Uses the official `tools/templates-v2/` shell, menu, panel, accordion, and status conventions.
8+
- Imports engine input sources from `src/engine/input/**`.
9+
- Captures keyboard keys, mouse buttons, gamepad buttons, and gamepad axes where the browser exposes live values.
10+
- Uses `InputMap` as the action-to-physical-input mapping model.
11+
- Supports captured input deletion by clicking the captured input token.
1112

12-
The tool does not provide hidden fallback action sets. Default actions are only starter bindings for interactive mapping and can be cleared or extended in the UI.
13+
## Template Source
14+
15+
Input Mapping V2 was rebuilt from the current official Tool Template V2 for PR_26140_087.
Lines changed: 28 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,31 @@
1-
<!DOCTYPE html>
1+
<!doctype html>
22
<html lang="en">
3-
<head>
4-
<meta charset="UTF-8">
5-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6-
<title>Input Mapping V2 - How To Use</title>
7-
<link rel="stylesheet" href="../../src/engine/theme/main.css">
8-
<link rel="stylesheet" href="../../src/engine/ui/hubCommon.css">
9-
<link rel="stylesheet" href="../common/toolShellCommon.css">
10-
</head>
11-
<body class="tools-platform-tool-page">
12-
<main class="tool-shell-common__app-shell">
13-
<header class="tool-shell-common__header">
14-
<div>
15-
<p class="tool-shell-common__eyebrow">How to use</p>
3+
<head>
4+
<meta charset="utf-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1">
6+
<title>Input Mapping V2 - How To Use</title>
7+
<link rel="stylesheet" href="../../src/engine/theme/main.css">
8+
<link rel="stylesheet" href="../../src/engine/ui/hubCommon.css">
9+
<link rel="stylesheet" href="./styles/toolStarter.css">
10+
</head>
11+
<body class="tools-platform-tool-page tools-platform-surface hub-page-tools" data-tool-id="input-mapping-v2">
12+
<main class="tool-starter app-shell" data-tool-id="input-mapping-v2">
13+
<section class="tool-starter__panel" aria-label="Input Mapping V2 workflow">
1614
<h1>Input Mapping V2</h1>
17-
<p class="tool-shell-common__description">Create keyboard and gamepad bindings for games, tools, and samples.</p>
18-
</div>
19-
<nav class="tool-shell-common__menu" aria-label="Input Mapping V2 links">
20-
<a href="./index.html">Open Tool</a>
21-
<a href="./README.md">Read Me</a>
22-
<a href="../index.html">Tools</a>
23-
</nav>
24-
</header>
25-
<section class="tool-shell-common__panel">
26-
<h2>Workflow</h2>
27-
<ol>
28-
<li>Select an action from the Actions panel.</li>
29-
<li>Use Capture Keyboard, then press the key to map.</li>
30-
<li>Use Capture Gamepad after pressing or holding the gamepad input to map.</li>
31-
<li>Review the generated mapping JSON and copy it when needed.</li>
32-
</ol>
33-
</section>
34-
</main>
35-
</body>
15+
<p>Select an action, capture a keyboard key, mouse button, or gamepad input, then review the generated mapping JSON.</p>
16+
<ol>
17+
<li>Open Input Mapping V2.</li>
18+
<li>Select an action from the Actions panel.</li>
19+
<li>Use Capture Keyboard, Capture Mouse, or Capture Gamepad.</li>
20+
<li>Click a captured input token to delete that binding.</li>
21+
<li>Use Copy JSON or Export toolState when the mapping is ready.</li>
22+
</ol>
23+
<nav class="tool-starter__menu" aria-label="Input Mapping V2 links">
24+
<a href="./index.html">Open Tool</a>
25+
<a href="./README.md">Read Me</a>
26+
<a href="../index.html">Tools</a>
27+
</nav>
28+
</section>
29+
</main>
30+
</body>
3631
</html>

0 commit comments

Comments
 (0)