Make InputMapper.setInteraction auto-add when matched entry is broader#18461
Make InputMapper.setInteraction auto-add when matched entry is broader#18461georginahalpern wants to merge 3 commits into
Conversation
Per AmoebaChant follow-up review feedback: the previous setInteraction
silently mutated the catch-all entry when called with conditions stricter
than any existing entry, which broke unrelated gestures. Example: calling
`setInteraction("pointer", { button: 0, modifiers: { ctrl: true } }, "rotate")`
on the GeospatialCamera default map (which has no ctrl-modifier entry)
mutated the unmodified `{ button: 0, interaction: "pan" }` catch-all and
broke plain left-drag.
New behavior:
- If the matched entry is at least as specific as the supplied conditions,
mutate its interaction in place (unchanged from before).
- If the matched entry is broader than the conditions (e.g. catch-all
matched a ctrl-modified request), add a new more-specific entry via
addEntry instead. The new entry wins for the requested combination
without clobbering the broader entry.
- If no entry matches at all, also add a new entry.
Internal helpers _entryIsAtLeastAsSpecificAsConditions and
_modifiersAtLeastAsSpecific implement the broader-than detection.
Tests: 5 new cases in cameraMovement.test.ts covering mutate-in-place,
modifier-broader add, button-broader add, no-match add, and the
less-specific-conditions add path. All 189 camera tests pass.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Please make sure to label your PR with "bug", "new feature" or "breaking change" label(s). |
Collapse _entryIsAtLeastAsSpecificAsConditions and _modifiersAtLeastAsSpecific into one _entryConstrainsAllOf helper. InputConditions is a flat type with all source-specific fields optional, so a string-keyed loop over the four fields (button, key, touchCount, modifiers) covers every source naturally -- the irrelevant fields for a given source are undefined on both entry and conditions and harmlessly skip the early return. Saves ~25 lines, no behavior change. All 5 setInteraction tests still pass. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Please make sure to label your PR with "bug", "new feature" or "breaking change" label(s). |
|
Snapshot stored with reference name: Test environment: To test a playground add it to the URL, for example: https://snapshots-cvgtc2eugrd3cgfd.z01.azurefd.net/refs/pull/18461/merge/index.html#WGZLGJ#4600 Links to test your changes to core in the published versions of the Babylon tools (does not contain changes you made to the tools themselves): https://playground.babylonjs.com/?snapshot=refs/pull/18461/merge To test the snapshot in the playground with a playground ID add it after the snapshot query string: https://playground.babylonjs.com/?snapshot=refs/pull/18461/merge#BCU1XR#0 If you made changes to the sandbox or playground in this PR, additional comments will be generated soon containing links to the dev versions of those tools. |
The movement system is unconditionally on for ArcRotateCamera (and GeospatialCamera). The setter has always been a no-op and the getter has always returned true, so leaving the accessor pair around only added noise to the public surface and invited misreading of the API. Soft breaking change: TypeScript users that read or assign `camera.useMovementSystem` will now see a compile error. Runtime behavior is unchanged for plain JS users -- writes silently set an instance property that has no effect (same as before, where the setter no-op'd). Drops the corresponding 'useMovementSystem backward compat' test block in arcRotateCameraMovement.test.ts. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Visualization tests for WebGPU |
|
WebGL2 visualization test reporter: |
…n.js#18461) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
WebGL2 visualization test reporter: |
⚡ Performance Test Results🟢 All performance tests passed — no regressions detected. |
|
Visualization tests for WebGPU |
🟢 Memory Leak Test Results13 passed, 0 leaked out of 13 scenarios 🟢 All memory leak tests passed — no leaks detected. Passed Scenarios (13)
|
Summary
Follow-up to #18379. Makes
InputMapper.setInteractionsmart about the catch-all-mutation footgun raised by @AmoebaChant in the docs PR review (BabylonJS/Documentation#1578).Problem
With #18379 as merged,
setInteractionalways mutated the matched entry'sinteractionin place. If the conditions you supplied were stricter than any existing entry — for example, askingsetInteraction("pointer", { button: 0, modifiers: { ctrl: true } }, "rotate")against the GeospatialCamera default map (which has no ctrl-modified pointer entry) — the call would resolve the catch-all{ button: 0, interaction: "pan" }, mutate it, and silently break unmodified left-drag too.The fix is to detect that the matched entry is broader than the conditions and fall through to
addEntry, inserting a more-specific entry that wins for the requested combo without clobbering the broader one.Changes
InputMapper.setInteraction:addEntryinstead.addEntry._entryIsAtLeastAsSpecificAsConditionsand_modifiersAtLeastAsSpecificimplement the broader-than detection.cameraMovement.test.tscovering: mutate-in-place, modifier-broader add, button-broader add, no-match add, and the less-specific-conditions add path.Backward compatibility
setInteractionagainst an entry that already exists with matching specificity continue to mutate in place. This is the primary case in the existing arc-rotate playgrounds.setInteractionreturningfalseto detect a missed match now always gettrue. The boolean return is preserved for source compatibility, but its semantics change from "found and updated" to "the requested mapping is now in effect" (true is the only outcome since the call now self-heals).Validation
npm run lint:check -w @dev/core: cleannpx vitest run packages/dev/core/test/unit/Cameras: 179/179 passadd a new specific entry when the matched entry is broader (modifier-broader case)reproduces exactly the geospatial scenario AmoebaChant flagged.Companion docs change