mirror of
				https://github.com/libsdl-org/SDL.git
				synced 2025-11-04 01:34:38 +00:00 
			
		
		
		
	Allow casting properties of different types
This commit is contained in:
		@@ -20,6 +20,7 @@
 | 
			
		||||
*/
 | 
			
		||||
#include "SDL_internal.h"
 | 
			
		||||
#include "SDL_hashtable.h"
 | 
			
		||||
#include "SDL_hints_c.h"
 | 
			
		||||
#include "SDL_properties_c.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -35,6 +36,8 @@ typedef struct
 | 
			
		||||
        SDL_bool boolean_value;
 | 
			
		||||
    } value;
 | 
			
		||||
 | 
			
		||||
    char *string_storage;
 | 
			
		||||
 | 
			
		||||
    void (SDLCALL *cleanup)(void *userdata, void *value);
 | 
			
		||||
    void *userdata;
 | 
			
		||||
} SDL_Property;
 | 
			
		||||
@@ -67,6 +70,9 @@ static void SDL_FreeProperty(const void *key, const void *value, void *data)
 | 
			
		||||
        default:
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
        if (property->string_storage) {
 | 
			
		||||
            SDL_free(property->string_storage);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    SDL_free((void *)key);
 | 
			
		||||
    SDL_free((void *)value);
 | 
			
		||||
@@ -342,7 +348,7 @@ int SDL_SetBooleanProperty(SDL_PropertiesID props, const char *name, SDL_bool va
 | 
			
		||||
        return SDL_OutOfMemory();
 | 
			
		||||
    }
 | 
			
		||||
    property->type = SDL_PROPERTY_TYPE_BOOLEAN;
 | 
			
		||||
    property->value.boolean_value = value;
 | 
			
		||||
    property->value.boolean_value = value ? SDL_TRUE : SDL_FALSE;
 | 
			
		||||
    return SDL_PrivateSetProperty(props, name, property);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -461,10 +467,40 @@ const char *SDL_GetStringProperty(SDL_PropertiesID props, const char *name, cons
 | 
			
		||||
    {
 | 
			
		||||
        SDL_Property *property = NULL;
 | 
			
		||||
        if (SDL_FindInHashTable(properties->props, name, (const void **)&property)) {
 | 
			
		||||
            if (property->type == SDL_PROPERTY_TYPE_STRING) {
 | 
			
		||||
            switch (property->type) {
 | 
			
		||||
            case SDL_PROPERTY_TYPE_STRING:
 | 
			
		||||
                value = property->value.string_value;
 | 
			
		||||
                break;
 | 
			
		||||
            case SDL_PROPERTY_TYPE_NUMBER:
 | 
			
		||||
                if (property->string_storage) {
 | 
			
		||||
                    value = property->string_storage;
 | 
			
		||||
                } else {
 | 
			
		||||
                    SDL_asprintf(&property->string_storage, "%" SDL_PRIs64 "", property->value.number_value);
 | 
			
		||||
                    if (property->string_storage) {
 | 
			
		||||
                        value = property->string_storage;
 | 
			
		||||
                    } else {
 | 
			
		||||
                        SDL_OutOfMemory();
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            case SDL_PROPERTY_TYPE_FLOAT:
 | 
			
		||||
                if (property->string_storage) {
 | 
			
		||||
                    value = property->string_storage;
 | 
			
		||||
                } else {
 | 
			
		||||
                    SDL_asprintf(&property->string_storage, "%f", property->value.float_value);
 | 
			
		||||
                    if (property->string_storage) {
 | 
			
		||||
                        value = property->string_storage;
 | 
			
		||||
                    } else {
 | 
			
		||||
                        SDL_OutOfMemory();
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            case SDL_PROPERTY_TYPE_BOOLEAN:
 | 
			
		||||
                value = property->value.boolean_value ? "true" : "false";
 | 
			
		||||
                break;
 | 
			
		||||
            default:
 | 
			
		||||
                SDL_SetError("Property %s isn't a string value", name);
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            SDL_SetError("Couldn't find property named %s", name);
 | 
			
		||||
@@ -502,10 +538,22 @@ Sint64 SDL_GetNumberProperty(SDL_PropertiesID props, const char *name, Sint64 de
 | 
			
		||||
    {
 | 
			
		||||
        SDL_Property *property = NULL;
 | 
			
		||||
        if (SDL_FindInHashTable(properties->props, name, (const void **)&property)) {
 | 
			
		||||
            if (property->type == SDL_PROPERTY_TYPE_NUMBER) {
 | 
			
		||||
            switch (property->type) {
 | 
			
		||||
            case SDL_PROPERTY_TYPE_STRING:
 | 
			
		||||
                value = SDL_strtoll(property->value.string_value, NULL, 0);
 | 
			
		||||
                break;
 | 
			
		||||
            case SDL_PROPERTY_TYPE_NUMBER:
 | 
			
		||||
                value = property->value.number_value;
 | 
			
		||||
            } else {
 | 
			
		||||
                SDL_SetError("Property %s isn't a string value", name);
 | 
			
		||||
                break;
 | 
			
		||||
            case SDL_PROPERTY_TYPE_FLOAT:
 | 
			
		||||
                value = (Sint64)SDL_round((double)property->value.float_value);
 | 
			
		||||
                break;
 | 
			
		||||
            case SDL_PROPERTY_TYPE_BOOLEAN:
 | 
			
		||||
                value = property->value.boolean_value;
 | 
			
		||||
                break;
 | 
			
		||||
            default:
 | 
			
		||||
                SDL_SetError("Property %s isn't a number value", name);
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            SDL_SetError("Couldn't find property named %s", name);
 | 
			
		||||
@@ -543,10 +591,22 @@ float SDL_GetFloatProperty(SDL_PropertiesID props, const char *name, float defau
 | 
			
		||||
    {
 | 
			
		||||
        SDL_Property *property = NULL;
 | 
			
		||||
        if (SDL_FindInHashTable(properties->props, name, (const void **)&property)) {
 | 
			
		||||
            if (property->type == SDL_PROPERTY_TYPE_FLOAT) {
 | 
			
		||||
            switch (property->type) {
 | 
			
		||||
            case SDL_PROPERTY_TYPE_STRING:
 | 
			
		||||
                value = (float)SDL_atof(property->value.string_value);
 | 
			
		||||
                break;
 | 
			
		||||
            case SDL_PROPERTY_TYPE_NUMBER:
 | 
			
		||||
                value = (float)property->value.number_value;
 | 
			
		||||
                break;
 | 
			
		||||
            case SDL_PROPERTY_TYPE_FLOAT:
 | 
			
		||||
                value = property->value.float_value;
 | 
			
		||||
            } else {
 | 
			
		||||
                break;
 | 
			
		||||
            case SDL_PROPERTY_TYPE_BOOLEAN:
 | 
			
		||||
                value = (float)property->value.boolean_value;
 | 
			
		||||
                break;
 | 
			
		||||
            default:
 | 
			
		||||
                SDL_SetError("Property %s isn't a float value", name);
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            SDL_SetError("Couldn't find property named %s", name);
 | 
			
		||||
@@ -584,10 +644,22 @@ SDL_bool SDL_GetBooleanProperty(SDL_PropertiesID props, const char *name, SDL_bo
 | 
			
		||||
    {
 | 
			
		||||
        SDL_Property *property = NULL;
 | 
			
		||||
        if (SDL_FindInHashTable(properties->props, name, (const void **)&property)) {
 | 
			
		||||
            if (property->type == SDL_PROPERTY_TYPE_BOOLEAN) {
 | 
			
		||||
            switch (property->type) {
 | 
			
		||||
            case SDL_PROPERTY_TYPE_STRING:
 | 
			
		||||
                value = SDL_GetStringBoolean(property->value.string_value, default_value);
 | 
			
		||||
                break;
 | 
			
		||||
            case SDL_PROPERTY_TYPE_NUMBER:
 | 
			
		||||
                value = (property->value.number_value != 0);
 | 
			
		||||
                break;
 | 
			
		||||
            case SDL_PROPERTY_TYPE_FLOAT:
 | 
			
		||||
                value = (property->value.float_value != 0.0f);
 | 
			
		||||
                break;
 | 
			
		||||
            case SDL_PROPERTY_TYPE_BOOLEAN:
 | 
			
		||||
                value = property->value.boolean_value;
 | 
			
		||||
            } else {
 | 
			
		||||
                break;
 | 
			
		||||
            default:
 | 
			
		||||
                SDL_SetError("Property %s isn't a boolean value", name);
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            SDL_SetError("Couldn't find property named %s", name);
 | 
			
		||||
 
 | 
			
		||||
@@ -81,7 +81,7 @@ static int properties_testBasic(void *arg)
 | 
			
		||||
            "Verify property, expected 0xabcd, got: %p", value);
 | 
			
		||||
    value_string = SDL_GetStringProperty(props, "foo", "abcd");
 | 
			
		||||
    SDLTest_AssertCheck(value_string && SDL_strcmp(value_string, "abcd") == 0,
 | 
			
		||||
            "Verify string property, expected \"abcd\", got: %s", value_string);
 | 
			
		||||
            "Verify string property, expected abcd, got: %s", value_string);
 | 
			
		||||
    value_number = SDL_GetNumberProperty(props, "foo", 1234);
 | 
			
		||||
    SDLTest_AssertCheck(value_number == 1234,
 | 
			
		||||
            "Verify number property, expected 1234, got: %" SDL_PRIu64 "", value_number);
 | 
			
		||||
@@ -125,7 +125,7 @@ static int properties_testBasic(void *arg)
 | 
			
		||||
            "Verify property, expected NULL, got: %p", value);
 | 
			
		||||
    value_string = SDL_GetStringProperty(props, "foo", NULL);
 | 
			
		||||
    SDLTest_AssertCheck(value_string != NULL && SDL_strcmp(value_string, "bar") == 0,
 | 
			
		||||
            "Verify string property, expected \"bar\", got: %s", value_string);
 | 
			
		||||
            "Verify string property, expected bar, 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);
 | 
			
		||||
@@ -133,8 +133,8 @@ static int properties_testBasic(void *arg)
 | 
			
		||||
    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");
 | 
			
		||||
    SDLTest_AssertCheck(value_bool == SDL_TRUE,
 | 
			
		||||
            "Verify boolean property, expected SDL_TRUE, got: %s", value_bool ? "SDL_TRUE" : "SDL_FALSE");
 | 
			
		||||
 | 
			
		||||
    /* Check number value */
 | 
			
		||||
    SDLTest_AssertPass("Call to SDL_SetNumberProperty(\"foo\", 1)");
 | 
			
		||||
@@ -146,21 +146,21 @@ static int properties_testBasic(void *arg)
 | 
			
		||||
    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);
 | 
			
		||||
    SDLTest_AssertCheck(value_string && SDL_strcmp(value_string, "1") == 0,
 | 
			
		||||
            "Verify string property, expected 1, got: %s", value_string);
 | 
			
		||||
    value_number = SDL_GetNumberProperty(props, "foo", 0);
 | 
			
		||||
    SDLTest_AssertCheck(value_number == 1,
 | 
			
		||||
            "Verify number property, expected 1, got: %" SDL_PRIu64 "", value_number);
 | 
			
		||||
    value_float = SDL_GetFloatProperty(props, "foo", 0.0f);
 | 
			
		||||
    SDLTest_AssertCheck(value_float == 0.0f,
 | 
			
		||||
            "Verify float property, expected 0, got: %f", value_float);
 | 
			
		||||
    SDLTest_AssertCheck(value_float == 1.0f,
 | 
			
		||||
            "Verify float 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");
 | 
			
		||||
    SDLTest_AssertCheck(value_bool == SDL_TRUE,
 | 
			
		||||
            "Verify boolean property, expected SDL_TRUE, got: %s", value_bool ? "SDL_TRUE" : "SDL_FALSE");
 | 
			
		||||
 | 
			
		||||
    /* Check float value */
 | 
			
		||||
    SDLTest_AssertPass("Call to SDL_SetFloatProperty(\"foo\", 1)");
 | 
			
		||||
    SDL_SetFloatProperty(props, "foo", 1.0f);
 | 
			
		||||
    SDL_SetFloatProperty(props, "foo", 1.75f);
 | 
			
		||||
    type = SDL_GetPropertyType(props, "foo");
 | 
			
		||||
    SDLTest_AssertCheck(type == SDL_PROPERTY_TYPE_FLOAT,
 | 
			
		||||
            "Verify property type, expected %d, got: %d", SDL_PROPERTY_TYPE_FLOAT, type);
 | 
			
		||||
@@ -168,21 +168,21 @@ static int properties_testBasic(void *arg)
 | 
			
		||||
    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);
 | 
			
		||||
    SDLTest_AssertCheck(value_string && SDL_strcmp(value_string, "1.750000") == 0,
 | 
			
		||||
            "Verify string property, expected 1.750000, 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);
 | 
			
		||||
    SDLTest_AssertCheck(value_number == 2,
 | 
			
		||||
            "Verify number property, expected 2, got: %" SDL_PRIu64 "", value_number);
 | 
			
		||||
    value_float = SDL_GetFloatProperty(props, "foo", 0.0f);
 | 
			
		||||
    SDLTest_AssertCheck(value_float == 1.0f,
 | 
			
		||||
            "Verify string property, expected 1, got: %f", value_float);
 | 
			
		||||
    SDLTest_AssertCheck(value_float == 1.75f,
 | 
			
		||||
            "Verify float property, expected 1.75, 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");
 | 
			
		||||
    SDLTest_AssertCheck(value_bool == SDL_TRUE,
 | 
			
		||||
            "Verify boolean property, expected SDL_TRUE, 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);
 | 
			
		||||
    SDL_SetBooleanProperty(props, "foo", 3); /* Note we're testing non-true/false value here */
 | 
			
		||||
    type = SDL_GetPropertyType(props, "foo");
 | 
			
		||||
    SDLTest_AssertCheck(type == SDL_PROPERTY_TYPE_BOOLEAN,
 | 
			
		||||
            "Verify property type, expected %d, got: %d", SDL_PROPERTY_TYPE_BOOLEAN, type);
 | 
			
		||||
@@ -190,14 +190,14 @@ static int properties_testBasic(void *arg)
 | 
			
		||||
    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);
 | 
			
		||||
    SDLTest_AssertCheck(value_string && SDL_strcmp(value_string, "true") == 0,
 | 
			
		||||
            "Verify string property, expected true, 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);
 | 
			
		||||
    SDLTest_AssertCheck(value_number == 1,
 | 
			
		||||
            "Verify number property, expected 1, 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);
 | 
			
		||||
    SDLTest_AssertCheck(value_float == 1.0f,
 | 
			
		||||
            "Verify float property, expected 1, 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");
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user