From 2626304e701b80998e622c352234c012b94bf51e Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sun, 26 May 2024 12:17:34 -0400 Subject: [PATCH] properties: add formal SDL_CleanupPropertyCallback type, improve docs. --- include/SDL3/SDL_properties.h | 48 ++++++++++++++++++++++++++++++++++- src/SDL_properties.c | 4 +-- src/dynapi/SDL_dynapi_procs.h | 2 +- 3 files changed, 50 insertions(+), 4 deletions(-) diff --git a/include/SDL3/SDL_properties.h b/include/SDL3/SDL_properties.h index 27e90526f9..870bcedc97 100644 --- a/include/SDL3/SDL_properties.h +++ b/include/SDL3/SDL_properties.h @@ -145,6 +145,30 @@ extern SDL_DECLSPEC int SDLCALL SDL_LockProperties(SDL_PropertiesID props); */ extern SDL_DECLSPEC void SDLCALL SDL_UnlockProperties(SDL_PropertiesID props); +/** + * A callback used to free resources when a property is deleted. + * + * This should release any resources associated with `value` that are + * no longer needed. + * + * This callback is set per-property. Different properties in the same + * set can have different cleanup callbacks. + * + * This callback will be called _during_ SDL_SetPropertyWithCleanup if the + * function fails for any reason. + * + * \param userdata an app-defined pointer passed to the callback. + * \param value the pointer assigned to the property to clean up. + * + * \threadsafety This callback may fire without any locks held; if this is + * a concern, the app should provide its own locking. + * + * \since This datatype is available since SDL 3.0.0. + * + * \sa SDL_SetPropertyWithCleanup + */ +typedef void (SDLCALL *SDL_CleanupPropertyCallback)(void *userdata, void *value); + /** * Set a property on a set of properties with a cleanup function that is * called when the property is deleted. @@ -152,6 +176,11 @@ extern SDL_DECLSPEC void SDLCALL SDL_UnlockProperties(SDL_PropertiesID props); * The cleanup function is also called if setting the property fails for any * reason. * + * For simply setting basic data types, like numbers, bools, or strings, + * use SDL_SetNumberProperty, SDL_SetBooleanProperty, or SDL_SetStringProperty + * instead, as those functions will handle cleanup on your behalf. This + * function is only for more complex, custom data. + * * \param props the properties to modify * \param name the name of the property to modify * \param value the new value of the property, or NULL to delete the property @@ -167,8 +196,9 @@ extern SDL_DECLSPEC void SDLCALL SDL_UnlockProperties(SDL_PropertiesID props); * * \sa SDL_GetProperty * \sa SDL_SetProperty + * \sa SDL_CleanupPropertyCallback */ -extern SDL_DECLSPEC int SDLCALL SDL_SetPropertyWithCleanup(SDL_PropertiesID props, const char *name, void *value, void (SDLCALL *cleanup)(void *userdata, void *value), void *userdata); +extern SDL_DECLSPEC int SDLCALL SDL_SetPropertyWithCleanup(SDL_PropertiesID props, const char *name, void *value, SDL_CleanupPropertyCallback cleanup, void *userdata); /** * Set a property on a set of properties. @@ -426,6 +456,22 @@ extern SDL_DECLSPEC SDL_bool SDLCALL SDL_GetBooleanProperty(SDL_PropertiesID pro */ extern SDL_DECLSPEC int SDLCALL SDL_ClearProperty(SDL_PropertiesID props, const char *name); +/** + * A callback used to enumerate all properties set in an SDL_PropertiesID. + * + * This callback is called from SDL_EnumerateProperties(), and is called once + * per property in the set. + * + * \param userdata an app-defined pointer passed to the callback. + * \param props the SDL_PropertiesID that is being enumerated. + * \param name the next property name in the enumeration. + * + * \threadsafety SDL_EnumerateProperties holds a lock on `props` during this callback. + * + * \since This datatype is available since SDL 3.0.0. + * + * \sa SDL_EnumerateProperties + */ typedef void (SDLCALL *SDL_EnumeratePropertiesCallback)(void *userdata, SDL_PropertiesID props, const char *name); /** diff --git a/src/SDL_properties.c b/src/SDL_properties.c index 1a094caacc..d2dca5c9f0 100644 --- a/src/SDL_properties.c +++ b/src/SDL_properties.c @@ -38,7 +38,7 @@ typedef struct char *string_storage; - void (SDLCALL *cleanup)(void *userdata, void *value); + SDL_CleanupPropertyCallback cleanup; void *userdata; } SDL_Property; @@ -338,7 +338,7 @@ static int SDL_PrivateSetProperty(SDL_PropertiesID props, const char *name, SDL_ return result; } -int SDL_SetPropertyWithCleanup(SDL_PropertiesID props, const char *name, void *value, void (SDLCALL *cleanup)(void *userdata, void *value), void *userdata) +int SDL_SetPropertyWithCleanup(SDL_PropertiesID props, const char *name, void *value, SDL_CleanupPropertyCallback cleanup, void *userdata) { SDL_Property *property; diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h index fd97c77e5f..1b069ff399 100644 --- a/src/dynapi/SDL_dynapi_procs.h +++ b/src/dynapi/SDL_dynapi_procs.h @@ -748,7 +748,7 @@ SDL_DYNAPI_PROC(int,SDL_SetPaletteColors,(SDL_Palette *a, const SDL_Color *b, in SDL_DYNAPI_PROC(int,SDL_SetPixelFormatPalette,(SDL_PixelFormat *a, SDL_Palette *b),(a,b),return) SDL_DYNAPI_PROC(int,SDL_SetPrimarySelectionText,(const char *a),(a),return) SDL_DYNAPI_PROC(int,SDL_SetProperty,(SDL_PropertiesID a, const char *b, void *c),(a,b,c),return) -SDL_DYNAPI_PROC(int,SDL_SetPropertyWithCleanup,(SDL_PropertiesID a, const char *b, void *c, void (SDLCALL *d)(void *userdata, void *value), void *e),(a,b,c,d,e),return) +SDL_DYNAPI_PROC(int,SDL_SetPropertyWithCleanup,(SDL_PropertiesID a, const char *b, void *c, SDL_CleanupPropertyCallback d, void *e),(a,b,c,d,e),return) SDL_DYNAPI_PROC(int,SDL_SetRelativeMouseMode,(SDL_bool a),(a),return) SDL_DYNAPI_PROC(int,SDL_SetRenderClipRect,(SDL_Renderer *a, const SDL_Rect *b),(a,b),return) SDL_DYNAPI_PROC(int,SDL_SetRenderColorScale,(SDL_Renderer *a, float b),(a,b),return)