diff --git a/include/SDL3/SDL_properties.h b/include/SDL3/SDL_properties.h index 655a21d41..eedc17880 100644 --- a/include/SDL3/SDL_properties.h +++ b/include/SDL3/SDL_properties.h @@ -49,6 +49,7 @@ typedef enum SDL_PROPERTY_TYPE_STRING, SDL_PROPERTY_TYPE_NUMBER, SDL_PROPERTY_TYPE_FLOAT, + SDL_PROPERTY_TYPE_BOOLEAN, } SDL_PropertyType; /** @@ -208,6 +209,23 @@ extern DECLSPEC int SDLCALL SDL_SetNumberProperty(SDL_PropertiesID props, const */ extern DECLSPEC int SDLCALL SDL_SetFloatProperty(SDL_PropertiesID props, const char *name, float value); +/** + * Set a boolean property on a set of properties + * + * \param props the properties to modify + * \param name the name of the property to modify + * \param value the new value of the property + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.0.0. + * + * \sa SDL_GetBooleanProperty + */ +extern DECLSPEC int SDLCALL SDL_SetBooleanProperty(SDL_PropertiesID props, const char *name, SDL_bool value); + /** * Get the type of a property on a set of properties * @@ -302,6 +320,25 @@ extern DECLSPEC Sint64 SDLCALL SDL_GetNumberProperty(SDL_PropertiesID props, con */ extern DECLSPEC float SDLCALL SDL_GetFloatProperty(SDL_PropertiesID props, const char *name, float default_value); +/** + * Get a boolean property on a set of properties + * + * You can use SDL_GetPropertyType() to query whether the property exists and is a boolean property. + * + * \param props the properties to query + * \param name the name of the property to query + * \param default_value the default value of the property + * \returns the value of the property, or `default_value` if it is not set or not a float property. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.0.0. + * + * \sa SDL_GetPropertyType + * \sa SDL_SetBooleanProperty + */ +extern DECLSPEC SDL_bool SDLCALL SDL_GetBooleanProperty(SDL_PropertiesID props, const char *name, SDL_bool default_value); + /** * Clear a property on a set of properties * diff --git a/src/SDL_properties.c b/src/SDL_properties.c index 5b47b597a..e32d1d11c 100644 --- a/src/SDL_properties.c +++ b/src/SDL_properties.c @@ -32,6 +32,7 @@ typedef struct char *string_value; Sint64 number_value; float float_value; + SDL_bool boolean_value; } value; void (SDLCALL *cleanup)(void *userdata, void *value); @@ -334,6 +335,17 @@ int SDL_SetFloatProperty(SDL_PropertiesID props, const char *name, float value) return SDL_PrivateSetProperty(props, name, property); } +int SDL_SetBooleanProperty(SDL_PropertiesID props, const char *name, SDL_bool value) +{ + SDL_Property *property = (SDL_Property *)SDL_calloc(1, sizeof(*property)); + if (!property) { + return SDL_OutOfMemory(); + } + property->type = SDL_PROPERTY_TYPE_BOOLEAN; + property->value.boolean_value = value; + return SDL_PrivateSetProperty(props, name, property); +} + SDL_PropertyType SDL_GetPropertyType(SDL_PropertiesID props, const char *name) { SDL_Properties *properties = NULL; @@ -545,6 +557,47 @@ float SDL_GetFloatProperty(SDL_PropertiesID props, const char *name, float defau return value; } +SDL_bool SDL_GetBooleanProperty(SDL_PropertiesID props, const char *name, SDL_bool default_value) +{ + SDL_Properties *properties = NULL; + SDL_bool value = default_value; + + if (!props) { + SDL_InvalidParamError("props"); + return value; + } + if (!name || !*name) { + SDL_InvalidParamError("name"); + return value; + } + + SDL_LockRWLockForReading(SDL_properties_lock); + SDL_FindInHashTable(SDL_properties, (const void *)(uintptr_t)props, (const void **)&properties); + SDL_UnlockRWLock(SDL_properties_lock); + + if (!properties) { + SDL_InvalidParamError("props"); + return value; + } + + SDL_LockMutex(properties->lock); + { + SDL_Property *property = NULL; + if (SDL_FindInHashTable(properties->props, name, (const void **)&property)) { + if (property->type == SDL_PROPERTY_TYPE_BOOLEAN) { + value = property->value.boolean_value; + } else { + SDL_SetError("Property %s isn't a boolean value", name); + } + } else { + SDL_SetError("Couldn't find property named %s", name); + } + } + SDL_UnlockMutex(properties->lock); + + return value; +} + int SDL_ClearProperty(SDL_PropertiesID props, const char *name) { return SDL_PrivateSetProperty(props, name, NULL); diff --git a/src/dynapi/SDL_dynapi.sym b/src/dynapi/SDL_dynapi.sym index f0dbaf6d7..46c1278c6 100644 --- a/src/dynapi/SDL_dynapi.sym +++ b/src/dynapi/SDL_dynapi.sym @@ -964,6 +964,8 @@ SDL3_0.0.0 { SDL_GetNumberProperty; SDL_GetFloatProperty; SDL_EnumerateProperties; + SDL_SetBooleanProperty; + SDL_GetBooleanProperty; # extra symbols go here (don't modify this line) local: *; }; diff --git a/src/dynapi/SDL_dynapi_overrides.h b/src/dynapi/SDL_dynapi_overrides.h index 8c7f5ea86..a476b53fc 100644 --- a/src/dynapi/SDL_dynapi_overrides.h +++ b/src/dynapi/SDL_dynapi_overrides.h @@ -989,3 +989,5 @@ #define SDL_GetNumberProperty SDL_GetNumberProperty_REAL #define SDL_GetFloatProperty SDL_GetFloatProperty_REAL #define SDL_EnumerateProperties SDL_EnumerateProperties_REAL +#define SDL_SetBooleanProperty SDL_SetBooleanProperty_REAL +#define SDL_GetBooleanProperty SDL_GetBooleanProperty_REAL diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h index 3314f71bd..90be91d07 100644 --- a/src/dynapi/SDL_dynapi_procs.h +++ b/src/dynapi/SDL_dynapi_procs.h @@ -1014,3 +1014,5 @@ SDL_DYNAPI_PROC(const char*,SDL_GetStringProperty,(SDL_PropertiesID a, const cha SDL_DYNAPI_PROC(Sint64,SDL_GetNumberProperty,(SDL_PropertiesID a, const char *b, Sint64 c),(a,b,c),return) SDL_DYNAPI_PROC(float,SDL_GetFloatProperty,(SDL_PropertiesID a, const char *b, float c),(a,b,c),return) SDL_DYNAPI_PROC(int,SDL_EnumerateProperties,(SDL_PropertiesID a, SDL_EnumeratePropertiesCallback b, void *c),(a,b,c),return) +SDL_DYNAPI_PROC(int,SDL_SetBooleanProperty,(SDL_PropertiesID a, const char *b, SDL_bool c),(a,b,c),return) +SDL_DYNAPI_PROC(SDL_bool,SDL_GetBooleanProperty,(SDL_PropertiesID a, const char *b, SDL_bool c),(a,b,c),return) diff --git a/test/testautomation_properties.c b/test/testautomation_properties.c index d2936f119..3feca3e04 100644 --- a/test/testautomation_properties.c +++ b/test/testautomation_properties.c @@ -32,6 +32,7 @@ static int properties_testBasic(void *arg) const char *value_string; Sint64 value_number; float value_float; + SDL_bool value_bool; int i, result, count; props = SDL_CreateProperties(); @@ -87,6 +88,9 @@ static int properties_testBasic(void *arg) value_float = SDL_GetFloatProperty(props, "foo", 1234.0f); SDLTest_AssertCheck(value_float == 1234.0f, "Verify float property, expected 1234, got: %f", value_float); + value_bool = SDL_GetBooleanProperty(props, "foo", SDL_TRUE); + SDLTest_AssertCheck(value_bool == SDL_TRUE, + "Verify boolean property, expected SDL_TRUE, got: %s", value_bool ? "SDL_TRUE" : "SDL_FALSE"); /* Check data value */ SDLTest_AssertPass("Call to SDL_SetProperty(\"foo\", 0x01)"); @@ -106,6 +110,9 @@ static int properties_testBasic(void *arg) value_float = SDL_GetFloatProperty(props, "foo", 0.0f); SDLTest_AssertCheck(value_float == 0.0f, "Verify float property, expected 0, got: %f", value_float); + value_bool = SDL_GetBooleanProperty(props, "foo", SDL_FALSE); + SDLTest_AssertCheck(value_bool == SDL_FALSE, + "Verify boolean property, expected SDL_FALSE, got: %s", value_bool ? "SDL_TRUE" : "SDL_FALSE"); /* Check string value */ SDLTest_AssertPass("Call to SDL_SetStringProperty(\"foo\", \"bar\")"); @@ -125,6 +132,9 @@ static int properties_testBasic(void *arg) value_float = SDL_GetFloatProperty(props, "foo", 0.0f); SDLTest_AssertCheck(value_float == 0.0f, "Verify float property, expected 0, got: %f", value_float); + value_bool = SDL_GetBooleanProperty(props, "foo", SDL_FALSE); + SDLTest_AssertCheck(value_bool == SDL_FALSE, + "Verify boolean property, expected SDL_FALSE, got: %s", value_bool ? "SDL_TRUE" : "SDL_FALSE"); /* Check number value */ SDLTest_AssertPass("Call to SDL_SetNumberProperty(\"foo\", 1)"); @@ -144,9 +154,12 @@ static int properties_testBasic(void *arg) value_float = SDL_GetFloatProperty(props, "foo", 0.0f); SDLTest_AssertCheck(value_float == 0.0f, "Verify float property, expected 0, got: %f", value_float); + value_bool = SDL_GetBooleanProperty(props, "foo", SDL_FALSE); + SDLTest_AssertCheck(value_bool == SDL_FALSE, + "Verify boolean property, expected SDL_FALSE, got: %s", value_bool ? "SDL_TRUE" : "SDL_FALSE"); /* Check float value */ - SDLTest_AssertPass("Call to SDL_SetNumberProperty(\"foo\", 1)"); + SDLTest_AssertPass("Call to SDL_SetFloatProperty(\"foo\", 1)"); SDL_SetFloatProperty(props, "foo", 1.0f); type = SDL_GetPropertyType(props, "foo"); SDLTest_AssertCheck(type == SDL_PROPERTY_TYPE_FLOAT, @@ -163,6 +176,31 @@ static int properties_testBasic(void *arg) value_float = SDL_GetFloatProperty(props, "foo", 0.0f); SDLTest_AssertCheck(value_float == 1.0f, "Verify string property, expected 1, got: %f", value_float); + value_bool = SDL_GetBooleanProperty(props, "foo", SDL_FALSE); + SDLTest_AssertCheck(value_bool == SDL_FALSE, + "Verify boolean property, expected SDL_FALSE, got: %s", value_bool ? "SDL_TRUE" : "SDL_FALSE"); + + /* Check boolean value */ + SDLTest_AssertPass("Call to SDL_SetBooleanProperty(\"foo\", SDL_TRUE)"); + SDL_SetBooleanProperty(props, "foo", SDL_TRUE); + type = SDL_GetPropertyType(props, "foo"); + SDLTest_AssertCheck(type == SDL_PROPERTY_TYPE_BOOLEAN, + "Verify property type, expected %d, got: %d", SDL_PROPERTY_TYPE_BOOLEAN, type); + value = SDL_GetProperty(props, "foo", NULL); + SDLTest_AssertCheck(value == NULL, + "Verify property, expected NULL, got: %p", value); + value_string = SDL_GetStringProperty(props, "foo", NULL); + SDLTest_AssertCheck(value_string == NULL, + "Verify string property, expected NULL, got: %s", value_string); + value_number = SDL_GetNumberProperty(props, "foo", 0); + SDLTest_AssertCheck(value_number == 0, + "Verify number property, expected 0, got: %" SDL_PRIu64 "", value_number); + value_float = SDL_GetFloatProperty(props, "foo", 0.0f); + SDLTest_AssertCheck(value_float == 0.0f, + "Verify string property, expected 0, got: %f", value_float); + value_bool = SDL_GetBooleanProperty(props, "foo", SDL_FALSE); + SDLTest_AssertCheck(value_bool == SDL_TRUE, + "Verify boolean property, expected SDL_TRUE, got: %s", value_bool ? "SDL_TRUE" : "SDL_FALSE"); /* Make sure we have exactly one property named foo */ count = 0;