perf(window): block message loop while paused on Win32 (#134) #152

Merged
catbot merged 1 commit from claude/issue-134 into master 2026-06-18 16:01:28 +02:00
Member

Problem

In StartSync() (implementations/Crafter.Graphics-Window.cpp), when updating is false (paused / minimized / stopped) the FIFO present no longer paces the loop, so the bare PeekMessage(PM_REMOVE) spin pins a core at 100% while uselessly re-running Gamepad::Tick() (mutex + per-pad GetCurrentReading COM call) and onBeforeUpdate every iteration.

Fix

Block on MsgWaitForMultipleObjectsEx with a short (~16ms) timeout while !updating. The loop wakes on input or after the timeout, eliminating the busy-spin while preserving gamepad polling / onBeforeUpdate at a sane rate (e.g. to detect a controller button asking to resume). The updating path is untouched — present remains vsync-gated, so per-frame polling stays correctly vsync-gated.

Testing

  • crafter-build test — 24/24 pass on the Linux/Wayland build (which compiles Crafter.Graphics-Window.cpp).
  • The changed Win32 snippet syntax-checks cleanly against mingw's windows.h (MsgWaitForMultipleObjectsEx, QS_ALLINPUT, MWMO_INPUTAVAILABLE). A full Windows cross-compile is blocked by a pre-existing mingw WinRT header issue in Crafter.Graphics-Gamepad.cpp, unrelated to this change.

Resolves #134

🤖 Generated with Claude Code

## Problem In `StartSync()` (`implementations/Crafter.Graphics-Window.cpp`), when `updating` is false (paused / minimized / stopped) the FIFO present no longer paces the loop, so the bare `PeekMessage(PM_REMOVE)` spin pins a core at 100% while uselessly re-running `Gamepad::Tick()` (mutex + per-pad `GetCurrentReading` COM call) and `onBeforeUpdate` every iteration. ## Fix Block on `MsgWaitForMultipleObjectsEx` with a short (~16ms) timeout while `!updating`. The loop wakes on input or after the timeout, eliminating the busy-spin while preserving gamepad polling / `onBeforeUpdate` at a sane rate (e.g. to detect a controller button asking to resume). The `updating` path is untouched — present remains vsync-gated, so per-frame polling stays correctly vsync-gated. ## Testing - `crafter-build test` — 24/24 pass on the Linux/Wayland build (which compiles `Crafter.Graphics-Window.cpp`). - The changed Win32 snippet syntax-checks cleanly against mingw's `windows.h` (`MsgWaitForMultipleObjectsEx`, `QS_ALLINPUT`, `MWMO_INPUTAVAILABLE`). A full Windows cross-compile is blocked by a pre-existing mingw WinRT header issue in `Crafter.Graphics-Gamepad.cpp`, unrelated to this change. Resolves #134 🤖 Generated with [Claude Code](https://claude.com/claude-code)
When `updating` is false (paused / minimized / stopped), the FIFO
present no longer paces StartSync()'s message loop, so the bare
PeekMessage(PM_REMOVE) spin pinned a core at 100% while uselessly
re-running Gamepad::Tick() (mutex + per-pad COM reads) and
onBeforeUpdate every iteration.

Block on MsgWaitForMultipleObjectsEx with a short timeout while
!updating: the loop now wakes on input or every ~16ms, eliminating the
busy-spin while preserving gamepad polling / onBeforeUpdate at a sane
rate (e.g. to detect a controller button asking to resume). The
updating path is unchanged — present remains vsync-gated.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
catbot merged commit 7720f0a9bc into master 2026-06-18 16:01:28 +02:00
catbot deleted branch claude/issue-134 2026-06-18 16:01:29 +02:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Catcrafts/Crafter.Graphics!152
No description provided.