From bd269b0f4103581f7adc0ec30631a159f6caf3b1 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Sun, 12 Nov 2023 18:34:22 -0800
Subject: [PATCH] Added SDL_SetBooleanProperty() and SDL_GetBooleanProperty()
---
include/SDL3/SDL_properties.h | 37 +++++++++++++++++++++
src/SDL_properties.c | 53 +++++++++++++++++++++++++++++++
src/dynapi/SDL_dynapi.sym | 2 ++
src/dynapi/SDL_dynapi_overrides.h | 2 ++
src/dynapi/SDL_dynapi_procs.h | 2 ++
test/testautomation_properties.c | 40 ++++++++++++++++++++++-
6 files changed, 135 insertions(+), 1 deletion(-)
diff --git a/include/SDL3/SDL_properties.h b/include/SDL3/SDL_properties.h
index 655a21d41551..eedc178806f4 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 5b47b597ac98..e32d1d11c759 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 f0dbaf6d7994..46c1278c6b65 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 8c7f5ea861b3..a476b53fc07d 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 3314f71bdd27..90be91d07899 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 d2936f119dbd..3feca3e0429f 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;