New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improved SDL_PollEvent usage #4794
Conversation
I've just tested your commits on Should I keep my PR open as to discuss the remaining mouse move squishing changes? |
Not too sure. I assume you can still end up with multiple (but not many) |
c48f0f0
to
5317182
Compare
if (timeout == 0 && event && event->type == SDL_POLLSENTINEL) { | ||
return 0; | ||
return SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT) == 1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After searching through GitHub for uses of SDL_PollEvent
, there is an alarming amount of strange/incorrect usage (mostly in beginner projects), such as:
- Only calling it once per frame
- Not checking the return value
- Calling
SDL_PollEvent(NULL)
in a loop - Polling until a certain event (i.e a key press), and pushing the rest back into the queue
I'd say those first 3 issues are broken by design, but the last one (and similar uses of user-added events inside a poll cycle) could be an issue, so I decided it's better to err on the side of caution and ignore the sentinel if there are still more events in the queue.
This demonstrates why Btw for anyone reading I recommend to use the better designed and more performant #define SIZE_EVENTS 64
SDL_Event events[SIZE_EVENTS];
while (1) { // main game loop
SDL_PumpEvents();
int eventCount;
do {
eventCount = SDL_PeepEvents(&events[0], SIZE_EVENTS, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT);
for (int i = 0; i < eventCount; ++i) {
switch (events[i].type) {
/* handle event */
}
}
} while (eventCount == SIZE_EVENTS);
} |
You should always call SDL_PumpEvents() at least once through the function, otherwise you might starve the OS events if there's another thread pushing events onto the queue. |
SDL_PumpEvents will still be called at least once per cycle (where a cycle is calling SDL_PollEvent in a loop it returns false). More specifically, it will be called when there are no events left in the SDL queue. The difference is that if SDL_PumpEvents then produces any new events, an extra sentinel event is also added. When that sentinel event is reached there are two possibilities: |
As recommended in libsdl-org/SDL#4794 (comment). Note that the linked PR itself will also fix this without any changes our side, but we will still get some extra efficiency by refactoring how we are processing events regardless. Should help with high poll rate input devices to some degree.
This reverts commit 8bf32e1.
pollEvents was apparently broken by a recent-ish [patch](libsdl-org/SDL#4794) to SDL. This should fix that. As an aside, this attempts to make polling events a bit more efficient; We just statically allocate a single buffer for events (AFAIK you can only call Poll from the main thread anyway, so the fact that this isn't thread safe shouldn't be an issue).
pollEvents was apparently broken by a recent-ish [patch](libsdl-org/SDL#4794) to SDL. This should fix that. As an aside, this attempts to make polling events a bit more efficient; We just statically allocate a single buffer for events (AFAIK you can only call Poll from the main thread anyway, so the fact that this isn't thread safe shouldn't be an issue).
pollEvents was apparently broken by a recent-ish [patch](libsdl-org/SDL#4794) to SDL. This should fix that. As an aside, this attempts to make polling events a bit more efficient; We just statically allocate a single buffer for events (AFAIK you can only call Poll from the main thread anyway, so the fact that this isn't thread safe shouldn't be an issue).
pollEvents was apparently broken by a recent-ish [patch](libsdl-org/SDL#4794) to SDL. This should fix that. As an aside, this attempts to make polling events a bit more efficient; We just statically allocate a single buffer for events (AFAIK you can only call Poll from the main thread anyway, so the fact that this isn't thread safe shouldn't be an issue).
pollEvents was apparently broken by a recent-ish [patch](libsdl-org/SDL#4794) to SDL. This should fix that. As an aside, this attempts to make polling events a bit more efficient; We just statically allocate a single buffer for events (AFAIK you can only call Poll from the main thread anyway, so the fact that this isn't thread safe shouldn't be an issue).
pollEvents was apparently broken by a recent-ish [patch](libsdl-org/SDL#4794) to SDL. This should fix that. As an aside, this attempts to make polling events a bit more efficient; We just statically allocate a single buffer for events (AFAIK you can only call Poll from the main thread anyway, so the fact that this isn't thread safe shouldn't be an issue).
pollEvents was apparently broken by a recent-ish [patch](libsdl-org/SDL#4794) to SDL. This should fix that. As an aside, this attempts to make polling events a bit more efficient; We just statically allocate a single buffer for events (AFAIK you can only call Poll from the main thread anyway, so the fact that this isn't thread safe shouldn't be an issue).
This PR changes the behaviour of
SDL_WaitEventTimeout
(used bySDL_PollEvent
) to reduce overhead, and avoid infinite loops.Description
Currently when polling for events you can end up in an infinite loop. There are two main reasons for this:
SDL_WaitEventTimeout
unconditionally callsSDL_PumpEvents
, even if there are already events available.SDL_WaitEventTimeout
has no understanding of a poll cycle.To fix this, there are two main changes:
SDL_PumpEvents
unless the event queue is actually empty.Alternatives
Unfortunately both of these changes could alter the behaviour of existing applications, so the following changes may be needed:
timeout == 0
.Existing Issue(s)
#4792 and #4376 describe the problems with the current event-poll cycle, though I felt part of #4792's approach is sub-optimal.