Просмотр исходного кода

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.
Sam Lantinga 2 лет назад
Родитель
Сommit
4c9fb3e169

+ 4 - 2
include/SDL3/SDL_events.h

@@ -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;

+ 25 - 0
src/events/SDL_events.c

@@ -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]) {

+ 16 - 0
src/joystick/SDL_gamepad.c

@@ -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;
     }
     }

+ 20 - 0
src/joystick/SDL_joystick.c

@@ -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

+ 2 - 0
src/joystick/SDL_sysjoystick.h

@@ -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 */