From 67b751c1362cb87698bfe803f074aff32a688d60 Mon Sep 17 00:00:00 2001 From: Sara Date: Mon, 6 Nov 2023 21:15:34 +0100 Subject: [PATCH 1/4] list_empty will now deallocate data completely --- src/list.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/list.c b/src/list.c index cca816e..6ec9a6a 100644 --- a/src/list.c +++ b/src/list.c @@ -37,8 +37,8 @@ List list_copy(const List* source) { void list_empty(List* self) { if(self->data == NULL || self->cap == 0) return; - self->data = realloc(self->data, LIST_DEFAULT_RESERVE * self->element_size); - self->cap = LIST_DEFAULT_RESERVE; + self->data = NULL; + self->cap = 0; self->len = 0; } @@ -51,7 +51,11 @@ void list_reserve(List* self, size_t at_least) { new_cap *= 2; } - void* new = realloc(self->data, new_cap * self->element_size); + void* new; + if(self->data == NULL) + new = malloc(new_cap * self->element_size); + else + new = realloc(self->data, new_cap * self->element_size); ASSERT_RETURN(new != NULL,, "Failed to reserve space for %zu extra elements in list", new_cap); self->data = new; From 6e61a7666ad03071114007fcd0e01116b4cc5f7e Mon Sep 17 00:00:00 2001 From: Sara Date: Mon, 6 Nov 2023 21:16:06 +0100 Subject: [PATCH 2/4] declared Asset trait combining Drop with a getter and setter for an asset id --- src/asset.h | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 src/asset.h diff --git a/src/asset.h b/src/asset.h new file mode 100644 index 0000000..c113ed5 --- /dev/null +++ b/src/asset.h @@ -0,0 +1,34 @@ +#ifndef _fencer_asset_h +#define _fencer_asset_h + +#include "drop.h" +#include "typeclass_helpers.h" +#include + +typedef uintptr_t asset_id; + +typedef struct { + asset_id (*const get_id)(void*); + void (*const set_id)(void*, asset_id); +} IAsset; + +typedef struct Asset { + void* data; + IAsset const* tc; + IDrop const* drop; +} Asset; + +#define impl_Asset_for(T, get_id_f, set_id_f)\ +static inline Asset T##_as_Asset(T* x) {\ + TC_FN_TYPECHECK(asset_id, get_id_f, T*);\ + TC_FN_TYPECHECK(void, set_id_f, T*, asset_id);\ + TC_FN_TYPECHECK(Drop, T##_as_Drop, T*);\ + static IAsset tc = (IAsset){\ + .get_id = (asset_id(*const)(void*)) get_id_f,\ + .set_id = (void(*const)(void*,asset_id)) set_id_f,\ + };\ + IDrop const* drop = T##_as_Drop(x).tc;\ + return (Asset){.data=x, .tc=&tc, .drop=drop};\ +} + +#endif // !_fencer_asset_h From 63713a59e733ff3272407672dd76a79f764bce25 Mon Sep 17 00:00:00 2001 From: Sara Date: Mon, 6 Nov 2023 21:16:21 +0100 Subject: [PATCH 3/4] assets now integrate Asset trait --- src/assets.c | 115 +++++++++++++++------------------------------- src/assets.h | 5 +- src/level.c | 19 +++++--- src/level.h | 15 ++++++ src/spritesheet.c | 16 +++++-- src/spritesheet.h | 15 ++++++ 6 files changed, 94 insertions(+), 91 deletions(-) diff --git a/src/assets.c b/src/assets.c index 9740593..6820b20 100644 --- a/src/assets.c +++ b/src/assets.c @@ -1,21 +1,13 @@ #include "assets.h" #include "debug.h" +#include "list.h" #include #include #include -typedef -struct AssetData { - void* asset; - asset_id id; - AssetDestructor destructor; -} AssetData; - cJSON* g_levels_json; -static AssetData* _assets = NULL; -static size_t _assets_len = 0; -static size_t _assets_cap = 0; +static List _assets; static asset_id _next_id = 0; static @@ -34,26 +26,9 @@ void read_file(FILE* fp, char* out_buffer, size_t out_size) { fseek(fp, start, SEEK_SET); } -static -void _resize_if_needed(size_t requested_len) { - if(requested_len < _assets_cap) { - return; // not needed. - } - - size_t new_cap = _assets_cap ? _assets_cap : 8; - while(new_cap < requested_len) { - new_cap *= 2; - } - AssetData* new_assets = realloc(_assets, new_cap * sizeof(AssetData)); - if(new_assets != NULL) { - _assets = new_assets; - _assets_cap = new_cap; - } -} - void assets_init() { LOG_INFO("assets_init"); - _assets = malloc(_assets_cap * sizeof(AssetData)); + _assets = list_from_type(Asset); _next_id = 1; g_levels_json = load_json_from_file("assets/levels/levels.ldtk"); @@ -62,59 +37,40 @@ void assets_init() { // clear all assets without shrinking the assets array. static void _empty_assets() { - AssetData* start = _assets; - AssetData* end = _assets + _assets_len; - - for(AssetData* asset = start; asset < end; ++asset) { - asset->destructor(asset->asset); + list_foreach(Asset*, asset, &_assets) { + asset->drop->drop(asset->data); } - _assets_len = 0; + list_empty(&_assets); } void assets_clean() { _empty_assets(); - - free(_assets); - _assets_len = 0; - _assets_cap = 0; - _assets = NULL; - cJSON_Delete(g_levels_json); g_levels_json = NULL; } void assets_reset() { _empty_assets(); - - size_t desired = 8; - AssetData* new = realloc(_assets, desired * sizeof(AssetData)); - if(new == NULL) - return; - _assets_cap = desired; - _assets = new; } -asset_id store_asset(void* asset, AssetDestructor destructor) { - _resize_if_needed(_assets_len + 1); - AssetData* data = _assets + _assets_len; - - data->asset = asset; - data->destructor = destructor; - data->id = _next_id; - - ++_next_id; - ++_assets_len; - - return data->id; +asset_id store_asset(Asset asset) { + list_reserve(&_assets, _assets.len + 1); + size_t index = list_add(&_assets, &asset); + Asset* new_asset = list_at_as(Asset, &_assets, index); + asset_id id = _next_id++; + new_asset->tc->set_id(new_asset->data, id); + asset_id actual_id = new_asset->tc->get_id(new_asset->data); + ASSERT_RETURN(actual_id == id,actual_id, "ID stored in asset not the same as the expected id"); + return actual_id; } static -AssetData* _internal_get_by_id(asset_id id) { +Asset* _internal_get_by_id(asset_id id) { 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) { - return _assets + i; + list_foreach(Asset*, asset, &_assets) { + if(asset->tc->get_id(asset->data) == id) { + return asset; } } @@ -122,16 +78,15 @@ AssetData* _internal_get_by_id(asset_id id) { } void* get_asset(asset_id id) { - AssetData* found = _internal_get_by_id(id); + Asset* found = _internal_get_by_id(id); ASSERT_RETURN(found != NULL, NULL, "Failed to find asset with id %zu.", id); - - return found; + return found->data; } asset_id get_asset_id(void* asset) { - for(size_t i = 0; i < _assets_len; ++i) { - if(_assets[i].asset == asset) { - return _assets[i].id; + list_foreach(Asset*, asset, &_assets) { + if(asset->data == asset) { + return asset->tc->get_id(asset->data); } } @@ -139,16 +94,20 @@ asset_id get_asset_id(void* asset) { } void free_asset(asset_id id) { - AssetData* found = _internal_get_by_id(id); - + Asset* found; + size_t found_index; + for(size_t i = 0; i < _assets.len; ++i) { + found = list_at_as(Asset, &_assets, i); + if(found->tc->get_id(found->data) == id) { + found_index = i; + break; + } else { + found = NULL; + } + } ASSERT_RETURN(found != NULL,, "Attempt to free nonexistent asset."); - - found->destructor(found->asset); - - AssetData* next = found + 1; - size_t dif = next - (_assets + _assets_len); - memmove(found, next, dif); - --_assets_len; + found->drop->drop(found->data); + list_erase(&_assets, found_index); } cJSON* load_json_from_file(const char* filename) { diff --git a/src/assets.h b/src/assets.h index a1d888c..f55d836 100644 --- a/src/assets.h +++ b/src/assets.h @@ -2,11 +2,12 @@ #define _fencer_assets_h #include "vmath.h" +#include "drop.h" +#include "asset.h" #include #include typedef void(*AssetDestructor)(void*); -typedef uintptr_t asset_id; extern cJSON* g_levels_json; @@ -19,7 +20,7 @@ void assets_clean(); void assets_reset(); // Submit an object to be managed as an asset. If the destructor is NULL, free will be used. // Returns zero if asset could not be stored. -asset_id store_asset(void* asset, AssetDestructor destructor); +asset_id store_asset(Asset drop); // Get an asset already submitted to the asset manager. // Returns 0 if asset does not exist. void* get_asset(asset_id id); diff --git a/src/level.c b/src/level.c index db8d5ec..27ab1ca 100644 --- a/src/level.c +++ b/src/level.c @@ -20,15 +20,11 @@ struct Level { Vector player_start; }; -static -void _deallocate_level(void* self_void) { - Level* self = self_void; - +void _internal_level_destroy(Level* self) { for(size_t map_index = 0; map_index < self->tilemaps_len; ++map_index) { physics_world_remove_map(self->tilemaps[map_index]); tilemap_destroy(self->tilemaps[map_index]); } - free(self); } @@ -62,7 +58,7 @@ Level* level_from_json(cJSON* json) { Level* self = malloc(sizeof(Level)); ASSERT_RETURN(self != NULL, NULL, "Failed to allocate level object."); *self = (Level) { - .asset_id = store_asset(self, &_deallocate_level), + .asset_id = 0, .transform = IdentityTransform }; @@ -98,6 +94,7 @@ Level* level_from_json(cJSON* json) { } } + store_asset(Level_as_Asset(self)); return self; } @@ -139,3 +136,13 @@ Tilemap* level_get_tilemap_layer(Level* self, size_t layer) { size_t level_get_tilemap_count(Level* self) { return self->tilemaps_len; } + +asset_id level_get_asset_id(Level* self) { + LOG_INFO("(get) level asset id %zu", self->asset_id); + return self->asset_id; +} + +void level_set_asset_id(Level* self, asset_id id) { + self->asset_id = id; + LOG_INFO("(set) level asset id %zu", self->asset_id); +} diff --git a/src/level.h b/src/level.h index 6832517..ca8e414 100644 --- a/src/level.h +++ b/src/level.h @@ -1,6 +1,7 @@ #ifndef _fencer_level_h #define _fencer_level_h +#include "asset.h" #include "sprite.h" #include #include @@ -21,4 +22,18 @@ extern void level_draw(Level* self); extern Tilemap* level_get_tilemap_layer(Level* self, size_t layer); extern size_t level_get_tilemap_count(Level* self); +extern asset_id level_get_asset_id(Level* self); +extern void level_set_asset_id(Level* self, asset_id id); + +extern void _internal_level_destroy(Level* self); + +impl_Drop_for(Level, + _internal_level_destroy +) + +impl_Asset_for(Level, + level_get_asset_id, + level_set_asset_id +) + #endif // !_fencer_level_h diff --git a/src/spritesheet.c b/src/spritesheet.c index 7fcadd7..a53c81c 100644 --- a/src/spritesheet.c +++ b/src/spritesheet.c @@ -24,11 +24,9 @@ struct Spritesheet { float frame_interval; }; -static -void _spritesheet_destroy_asset(void* self_void) { - Spritesheet* self = self_void; +void _internal_spritesheet_destroy(Spritesheet* self) { SDL_DestroyTexture(self->texture); - free(self_void); + free(self); } Spritesheet* spritesheet_load(const char* texture_name, IVector frame_resolution) { @@ -42,7 +40,7 @@ Spritesheet* spritesheet_from_texture(SDL_Texture* texture, IVector frame_resolu ASSERT_RETURN(self != NULL, NULL, "Failed to allocate spritesheet."); - self->asset_id = store_asset(self, _spritesheet_destroy_asset); + self->asset_id = store_asset(Spritesheet_as_Asset(self)); // Load the texture image and query it's size self->texture = texture; @@ -78,3 +76,11 @@ SDL_Rect spritesheet_get_frame_rect(const Spritesheet* self, size_t index) { IVector spritesheet_get_resolution(const Spritesheet* self) { return self->resolution; } + +asset_id spritesheet_get_asset_id(Spritesheet* self) { + return self->asset_id; +} + +void spritesheet_set_asset_id(Spritesheet* self, asset_id id) { + self->asset_id = id; +} diff --git a/src/spritesheet.h b/src/spritesheet.h index e650bb4..4065b83 100644 --- a/src/spritesheet.h +++ b/src/spritesheet.h @@ -1,6 +1,7 @@ #ifndef _fencer_spritesheet_h #define _fencer_spritesheet_h +#include "asset.h" #include "vmath.h" #include @@ -20,4 +21,18 @@ extern SDL_Texture* spritesheet_get_texture(const Spritesheet* self); extern SDL_Rect spritesheet_get_frame_rect(const Spritesheet* self, size_t index); extern IVector spritesheet_get_resolution(const Spritesheet* self); +extern asset_id spritesheet_get_asset_id(Spritesheet* self); +extern void spritesheet_set_asset_id(Spritesheet* self, asset_id id); + +extern void _internal_spritesheet_destroy(Spritesheet* self_void); + +impl_Drop_for(Spritesheet, + _internal_spritesheet_destroy +) + +impl_Asset_for(Spritesheet, + spritesheet_get_asset_id, + spritesheet_set_asset_id +) + #endif // !_fencer_spritesheet_h From 65ee914e52028fa9b49995621e48065d9019fb07 Mon Sep 17 00:00:00 2001 From: Sara Date: Tue, 7 Nov 2023 20:40:32 +0100 Subject: [PATCH 4/4] removed extranious player.h include from collision.c --- src/collision.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/collision.c b/src/collision.c index ebfd434..9cede9a 100644 --- a/src/collision.c +++ b/src/collision.c @@ -1,6 +1,5 @@ #include "collision.h" #include "debug.h" -#include "player.h" #include "vmath.h" #include "rigidbody.h"