-
Notifications
You must be signed in to change notification settings - Fork 1.2k
run_forever cannot bulk process events, unable to empty event queue #276
Description
In a program that uses poll_events in an infinite loop, poll_events will process events until the event queue is empty. If multiple events are enqueued while the program is rendering, the program can process each of them before beginning the relatively expensive task of rendering the next frame.
With run_forever though, this sort of "bulk event processing" cannot happen. The callback does not know if more events are in the queue, so it must unconditionally render a frame to the user. But while rendering a frame, more events can be enqueued. If rendering takes too long, the input queue becomes filled with events, and the run_forever callback cannot process them fast enough as it has to process older events first.
This severely affects interactivity; the program appears to the user that the program is constantly "catching up" with what the user did seconds ago (this is particularly noticeable when moving the mouse, which causes many events).
There are a couple workarounds to this issue. The obvious one is to use poll_events instead. However, if the program only needs to re-render in response to user input (common in editors), rendering all of the time wastes CPU and power.
A more complicated workaround is to have the event loop forward all of its events to the program's own queue (such as std::sync::mpsc), which can implement a "check if empty function". This introduces complexity in the program, though, and it would be better if winit had a simpler interface.
The API described in #231 would solve this issue. The program can call get_event with a short timeout until no events are left, then render the frame and call get_event with an infinite timeout.