Skip to content

Commit

Permalink
Automatically clean up memory associated with events
Browse files Browse the repository at this point in the history
  • Loading branch information
slouken committed Nov 5, 2023
1 parent 9302d77 commit a298e0d
Show file tree
Hide file tree
Showing 16 changed files with 152 additions and 148 deletions.
5 changes: 2 additions & 3 deletions docs/README-main-functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -175,9 +175,8 @@ int SDL_AppEvent(const SDL_Event *event);
```
This will be called whenever an SDL event arrives, on the thread that runs
SDL_AppIterate. You should not call SDL_CleanupEvent() on the provided
event, and your app should also not call SDL_PollEvent, SDL_PumpEvent, etc,
as SDL will manage all this for you. Return values are the same as from
SDL_AppIterate. Your app should also not call SDL_PollEvent, SDL_PumpEvent,
etc, as SDL will manage all this for you. Return values are the same as from
SDL_AppIterate(), so you can terminate in response to SDL_EVENT_QUIT, etc.
Expand Down
4 changes: 2 additions & 2 deletions docs/README-migration.md
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ The timestamp_us member of the sensor events has been renamed sensor_timestamp a
You should set the event.common.timestamp field before passing an event to SDL_PushEvent(). If the timestamp is 0 it will be filled in with SDL_GetTicksNS().
You should call SDL_CleanupEvent() after handling SDL_EVENT_DROP_FILE, SDL_EVENT_DROP_TEXT, SDL_EVENT_SYSWM, SDL_EVENT_TEXT_EDITING, and SDL_EVENT_TEXT_INPUT. This cleans up the memory associated with those events, and you no longer have to free the data yourself.
You should not call SDL_free() on the data in SDL_EVENT_DROP_FILE, SDL manages the memory for events internally, you no longer have to free the data yourself.
Mouse events use floating point values for mouse coordinates and relative motion values. You can get sub-pixel motion depending on the platform and display scaling.
Expand Down Expand Up @@ -559,7 +559,7 @@ The following hints have been removed:
* SDL_HINT_VIDEO_X11_FORCE_EGL - use SDL_HINT_VIDEO_FORCE_EGL instead
* SDL_HINT_VIDEO_X11_XINERAMA - Xinerama no longer supported by the X11 backend
* SDL_HINT_VIDEO_X11_XVIDMODE - Xvidmode no longer supported by the X11 backend
* SDL_HINT_IME_SUPPORT_EXTENDED_TEXT - the normal text editing event has dynamically allocated text if needed, and should be freed with SDL_CleanupEvent() when processed
* SDL_HINT_IME_SUPPORT_EXTENDED_TEXT - the normal text editing event has extended text

* Renamed hints SDL_HINT_VIDEODRIVER and SDL_HINT_AUDIODRIVER to SDL_HINT_VIDEO_DRIVER and SDL_HINT_AUDIO_DRIVER
* Renamed environment variables SDL_VIDEODRIVER and SDL_AUDIODRIVER to SDL_VIDEO_DRIVER and SDL_AUDIO_DRIVER
Expand Down
86 changes: 33 additions & 53 deletions include/SDL3/SDL_events.h
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ typedef struct SDL_WindowEvent
{
Uint32 type; /**< ::SDL_WINDOWEVENT_* */
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
SDL_WindowID windowID;/**< The associated window */
SDL_WindowID windowID; /**< The associated window */
Sint32 data1; /**< event dependent data */
Sint32 data2; /**< event dependent data */
} SDL_WindowEvent;
Expand All @@ -248,7 +248,7 @@ typedef struct SDL_KeyboardEvent
{
Uint32 type; /**< ::SDL_EVENT_KEY_DOWN or ::SDL_EVENT_KEY_UP */
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
SDL_WindowID windowID;/**< The window with keyboard focus, if any */
SDL_WindowID windowID; /**< The window with keyboard focus, if any */
Uint8 state; /**< ::SDL_PRESSED or ::SDL_RELEASED */
Uint8 repeat; /**< Non-zero if this is a key repeat */
Uint8 padding2;
Expand All @@ -259,33 +259,27 @@ typedef struct SDL_KeyboardEvent
#define SDL_TEXTEDITINGEVENT_TEXT_SIZE 64
/**
* \brief Keyboard text editing event structure (event.edit.*)
*
* \note This event should be cleaned up with SDL_CleanupEvent() after processing.
*/
typedef struct SDL_TextEditingEvent
{
Uint32 type; /**< ::SDL_EVENT_TEXT_EDITING */
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
SDL_WindowID windowID; /**< The window with keyboard focus, if any */
char *text; /**< The editing text */
char short_text[SDL_TEXTEDITINGEVENT_TEXT_SIZE]; /**< Memory space for short editing text, use 'text' instead */
Sint32 start; /**< The start cursor of selected editing text */
Sint32 length; /**< The length of selected editing text */
Uint32 type; /**< ::SDL_EVENT_TEXT_EDITING */
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
SDL_WindowID windowID; /**< The window with keyboard focus, if any */
char *text; /**< The editing text */
Sint32 start; /**< The start cursor of selected editing text */
Sint32 length; /**< The length of selected editing text */
} SDL_TextEditingEvent;

#define SDL_TEXTINPUTEVENT_TEXT_SIZE 64
/**
* \brief Keyboard text input event structure (event.text.*)
*
* \note This event should be cleaned up with SDL_CleanupEvent() after processing.
*/
typedef struct SDL_TextInputEvent
{
Uint32 type; /**< ::SDL_EVENT_TEXT_INPUT */
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
SDL_WindowID windowID; /**< The window with keyboard focus, if any */
char *text; /**< The input text */
char short_text[SDL_TEXTEDITINGEVENT_TEXT_SIZE]; /**< Memory space for short input text, use 'text' instead */
Uint32 type; /**< ::SDL_EVENT_TEXT_INPUT */
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
SDL_WindowID windowID; /**< The window with keyboard focus, if any */
char *text; /**< The input text */
} SDL_TextInputEvent;

/**
Expand All @@ -295,7 +289,7 @@ typedef struct SDL_MouseMotionEvent
{
Uint32 type; /**< ::SDL_EVENT_MOUSE_MOTION */
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
SDL_WindowID windowID;/**< The window with mouse focus, if any */
SDL_WindowID windowID; /**< The window with mouse focus, if any */
SDL_MouseID which; /**< The mouse instance id, or SDL_TOUCH_MOUSEID */
Uint32 state; /**< The current button state */
float x; /**< X coordinate, relative to window */
Expand All @@ -311,7 +305,7 @@ typedef struct SDL_MouseButtonEvent
{
Uint32 type; /**< ::SDL_EVENT_MOUSE_BUTTON_DOWN or ::SDL_EVENT_MOUSE_BUTTON_UP */
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
SDL_WindowID windowID;/**< The window with mouse focus, if any */
SDL_WindowID windowID; /**< The window with mouse focus, if any */
SDL_MouseID which; /**< The mouse instance id, or SDL_TOUCH_MOUSEID */
Uint8 button; /**< The mouse button index */
Uint8 state; /**< ::SDL_PRESSED or ::SDL_RELEASED */
Expand All @@ -328,7 +322,7 @@ typedef struct SDL_MouseWheelEvent
{
Uint32 type; /**< ::SDL_EVENT_MOUSE_WHEEL */
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
SDL_WindowID windowID;/**< The window with mouse focus, if any */
SDL_WindowID windowID; /**< The window with mouse focus, if any */
SDL_MouseID which; /**< The mouse instance id, or SDL_TOUCH_MOUSEID */
float x; /**< The amount scrolled horizontally, positive to the right and negative to the left */
float y; /**< The amount scrolled vertically, positive away from the user and negative toward the user */
Expand Down Expand Up @@ -507,15 +501,13 @@ typedef struct SDL_TouchFingerEvent
float dx; /**< Normalized in the range -1...1 */
float dy; /**< Normalized in the range -1...1 */
float pressure; /**< Normalized in the range 0...1 */
SDL_WindowID windowID;/**< The window underneath the finger, if any */
SDL_WindowID windowID; /**< The window underneath the finger, if any */
} SDL_TouchFingerEvent;


#define SDL_DROPEVENT_DATA_SIZE 64
/**
* \brief An event used to drop text or request a file open by the system (event.drop.*)
*
* \note This event should be cleaned up with SDL_CleanupEvent() after processing.
*/
typedef struct SDL_DropEvent
{
Expand All @@ -526,7 +518,6 @@ typedef struct SDL_DropEvent
float y; /**< Y coordinate, relative to window (not on begin) */
char *source; /**< The source app that sent this drop event, or NULL if that isn't available */
char *data; /**< The text for SDL_EVENT_DROP_TEXT and the file name for SDL_EVENT_DROP_FILE, NULL for other events */
char short_data[SDL_DROPEVENT_DATA_SIZE]; /**< Memory space for short data, use 'data' instead */
} SDL_DropEvent;

/**
Expand All @@ -545,7 +536,7 @@ typedef struct SDL_SensorEvent
{
Uint32 type; /**< ::SDL_EVENT_SENSOR_UPDATE */
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
SDL_SensorID which; /**< The instance ID of the sensor */
SDL_SensorID which; /**< The instance ID of the sensor */
float data[6]; /**< Up to 6 values from the sensor - additional values can be queried using SDL_GetSensorData() */
Uint64 sensor_timestamp; /**< The timestamp of the sensor reading in nanoseconds, not necessarily synchronized with the system clock */
} SDL_SensorEvent;
Expand Down Expand Up @@ -575,7 +566,7 @@ typedef struct SDL_UserEvent
{
Uint32 type; /**< ::SDL_EVENT_USER through ::SDL_EVENT_LAST-1 */
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
SDL_WindowID windowID;/**< The associated window if any */
SDL_WindowID windowID; /**< The associated window if any */
Sint32 code; /**< User defined event code */
void *data1; /**< User defined data pointer */
void *data2; /**< User defined data pointer */
Expand All @@ -589,8 +580,6 @@ typedef struct SDL_SysWMmsg SDL_SysWMmsg;
* \brief A video driver dependent system event (event.syswm.*)
* This event is disabled by default, you can enable it with SDL_SetEventEnabled()
*
* \note This event should be cleaned up with SDL_CleanupEvent() after processing.
*
* \note If you want to use this event, you should include SDL_syswm.h.
*/
typedef struct SDL_SysWMEvent
Expand Down Expand Up @@ -641,7 +630,7 @@ typedef union SDL_Event
largest datatype within the union, which is 8 bytes on 64-bit
architectures.
So... we'll add padding to force the size to be 56 bytes for both.
So... we'll add padding to force the size to be the same for both.
On architectures where pointers are 16 bytes, this needs rounding up to
the next multiple of 16, 64, and on architectures where pointers are
Expand Down Expand Up @@ -850,7 +839,6 @@ extern DECLSPEC void SDLCALL SDL_FlushEvents(Uint32 minType, Uint32 maxType);
*
* \since This function is available since SDL 3.0.0.
*
* \sa SDL_CleanupEvent
* \sa SDL_PushEvent
* \sa SDL_WaitEvent
* \sa SDL_WaitEventTimeout
Expand All @@ -873,7 +861,6 @@ extern DECLSPEC SDL_bool SDLCALL SDL_PollEvent(SDL_Event *event);
*
* \since This function is available since SDL 3.0.0.
*
* \sa SDL_CleanupEvent
* \sa SDL_PollEvent
* \sa SDL_PushEvent
* \sa SDL_WaitEventTimeout
Expand Down Expand Up @@ -902,33 +889,12 @@ extern DECLSPEC SDL_bool SDLCALL SDL_WaitEvent(SDL_Event *event);
*
* \since This function is available since SDL 3.0.0.
*
* \sa SDL_CleanupEvent
* \sa SDL_PollEvent
* \sa SDL_PushEvent
* \sa SDL_WaitEvent
*/
extern DECLSPEC SDL_bool SDLCALL SDL_WaitEventTimeout(SDL_Event *event, Sint32 timeoutMS);

/**
* Clean up dynamically allocated memory for an event.
*
* Some events have dynamically allocated data that must be cleaned up when
* the event is processed. If you handle any of these events, you should call
* SDL_CleanupEvent() after processing them: SDL_EVENT_DROP_FILE
* SDL_EVENT_DROP_TEXT SDL_EVENT_SYSWM SDL_EVENT_TEXT_EDITING
*
* It is safe, but not necessary, to call this function for other event types.
*
* \param event a pointer to the event that should be cleaned up
*
* \since This function is available since SDL 3.0.0.
*
* \sa SDL_PollEvent
* \sa SDL_WaitEvent
* \sa SDL_WaitEventTimeout
*/
extern DECLSPEC void SDLCALL SDL_CleanupEvent(SDL_Event *event);

/**
* Add an event to the event queue.
*
Expand Down Expand Up @@ -1145,6 +1111,20 @@ extern DECLSPEC SDL_bool SDLCALL SDL_EventEnabled(Uint32 type);
*/
extern DECLSPEC Uint32 SDLCALL SDL_RegisterEvents(int numevents);

/**
* Allocate dynamic memory for an SDL event
*
* You can use this to allocate memory for user events that will be automatically freed after the event is processed.
*
* \param size the amount of memory to allocate
* \returns a pointer to the memory allocated or NULL on failure; call SDL_GetError() for more information.
*
* \since This function is available since SDL 3.0.0.
*
* \sa SDL_FlushEventMemory
*/
extern DECLSPEC void * SDLCALL SDL_AllocateEventMemory(size_t size);

/* Ends C function definitions when using C++ */
#ifdef __cplusplus
}
Expand Down
2 changes: 1 addition & 1 deletion src/dynapi/SDL_dynapi.sym
Original file line number Diff line number Diff line change
Expand Up @@ -921,9 +921,9 @@ SDL3_0.0.0 {
SDL_GetWindowProperties;
SDL_ClearProperty;
SDL_EnterAppMainCallbacks;
SDL_CleanupEvent;
SDL_RWprintf;
SDL_RWvprintf;
SDL_AllocateEventMemory;
# extra symbols go here (don't modify this line)
local: *;
};
2 changes: 1 addition & 1 deletion src/dynapi/SDL_dynapi_overrides.h
Original file line number Diff line number Diff line change
Expand Up @@ -946,6 +946,6 @@
#define SDL_GetWindowProperties SDL_GetWindowProperties_REAL
#define SDL_ClearProperty SDL_ClearProperty_REAL
#define SDL_EnterAppMainCallbacks SDL_EnterAppMainCallbacks_REAL
#define SDL_CleanupEvent SDL_CleanupEvent_REAL
#define SDL_RWprintf SDL_RWprintf_REAL
#define SDL_RWvprintf SDL_RWvprintf_REAL
#define SDL_AllocateEventMemory SDL_AllocateEventMemory_REAL
2 changes: 1 addition & 1 deletion src/dynapi/SDL_dynapi_procs.h
Original file line number Diff line number Diff line change
Expand Up @@ -979,5 +979,5 @@ SDL_DYNAPI_PROC(SDL_PropertiesID,SDL_GetSurfaceProperties,(SDL_Surface *a),(a),r
SDL_DYNAPI_PROC(SDL_PropertiesID,SDL_GetWindowProperties,(SDL_Window *a),(a),return)
SDL_DYNAPI_PROC(int,SDL_ClearProperty,(SDL_PropertiesID a, const char *b),(a,b),return)
SDL_DYNAPI_PROC(int,SDL_EnterAppMainCallbacks,(int a, char *b[], SDL_AppInit_func c, SDL_AppIterate_func d, SDL_AppEvent_func e, SDL_AppQuit_func f),(a,b,c,d,e,f),return)
SDL_DYNAPI_PROC(void,SDL_CleanupEvent,(SDL_Event *a),(a),)
SDL_DYNAPI_PROC(size_t,SDL_RWvprintf,(SDL_RWops *a, const char *b, va_list c),(a,b,c),return)
SDL_DYNAPI_PROC(void*,SDL_AllocateEventMemory,(size_t a),(a),return)
11 changes: 5 additions & 6 deletions src/events/SDL_dropevents.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,12 @@ static int SDL_SendDrop(SDL_Window *window, const SDL_EventType evtype, const ch
event.drop.source = SDL_strdup(source);
}
if (data) {
size_t len = SDL_strlen(data);
if (len < sizeof(event.drop.short_data)) {
SDL_memcpy(event.drop.short_data, data, len + 1);
event.drop.data = event.drop.short_data;
} else {
event.drop.data = SDL_strdup(data);
size_t size = SDL_strlen(data) + 1;
event.drop.data = (char *)SDL_AllocateEventMemory(size);
if (!event.drop.data) {
return 0;
}
SDL_memcpy(event.drop.data, data, size);
}
event.drop.windowID = window ? window->id : 0;

Expand Down
Loading

0 comments on commit a298e0d

Please sign in to comment.