From 783258e086ee1f4c6595fdfe8e5dd5c8ca0e9b26 Mon Sep 17 00:00:00 2001 From: Sara Date: Mon, 2 Oct 2023 10:45:30 +0200 Subject: [PATCH] Added ASSERT_RETURN and RETURN_ERROR as well as WARNING variants of each --- src/assets.c | 34 +++++++++--------------------- src/debug.h | 38 ++++++++++++++++++++++++++++----- src/level.c | 10 ++------- src/sprite.c | 5 +---- src/spritesheet.c | 11 ++++------ src/tilemap.c | 29 +++++++------------------- src/tileset.c | 53 ++++++++++++++++++----------------------------- 7 files changed, 78 insertions(+), 102 deletions(-) diff --git a/src/assets.c b/src/assets.c index 5eabd3e..561dd0c 100644 --- a/src/assets.c +++ b/src/assets.c @@ -110,9 +110,7 @@ asset_id store_asset(void* asset, AssetDestructor destructor) { static AssetData* _internal_get_by_id(asset_id id) { - if(id == 0) { - return NULL; - } + ASSERT_RETURN_WARN(id != 0, NULL, "Cannot get element with id 0"); for(size_t i = 0; i < _assets_len; ++i) { if(_assets[i].id == id) { @@ -120,16 +118,14 @@ AssetData* _internal_get_by_id(asset_id id) { } } - return NULL; + RETURN_WARNING(NULL, "Failed to find requested asset with id %zu", id); } void* get_asset(asset_id id) { AssetData* found = _internal_get_by_id(id); - if(found != NULL) { - return found->asset; - } + ASSERT_RETURN(found != NULL, NULL, "Failed to find asset with id %zu.", id); - return NULL; + return found; } asset_id get_asset_id(void* asset) { @@ -139,15 +135,13 @@ asset_id get_asset_id(void* asset) { } } - return 0; + RETURN_WARNING(NULL, "Failed to find asset referencing %p", asset); } void free_asset(asset_id id) { AssetData* found = _internal_get_by_id(id); - if(found == NULL) { - return; - } + ASSERT_RETURN(found != NULL,, "Attempt to free nonexistent asset."); found->destructor(found->asset); @@ -159,31 +153,23 @@ void free_asset(asset_id id) { cJSON* load_json_from_file(const char* filename) { FILE* fp = fopen(filename, "r"); - if(fp == NULL) { - return NULL; - } + ASSERT_RETURN(fp != NULL, NULL, "Failed to open file %s.", filename); size_t len = file_length(fp); char* buffer = malloc(len + 1); - if(buffer == NULL) { - return NULL; - } + ASSERT_RETURN(buffer != NULL, NULL, "Failed to allocate buffer for json string."); read_file(fp, buffer, len); cJSON* out = cJSON_Parse(buffer); free(buffer); - if(out == NULL) { - return NULL; - } + ASSERT_RETURN(out != NULL, NULL, "Failed to parse json from file %s.", filename); return out; } size_t json_array_len(cJSON* json) { - if(!cJSON_IsArray(json)) { - return 0; - } + ASSERT_RETURN(!cJSON_IsArray(json), 0, "Tried to get the length of a non-array json element."); size_t len = 0; cJSON* itr; cJSON_ArrayForEach(itr, json) { diff --git a/src/debug.h b/src/debug.h index 4283282..17c6a81 100644 --- a/src/debug.h +++ b/src/debug.h @@ -6,20 +6,48 @@ extern int g_debug_error_abort; #define LOG_INFO(...) do {\ - printf("[%s:%d] ", __FILE__, __LINE__);\ - printf("INFO | ");\ + printf("[%s:%d] INFO | ", __FILE__, __LINE__);\ printf(__VA_ARGS__);\ printf("\n");\ - fflush(stdout);\ } while(0) #define LOG_ERROR(...) do {\ - printf("[%s:%d] ", __FILE__, __LINE__);\ - printf("ERROR | ");\ + printf("[%s:%d] ERROR | ", __FILE__, __LINE__);\ printf(__VA_ARGS__);\ printf("\n");\ fflush(stdout);\ if(g_debug_error_abort != 0) abort();\ } while(0) +#define LOG_WARNING(...) do {\ + printf("[%s:%d] WARNING | ", __FILE__, __LINE__);\ + printf(__VA_ARGS__);\ + printf("\n");\ +} while(0) + + +#define RETURN_ERROR(__VALUE, ...) do {\ + LOG_ERROR(__VA_ARGS__);\ + return __VALUE;\ +} while(0) + +#define RETURN_WARNING(__VALUE, ...) do {\ + LOG_WARNING(__VA_ARGS__);\ + return __VALUE;\ +} while(0) + +#define ASSERT_RETURN(__ASSERT, __RETURN, ...) do {\ + if(!(__ASSERT)) {\ + LOG_ERROR(__VA_ARGS__);\ + return __RETURN;\ + }\ +} while(0) + +#define ASSERT_RETURN_WARN(__ASSERT, __RETURN, ...) do {\ + if(!(__ASSERT)) {\ + LOG_WARNING(__VA_ARGS__);\ + return __RETURN;\ + }\ +} while(0) + #endif // !_fencer_debug_h diff --git a/src/level.c b/src/level.c index 3e0b0bf..dc5b21d 100644 --- a/src/level.c +++ b/src/level.c @@ -54,12 +54,7 @@ size_t _count_layers(cJSON* layers, size_t* entities, size_t* automap) { Level* level_from_json(cJSON* json) { // allocate a new level struct Level* self = malloc(sizeof(Level)); - - // ensure allocations succeeded and initialize - if(self == NULL) { - LOG_ERROR("Failed to allocate level"); - return NULL; - } + ASSERT_RETURN(self != NULL, NULL, "Failed to allocate level object."); *self = (Level) { .asset_id = store_asset(self, &_deallocate_level), .transform = IdentityTransform @@ -109,9 +104,8 @@ Level* level_load(const char* level_id) { cJSON* level = load_json_from_file(filename); if(level == NULL) { - LOG_ERROR("Failed to load level file %s", filename); free(filename); - return NULL; + RETURN_ERROR(NULL, "Failed to load level from '%s'.", filename); } free(filename); diff --git a/src/sprite.c b/src/sprite.c index 76e2370..7d7420a 100644 --- a/src/sprite.c +++ b/src/sprite.c @@ -22,10 +22,7 @@ struct Sprite { Sprite* sprite_from_spritesheet(Spritesheet* sheet, size_t initial_frame) { Sprite* self = malloc(sizeof(Sprite)); - if(self == NULL) { - LOG_ERROR("Failed to allocate memory for new sprite"); - return NULL; - } + ASSERT_RETURN(self != NULL, NULL, "Failed to allocate memory for new sprite."); self->spritesheet = sheet; self->origin = (Vector){0.5f, 1.0f}; diff --git a/src/spritesheet.c b/src/spritesheet.c index 3b7fbdd..2c1ae15 100644 --- a/src/spritesheet.c +++ b/src/spritesheet.c @@ -1,6 +1,7 @@ #include "spritesheet.h" #include "assets.h" #include "render.h" +#include "debug.h" #include #include @@ -32,18 +33,14 @@ void _spritesheet_destroy_asset(void* self_void) { Spritesheet* spritesheet_load(const char* texture_name, IVector frame_resolution) { SDL_Texture* texture = IMG_LoadTexture(g_renderer, texture_name); - if(texture == NULL) - return NULL; - else - return spritesheet_from_texture(texture, frame_resolution); + ASSERT_RETURN(texture != NULL, NULL, "Failed to load texture from file %s.", texture_name); + return spritesheet_from_texture(texture, frame_resolution); } Spritesheet* spritesheet_from_texture(SDL_Texture* texture, IVector frame_resolution) { Spritesheet* self = malloc(sizeof(Spritesheet)); - if(self == NULL) { - return NULL; - } + ASSERT_RETURN(self != NULL, NULL, "Failed to allocate spritesheet."); self->asset_id = store_asset(self, _spritesheet_destroy_asset); diff --git a/src/tilemap.c b/src/tilemap.c index d5fc6a8..f14b526 100644 --- a/src/tilemap.c +++ b/src/tilemap.c @@ -26,31 +26,19 @@ struct Tilemap { Tilemap* tilemap_from_autolayer(cJSON* json) { cJSON* const tileset = cJSON_GetObjectItem(json, "__tilesetDefUid"); - if(tileset == NULL || !cJSON_IsNumber(tileset)) { - // no tileset means we cannot point at tile definitions later - LOG_ERROR("Could not find __tilesetDefUid while loading tilemap"); - return NULL; - } + ASSERT_RETURN(tileset != NULL && cJSON_IsNumber(tileset), NULL, "Could not find __tilesetDefUid while loading tilemap"); cJSON* const tiles = cJSON_GetObjectItem(json, "autoLayerTiles"); - if(tiles == NULL || !cJSON_IsArray(tiles)) { - LOG_ERROR("Could not find autoLayerTiles while loading tilemap"); - return NULL; - } + ASSERT_RETURN(tiles != NULL && cJSON_IsArray(tiles), NULL, "Could not find autoLayerTiles while loading tilemap"); cJSON* const wid = cJSON_GetObjectItem(json, "__cWid"); + ASSERT_RETURN(wid != NULL && cJSON_IsNumber(wid), NULL, "Could not find __cWid while loading tilemap"); + cJSON* const hei = cJSON_GetObjectItem(json, "__cHei"); - if(wid == NULL || hei == NULL || !cJSON_IsNumber(wid) || !cJSON_IsNumber(hei)) { - // no width and height mean we cannot allocate the tile map - LOG_ERROR("Could not find __cWid or __cHei while loading tilemap"); - return NULL; - } + ASSERT_RETURN(hei != NULL && cJSON_IsNumber(hei), NULL, "Could not find __cHei while loading tilemap"); + cJSON* const grid = cJSON_GetObjectItem(json, "__gridSize"); - if(grid == NULL || !cJSON_IsNumber(grid)) { - // can't know how to scale sprites - LOG_ERROR("Could not find __gridSize while loading tilemap"); - return NULL; - } + ASSERT_RETURN(grid != NULL && cJSON_IsNumber(grid), NULL, "Could not find __gridSize while loading tilemap"); // the minimum requirements for a valid tilemap are met @@ -69,8 +57,7 @@ Tilemap* tilemap_from_autolayer(cJSON* json) { if(self->map == NULL) { tileset_destroy(self->set); free(self); - LOG_ERROR("Failed to allocate map memory"); - return NULL; + RETURN_ERROR(NULL, "Failed to allocate map memory"); } const double px_to_ws = 1.0 / grid->valuedouble; diff --git a/src/tileset.c b/src/tileset.c index a58b5e8..1e68a89 100644 --- a/src/tileset.c +++ b/src/tileset.c @@ -3,12 +3,13 @@ #include "spritesheet.h" #include "assets.h" #include "render.h" +#include "shape.h" #include "SDL2/SDL_image.h" struct TileDef { size_t tid; Sprite* sprite; - // Shape* collision; + Shape* collision; }; struct Tileset { @@ -77,37 +78,31 @@ void _tileset_store(Tileset* self) { Tileset* tileset_from_json(cJSON* json) { cJSON* uid = cJSON_GetObjectItem(json, "uid"); - if(uid == NULL || !cJSON_IsNumber(uid)) { - LOG_ERROR("Failed to find uid while loading tileset"); - return NULL; - } + ASSERT_RETURN(uid != NULL && cJSON_IsNumber(uid), NULL, "Failed to find uid while loading tileset"); cJSON* path = cJSON_GetObjectItem(json, "relPath"); - if(path == NULL || !cJSON_IsString(path)) { - LOG_ERROR("Failed to find relPath while loading tileset"); - return NULL; - } + ASSERT_RETURN(path != NULL && cJSON_IsString(path), NULL, "Failed to find relPath while loading tileset"); cJSON* gridsize = cJSON_GetObjectItem(json, "tileGridSize"); - if(gridsize == NULL || !cJSON_IsNumber(gridsize)) { - LOG_ERROR("Failed to find tileGridSize while loading tileset"); - return NULL; - } + ASSERT_RETURN(gridsize != NULL && cJSON_IsNumber(gridsize), NULL, "Failed to find tileGridSize while loading tileset"); SDL_Surface* atlas_surface = IMG_Load(path->valuestring); - if(atlas_surface == NULL) { - LOG_ERROR("Failed to load atlas image while loading tileset"); - return NULL; - } + ASSERT_RETURN(atlas_surface != NULL, NULL, "Failed to load atlas image while loading tileset"); Tileset* self = malloc(sizeof(Tileset)); + if(self != NULL) { + SDL_FreeSurface(atlas_surface); + RETURN_ERROR(NULL, "Failed to allocate space for new tileset."); + } + SDL_Texture* texture = SDL_CreateTextureFromSurface(g_renderer, atlas_surface); + if(texture == NULL) { + free(self); + SDL_FreeSurface(atlas_surface); + RETURN_ERROR(NULL, "Failed to convert atlas surface to texture"); + } IVector grid = {gridsize->valueint, gridsize->valueint}; - if(self == NULL) { - LOG_ERROR("Failed to allocate space for Tileset"); - return NULL; - } _tileset_store(self); *self = (Tileset) { .uid = uid->valueint, @@ -143,15 +138,10 @@ Tileset* tileset_load(size_t uid) { } cJSON* defs = cJSON_GetObjectItem(g_levels_json, "defs"); - if(defs == NULL) { - LOG_ERROR("Failed to find defs element in levels json"); - return NULL; - } + ASSERT_RETURN(defs != NULL, NULL, "Failed to find defs element in levels json."); + cJSON* tilesets = cJSON_GetObjectItem(defs, "tilesets"); - if(tilesets == NULL) { - LOG_ERROR("Failed to find tilesets def region in levels json"); - return NULL; - } + ASSERT_RETURN(tilesets != NULL, NULL, "Failed to find tileset defs region in levels json"); cJSON* tileset = NULL; cJSON_ArrayForEach(tileset, tilesets) { @@ -163,10 +153,7 @@ Tileset* tileset_load(size_t uid) { } } - if(tileset == NULL) { - LOG_ERROR("Failed to find a tileset with the uid matching %zu", uid); - return NULL; - } + ASSERT_RETURN(tileset != NULL, NULL, "Failed to find a tileset with the uid matching %zu", uid); return tileset_from_json(tileset); }