mirror of
https://github.com/MCKero6423/uv-k5-v3-emulator.git
synced 2026-10-03 19:47:22 +00:00
One thread grabs the LCD at a fixed rate into a shared buffer; HTTP clients serve from that buffer. Before, every /stream iteration issued its own QMP reads, so load scaled with client count and reconnects, and a slow reader could stall the grab loop. Encodes only when the framebuffer bytes change, and exposes generation so a client can tell a new frame from the same one without comparing bytes. rebind() is here for the power work in a later task: the emulator comes and goes under the server, and rebind(None) blanks the screen instead of leaving a stale frame that looks live. The run loop re-checks the grabber identity under the lock after a read, so a rebind landing mid-read cannot be undone by the frame it was already fetching. A client that raises is swallowed on purpose -- a dead emulator must not kill the pump, since power may come back. Verified against a real emulator: 5000 latest() calls in 1 ms with no QMP traffic, generation flat at 1 over a second of static screen, guest still running, and rebind(None) going dark. 9 unit tests.