Skip to content

fix(input): clear PointerEventReceiver events independently of PointerSystem (#3356)#3781

Open
MohammadYusif wants to merge 1 commit into
excaliburjs:mainfrom
MohammadYusif:fix/issue-3356
Open

fix(input): clear PointerEventReceiver events independently of PointerSystem (#3356)#3781
MohammadYusif wants to merge 1 commit into
excaliburjs:mainfrom
MohammadYusif:fix/issue-3356

Conversation

@MohammadYusif

Copy link
Copy Markdown

===:clipboard: PR Checklist :clipboard:===

  • 📌 issue exists in github for these changes (PointerEventReceiver memory leak #3356)
  • 🔬 existing tests still pass
  • 🙈 code conforms to the style guide
  • 📐 new tests written and passing / old tests updated with new scenario(s)
  • 📄 changelog entry added (or not needed)

==================

Closes #3356

Changes:

PointerEventReceiver accumulates native pointer events in its currentFrameDown / currentFrameUp / currentFrameMove / currentFrameCancel / currentFrameWheel arrays. Those arrays were only ever consumed (update()) and freed (clear()) by PointerSystem.update() each frame. If a scene removes the PointerSystem (e.g. world.remove(world.get(PointerSystem))), nothing flushes those arrays, so they grow without bound on every native pointer event — a memory leak (as noted by @eonarheim, pointer flushing should not depend on the system being present).

  • src/engine/input/input-host.ts: InputHost.update() (which runs every frame for both the engine-level and scene-level input hosts) now guarantees the pointer receiver is flushed exactly once per frame, independent of the PointerSystem. If the receiver was already processed by the system this frame, it just resets the marker; otherwise it calls update() + clear() itself.
  • src/engine/input/pointer-system.ts: after the system updates/clears each receiver it marks receiver._processedThisFrame = true so the InputHost fallback does not double-process (and therefore never double-emits raw pointer events) when a PointerSystem is active.
  • src/engine/input/pointer-event-receiver.ts: added the internal _processedThisFrame flag used to coordinate the two.
  • src/spec/vitest/pointer-input-spec.ts: added a regression test that removes the PointerSystem from the scene, dispatches several pointer events across multiple frames, and asserts the receiver's currentFrame* arrays stay empty.
  • CHANGELOG.md: added a Fixed entry.

Note: the project's browser-mode (Playwright/Chromium) test runner could not launch a browser in my local sandbox (browserType.launch: spawn UNKNOWN), so the suite was validated via tsc on the engine sources; the new spec follows the existing patterns in the same file and should run normally in CI.

…rSystem (excaliburjs#3356)

The PointerEventReceiver accumulates native pointer events in its
currentFrame* arrays. These were only ever updated and cleared by
PointerSystem.update() each frame. If a scene removed the PointerSystem
(e.g. world.remove(world.get(PointerSystem))), nothing flushed those
arrays, so they grew without bound on every pointer event - a memory
leak.

The InputHost now guarantees the receiver is flushed exactly once per
frame regardless of whether a PointerSystem is active: the PointerSystem
marks each receiver it processes, and the InputHost flushes any receiver
that wasn't processed. This avoids double-emitting raw pointer events
when the system is present while preventing the leak when it is absent.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

PointerEventReceiver memory leak

1 participant