mirror of
https://github.com/got-feedBack/feedBack.git
synced 2026-08-11 19:29:33 +00:00
* refactor(highway): lift 79 per-instance closure vars into `hwState` (R3c H lift) Collapses createHighway()'s 79 mutable closure `let`s into one per-instance `hwState` object. Scope-resolved rewrite via acorn + eslint-scope: 1059 edits (1057 references + 79 defs - the deleted `let canvas, ctx, ws`), with the four names shadowed in inner scopes (chartTime/ctx/notes/chordTemplates) resolved correctly so only closure-bound refs move. Enables the later module split: extracted renderer/ws modules close over `hwState` as a factory arg, so multi-panel plugins (highway_3d, note_detect, splitscreen) don't share one highway's state. Container is `hwState`, NOT `H` — `H` is already canvas height (70 uses). The frame-time gate caught that collision instantly (0 draws, `H._drawHooks is not iterable` in the shared draw-hook path). PERF (the whole risk): identical to the pre-lift baseline. Draw p50 2.1-2.2 ms, p95 2.7-3.0 ms (pre-lift 2.7-3.2), measured on the Arcturus feedpak, headless. Each closure-slot read became a `hwState.<slot>` monomorphic property load; the hot loop pays nothing. On-device: Byron confirmed the 2D highway plays smoothly. Tests: the ~30 highway JS suites brace-extract functions/patterns from the source; their state references + the monotonic-clock vm sandbox now use `hwState.<slot>` (the const _CHART_MAX_INTERP_MS etc. stay top-level, not lifted). node --test: 1030/1030 green. Two self-inflicted over-replacements caught and reverted (`_lefty` is a prefix of the 3D-local `_leftyCached`; `STRING_COLORS` a suffix of `DEFAULT_STRING_COLORS`) — substring replaces on the brace-extract regexes need word care. Transformer saved at ~/.local/share/feedback-editor/highway-h-lift.mjs. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * test(highway): pin the setNoteStateProvider assertion to hwState._noteStateProvider (CodeRabbit) The [^}]* form matched an unqualified _noteStateProvider =, so a regression to closure-level state could still pass. Require the hwState-qualified assignment. --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
94 lines
3.9 KiB
JavaScript
94 lines
3.9 KiB
JavaScript
// Pins 3D Highway left-handed fret ordering (feedBack#321).
|
|
// Source-level only, matching the other tests/js/ regression guards: the
|
|
// runtime path is browser/WebGL-heavy, so these tests preserve the exact
|
|
// contracts that keep the lefty geometry coherent.
|
|
|
|
const { test } = require('node:test');
|
|
const assert = require('node:assert/strict');
|
|
const fs = require('node:fs');
|
|
const path = require('node:path');
|
|
|
|
const ROOT = path.join(__dirname, '..', '..');
|
|
const HIGHWAY_JS = path.join(ROOT, 'static', 'highway.js');
|
|
const SCREEN_JS = path.join(ROOT, 'plugins', 'highway_3d', 'screen.js');
|
|
const CLAUDE_MD = path.join(ROOT, 'plugins', 'highway_3d', 'CLAUDE.md');
|
|
|
|
function src(file) {
|
|
return fs.readFileSync(file, 'utf8');
|
|
}
|
|
|
|
test('highway renderer bundles surface the core lefty flag', () => {
|
|
assert.match(
|
|
src(HIGHWAY_JS),
|
|
/lefty\s*[:=]\s*hwState\._lefty/,
|
|
'custom renderer bundles must include lefty: _lefty',
|
|
);
|
|
});
|
|
|
|
test('3D Highway defines lefty-aware fret-position helpers', () => {
|
|
const screen = src(SCREEN_JS);
|
|
assert.match(
|
|
screen,
|
|
/let\s+_leftyCached\s*=\s*false\s*;/,
|
|
'renderer must cache the bundle lefty flag',
|
|
);
|
|
assert.match(
|
|
screen,
|
|
/const\s+xFret\s*=\s*f\s*=>\s*\(\s*_leftyCached\s*\?\s*-fretX\(f\)\s*:\s*fretX\(f\)\s*\)/,
|
|
'xFret must mirror fret edges when lefty is active',
|
|
);
|
|
assert.match(
|
|
screen,
|
|
/const\s+xFretMid\s*=\s*f\s*=>\s*\(\s*_leftyCached\s*\?\s*-fretMid\(f\)\s*:\s*fretMid\(f\)\s*\)/,
|
|
'xFretMid must mirror fret centers when lefty is active',
|
|
);
|
|
assert.match(
|
|
screen,
|
|
/const\s+boardSpanX\s*=\s*\(\s*\)\s*=>\s*\{[\s\S]*?const\s+x0\s*=\s*xFret\(0\)\s*;[\s\S]*?const\s+xN\s*=\s*xFret\(NFRETS\)\s*;[\s\S]*?min\s*:\s*Math\.min\(x0,\s*xN\)[\s\S]*?max\s*:\s*Math\.max\(x0,\s*xN\)[\s\S]*?center\s*:\s*\(x0\s*\+\s*xN\)\s*\/\s*2[\s\S]*?width\s*:\s*Math\.abs\(xN\s*-\s*x0\)/,
|
|
'boardSpanX must derive min/max/center/width from the lefty-aware xFret helper',
|
|
);
|
|
});
|
|
|
|
test('draw(bundle) handles lefty changes by flipping camera X state and rebuilding the board', () => {
|
|
const screen = src(SCREEN_JS);
|
|
assert.match(
|
|
screen,
|
|
/_leftyCached\s*=\s*!!bundle\.lefty\s*;/,
|
|
'draw(bundle) must refresh _leftyCached from bundle.lefty',
|
|
);
|
|
assert.match(
|
|
screen,
|
|
/const\s+leftyChanged\s*=\s*_leftyCached\s*!==\s*_leftyForBoard\s*;/,
|
|
'draw(bundle) must detect runtime lefty changes',
|
|
);
|
|
assert.match(
|
|
screen,
|
|
/if\s*\(\s*_invertedCached\s*!==\s*_invertedForBoard\s*\|\|\s*leftyChanged\s*\|\|\s*newNStr\s*!==\s*nStr\s*\)\s*\{[\s\S]*?if\s*\(\s*leftyChanged\s*\)\s*\{[\s\S]*?curX\s*=\s*-curX\s*;[\s\S]*?tgtX\s*=\s*-tgtX\s*;[\s\S]*?_lookaheadCamX\s*=\s*-_lookaheadCamX\s*;[\s\S]*?\}[\s\S]*?buildBoard\(\)\s*;[\s\S]*?_leftyForBoard\s*=\s*_leftyCached\s*;/,
|
|
'lefty changes must mirror curX/tgtX/_lookaheadCamX, rebuild board geometry, and update _leftyForBoard',
|
|
);
|
|
});
|
|
|
|
test('camera shoulder offset follows the cached lefty orientation', () => {
|
|
assert.match(
|
|
src(SCREEN_JS),
|
|
// The shoulder offset now feeds the base _camX (which the opt-in
|
|
// free-camera bridge layers on top of) before cam.position.set (#771).
|
|
/const\s+shoulderOffset\s*=\s*\(\s*_leftyCached\s*\?\s*-1\s*:\s*1\s*\)\s*\*\s*10\s*\*\s*K\s*;[\s\S]*?_camX\s*=\s*curX\s*\+\s*shoulderOffset/,
|
|
'camera shoulder offset must flip with _leftyCached',
|
|
);
|
|
});
|
|
|
|
test('3D Highway documentation says the renderer consumes bundle.lefty', () => {
|
|
const doc = src(CLAUDE_MD);
|
|
assert.doesNotMatch(
|
|
doc,
|
|
/bundle\.lefty[\s\S]{0,180}renderer never reads it/,
|
|
'CLAUDE.md must not claim the 3D renderer ignores bundle.lefty',
|
|
);
|
|
assert.match(
|
|
doc,
|
|
/bundle\.lefty[\s\S]{0,240}(?:mirrors|lefty|left-handed|left-handed)/i,
|
|
'CLAUDE.md should document the lefty flag as part of the renderer contract',
|
|
);
|
|
});
|