Added the events SDL_EVENT_JOYSTICK_UPDATE_COMPLETE and SDL_EVENT_GAMEPAD_UPDATE_COMPLETE

This allows the application to tell when a joystick polling cycle is complete and can process state changes as a single atomic update. It is disabled by default, at least for now.
This commit is contained in:
Sam Lantinga
2023-06-21 13:59:53 -07:00
parent 808d83dd67
commit 4c9fb3e169
5 changed files with 67 additions and 2 deletions

View File

@@ -151,6 +151,7 @@ typedef enum
SDL_EVENT_JOYSTICK_ADDED, /**< A new joystick has been inserted into the system */ SDL_EVENT_JOYSTICK_ADDED, /**< A new joystick has been inserted into the system */
SDL_EVENT_JOYSTICK_REMOVED, /**< An opened joystick has been removed */ SDL_EVENT_JOYSTICK_REMOVED, /**< An opened joystick has been removed */
SDL_EVENT_JOYSTICK_BATTERY_UPDATED, /**< Joystick battery level change */ SDL_EVENT_JOYSTICK_BATTERY_UPDATED, /**< Joystick battery level change */
SDL_EVENT_JOYSTICK_UPDATE_COMPLETE, /**< Joystick update is complete (disabled by default) */
/* Gamepad events */ /* Gamepad events */
SDL_EVENT_GAMEPAD_AXIS_MOTION = 0x650, /**< Gamepad axis motion */ SDL_EVENT_GAMEPAD_AXIS_MOTION = 0x650, /**< Gamepad axis motion */
@@ -163,6 +164,7 @@ typedef enum
SDL_EVENT_GAMEPAD_TOUCHPAD_MOTION, /**< Gamepad touchpad finger was moved */ SDL_EVENT_GAMEPAD_TOUCHPAD_MOTION, /**< Gamepad touchpad finger was moved */
SDL_EVENT_GAMEPAD_TOUCHPAD_UP, /**< Gamepad touchpad finger was lifted */ SDL_EVENT_GAMEPAD_TOUCHPAD_UP, /**< Gamepad touchpad finger was lifted */
SDL_EVENT_GAMEPAD_SENSOR_UPDATE, /**< Gamepad sensor was updated */ SDL_EVENT_GAMEPAD_SENSOR_UPDATE, /**< Gamepad sensor was updated */
SDL_EVENT_GAMEPAD_UPDATE_COMPLETE, /**< Gamepad update is complete (disabled by default) */
/* Touch events */ /* Touch events */
SDL_EVENT_FINGER_DOWN = 0x700, SDL_EVENT_FINGER_DOWN = 0x700,
@@ -398,7 +400,7 @@ typedef struct SDL_JoyButtonEvent
*/ */
typedef struct SDL_JoyDeviceEvent typedef struct SDL_JoyDeviceEvent
{ {
Uint32 type; /**< ::SDL_EVENT_JOYSTICK_ADDED or ::SDL_EVENT_JOYSTICK_REMOVED */ Uint32 type; /**< ::SDL_EVENT_JOYSTICK_ADDED or ::SDL_EVENT_JOYSTICK_REMOVED or ::SDL_EVENT_JOYSTICK_UPDATE_COMPLETE */
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
SDL_JoystickID which; /**< The joystick instance id */ SDL_JoystickID which; /**< The joystick instance id */
} SDL_JoyDeviceEvent; } SDL_JoyDeviceEvent;
@@ -451,7 +453,7 @@ typedef struct SDL_GamepadButtonEvent
*/ */
typedef struct SDL_GamepadDeviceEvent typedef struct SDL_GamepadDeviceEvent
{ {
Uint32 type; /**< ::SDL_EVENT_GAMEPAD_ADDED, ::SDL_EVENT_GAMEPAD_REMOVED, or ::SDL_EVENT_GAMEPAD_REMAPPED */ Uint32 type; /**< ::SDL_EVENT_GAMEPAD_ADDED, ::SDL_EVENT_GAMEPAD_REMOVED, or ::SDL_EVENT_GAMEPAD_REMAPPED or ::SDL_EVENT_GAMEPAD_UPDATE_COMPLETE */
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
SDL_JoystickID which; /**< The joystick instance id */ SDL_JoystickID which; /**< The joystick instance id */
} SDL_GamepadDeviceEvent; } SDL_GamepadDeviceEvent;

View File

@@ -579,6 +579,8 @@ int SDL_StartEventLoop(void)
SDL_SetEventEnabled(SDL_EVENT_DROP_FILE, SDL_FALSE); SDL_SetEventEnabled(SDL_EVENT_DROP_FILE, SDL_FALSE);
SDL_SetEventEnabled(SDL_EVENT_DROP_TEXT, SDL_FALSE); SDL_SetEventEnabled(SDL_EVENT_DROP_TEXT, SDL_FALSE);
#endif #endif
SDL_SetEventEnabled(SDL_EVENT_JOYSTICK_UPDATE_COMPLETE, SDL_FALSE);
SDL_SetEventEnabled(SDL_EVENT_GAMEPAD_UPDATE_COMPLETE, SDL_FALSE);
SDL_EventQ.active = SDL_TRUE; SDL_EventQ.active = SDL_TRUE;
SDL_UnlockMutex(SDL_EventQ.lock); SDL_UnlockMutex(SDL_EventQ.lock);
@@ -1264,6 +1266,29 @@ void SDL_SetEventEnabled(Uint32 type, SDL_bool enabled)
if (enabled != current_state) { if (enabled != current_state) {
if (enabled) { if (enabled) {
SDL_disabled_events[hi]->bits[lo / 32] &= ~(1 << (lo & 31)); SDL_disabled_events[hi]->bits[lo / 32] &= ~(1 << (lo & 31));
/* Gamepad events depend on joystick events */
switch (type) {
case SDL_EVENT_GAMEPAD_ADDED:
SDL_SetEventEnabled(SDL_EVENT_JOYSTICK_ADDED, SDL_TRUE);
break;
case SDL_EVENT_GAMEPAD_REMOVED:
SDL_SetEventEnabled(SDL_EVENT_JOYSTICK_REMOVED, SDL_TRUE);
break;
case SDL_EVENT_GAMEPAD_AXIS_MOTION:
case SDL_EVENT_GAMEPAD_BUTTON_DOWN:
case SDL_EVENT_GAMEPAD_BUTTON_UP:
SDL_SetEventEnabled(SDL_EVENT_JOYSTICK_AXIS_MOTION, SDL_TRUE);
SDL_SetEventEnabled(SDL_EVENT_JOYSTICK_HAT_MOTION, SDL_TRUE);
SDL_SetEventEnabled(SDL_EVENT_JOYSTICK_BUTTON_DOWN, SDL_TRUE);
SDL_SetEventEnabled(SDL_EVENT_JOYSTICK_BUTTON_UP, SDL_TRUE);
break;
case SDL_EVENT_GAMEPAD_UPDATE_COMPLETE:
SDL_SetEventEnabled(SDL_EVENT_JOYSTICK_UPDATE_COMPLETE, SDL_TRUE);
break;
default:
break;
}
} else { } else {
/* Disable this event type and discard pending events */ /* Disable this event type and discard pending events */
if (!SDL_disabled_events[hi]) { if (!SDL_disabled_events[hi]) {

View File

@@ -392,6 +392,22 @@ static int SDLCALL SDL_GamepadEventWatcher(void *userdata, SDL_Event *event)
SDL_PushEvent(&deviceevent); SDL_PushEvent(&deviceevent);
} }
} break; } break;
case SDL_EVENT_JOYSTICK_UPDATE_COMPLETE:
{
SDL_AssertJoysticksLocked();
for (gamepad = SDL_gamepads; gamepad; gamepad = gamepad->next) {
if (gamepad->joystick->instance_id == event->jdevice.which) {
SDL_Event deviceevent;
deviceevent.type = SDL_EVENT_GAMEPAD_UPDATE_COMPLETE;
deviceevent.common.timestamp = event->jdevice.timestamp;
deviceevent.gdevice.which = event->jdevice.which;
SDL_PushEvent(&deviceevent);
break;
}
}
} break;
default: default:
break; break;
} }

View File

@@ -1753,6 +1753,7 @@ int SDL_SendJoystickAxis(Uint64 timestamp, SDL_Joystick *joystick, Uint8 axis, S
/* Update internal joystick state */ /* Update internal joystick state */
info->value = value; info->value = value;
joystick->update_complete = timestamp;
/* Post the event, if desired */ /* Post the event, if desired */
posted = 0; posted = 0;
@@ -1795,6 +1796,7 @@ int SDL_SendJoystickHat(Uint64 timestamp, SDL_Joystick *joystick, Uint8 hat, Uin
/* Update internal joystick state */ /* Update internal joystick state */
joystick->hats[hat] = value; joystick->hats[hat] = value;
joystick->update_complete = timestamp;
/* Post the event, if desired */ /* Post the event, if desired */
posted = 0; posted = 0;
@@ -1853,6 +1855,7 @@ int SDL_SendJoystickButton(Uint64 timestamp, SDL_Joystick *joystick, Uint8 butto
/* Update internal joystick state */ /* Update internal joystick state */
joystick->buttons[button] = state; joystick->buttons[button] = state;
joystick->update_complete = timestamp;
/* Post the event, if desired */ /* Post the event, if desired */
posted = 0; posted = 0;
@@ -1913,6 +1916,21 @@ void SDL_UpdateJoysticks(void)
} }
} }
if (SDL_EventEnabled(SDL_EVENT_JOYSTICK_UPDATE_COMPLETE)) {
for (joystick = SDL_joysticks; joystick; joystick = joystick->next) {
if (joystick->update_complete) {
SDL_Event event;
event.type = SDL_EVENT_JOYSTICK_UPDATE_COMPLETE;
event.common.timestamp = joystick->update_complete;
event.gdevice.which = joystick->instance_id;
SDL_PushEvent(&event);
joystick->update_complete = 0;
}
}
}
/* this needs to happen AFTER walking the joystick list above, so that any /* this needs to happen AFTER walking the joystick list above, so that any
dangling hardware data from removed devices can be free'd dangling hardware data from removed devices can be free'd
*/ */
@@ -3178,6 +3196,7 @@ int SDL_SendJoystickTouchpad(Uint64 timestamp, SDL_Joystick *joystick, int touch
finger_info->x = x; finger_info->x = x;
finger_info->y = y; finger_info->y = y;
finger_info->pressure = pressure; finger_info->pressure = pressure;
joystick->update_complete = timestamp;
/* Post the event, if desired */ /* Post the event, if desired */
posted = 0; posted = 0;
@@ -3219,6 +3238,7 @@ int SDL_SendJoystickSensor(Uint64 timestamp, SDL_Joystick *joystick, SDL_SensorT
/* Update internal sensor state */ /* Update internal sensor state */
SDL_memcpy(sensor->data, data, num_values * sizeof(*data)); SDL_memcpy(sensor->data, data, num_values * sizeof(*data));
joystick->update_complete = timestamp;
/* Post the event, if desired */ /* Post the event, if desired */
#ifndef SDL_EVENTS_DISABLED #ifndef SDL_EVENTS_DISABLED

View File

@@ -119,6 +119,8 @@ struct SDL_Joystick
SDL_Sensor *gyro _guarded; SDL_Sensor *gyro _guarded;
float sensor_transform[3][3] _guarded; float sensor_transform[3][3] _guarded;
Uint64 update_complete _guarded;
struct SDL_JoystickDriver *driver _guarded; struct SDL_JoystickDriver *driver _guarded;
struct joystick_hwdata *hwdata _guarded; /* Driver dependent information */ struct joystick_hwdata *hwdata _guarded; /* Driver dependent information */