Skip to content
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

Merged
merged 7 commits into from Oct 15, 2021
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions include/SDL_events.h
Expand Up @@ -87,6 +87,8 @@ typedef enum

SDL_LOCALECHANGED, /**< The user's locale preferences have changed. */

SDL_POLLSENTINEL, /**< Signals the end of an event poll cycle */
flibitijibibo marked this conversation as resolved.
Show resolved Hide resolved

/* Display events */
SDL_DISPLAYEVENT = 0x150, /**< Display state change */

Expand Down
16 changes: 16 additions & 0 deletions include/SDL_hints.h
Expand Up @@ -958,6 +958,22 @@ extern "C" {
*/
#define SDL_HINT_ORIENTATIONS "SDL_IOS_ORIENTATIONS"

/**
* \brief A variable controlling the use of a sentinel event when polling the event queue
*
* This variable can be set to the following values:
* "0" - Disable poll sentinels
* "1" - Enable poll sentinels
*
* When polling for events, SDL_PumpEvents is used to gather new events from devices.
* If a device keeps producing new events between calls to SDL_PumpEvents, a poll loop will
* become stuck until the new events stop.
* This is most noticable when moving a high frequency mouse.
*
* By default, poll sentinels are enabled.
*/
#define SDL_HINT_POLL_SENTINEL "SDL_POLL_SENTINEL"

/**
* \brief Override for SDL_GetPreferredLocales()
*
Expand Down
28 changes: 28 additions & 0 deletions src/events/SDL_events.c
Expand Up @@ -26,6 +26,7 @@
#include "SDL_events.h"
#include "SDL_thread.h"
#include "SDL_events_c.h"
#include "../SDL_hints_c.h"
#include "../timer/SDL_timer_c.h"
#if !SDL_JOYSTICK_DISABLED
#include "../joystick/SDL_joystick_c.h"
Expand Down Expand Up @@ -139,6 +140,11 @@ SDL_AutoUpdateSensorsChanged(void *userdata, const char *name, const char *oldVa

#endif /* !SDL_SENSOR_DISABLED */

static void SDLCALL
SDL_PollSentinelChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
{
SDL_EventState(SDL_POLLSENTINEL, SDL_GetStringBoolean(hint, SDL_TRUE) ? SDL_ENABLE : SDL_DISABLE);
}

/* 0 (default) means no logging, 1 means logging, 2 means logging with mouse and finger motion */
static int SDL_DoEventLogging = 0;
Expand Down Expand Up @@ -874,6 +880,21 @@ SDL_WaitEventTimeout(SDL_Event * event, int timeout)
SDL_Window *wakeup_window;
Uint32 expiration = 0;

/* First check for existing events */
switch (SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT)) {
case -1:
return 0;
case 0:
break;
default:
/* Check whether we have reached the end of the poll cycle */
if (timeout == 0 && event && event->type == SDL_POLLSENTINEL) {
return 0;
}
/* Has existing events */
return 1;
}

if (timeout > 0)
expiration = SDL_GetTicks() + timeout;

Expand Down Expand Up @@ -908,6 +929,11 @@ SDL_WaitEventTimeout(SDL_Event * event, int timeout)
SDL_Delay(1);
break;
default:
if (timeout == 0) {
/* We are at the start of a poll cycle with at least one new event.
Add a sentinel event to mark the end of the cycle. */
SDL_SendAppEvent(SDL_POLLSENTINEL);
}
/* Has events */
return 1;
}
Expand Down Expand Up @@ -1202,6 +1228,7 @@ SDL_EventsInit(void)
SDL_AddHintCallback(SDL_HINT_AUTO_UPDATE_SENSORS, SDL_AutoUpdateSensorsChanged, NULL);
#endif
SDL_AddHintCallback(SDL_HINT_EVENT_LOGGING, SDL_EventLoggingChanged, NULL);
SDL_AddHintCallback(SDL_HINT_POLL_SENTINEL, SDL_PollSentinelChanged, NULL);
if (SDL_StartEventLoop() < 0) {
SDL_DelHintCallback(SDL_HINT_EVENT_LOGGING, SDL_EventLoggingChanged, NULL);
return -1;
Expand All @@ -1217,6 +1244,7 @@ SDL_EventsQuit(void)
{
SDL_QuitQuit();
SDL_StopEventLoop();
SDL_DelHintCallback(SDL_HINT_POLL_SENTINEL, SDL_PollSentinelChanged, NULL);
SDL_DelHintCallback(SDL_HINT_EVENT_LOGGING, SDL_EventLoggingChanged, NULL);
#if !SDL_JOYSTICK_DISABLED
SDL_DelHintCallback(SDL_HINT_AUTO_UPDATE_JOYSTICKS, SDL_AutoUpdateJoysticksChanged, NULL);
Expand Down