diff --git a/src/asset_manager.c b/src/asset_manager.c index d56dece..6603605 100644 --- a/src/asset_manager.c +++ b/src/asset_manager.c @@ -1,11 +1,89 @@ #include "asset_manager.h" +#include +#include +#include "linked_list.h" +#include "memory_alloc.h" + +asset_t *create_asset(asset_type_t asset_type) +{ + asset_t *asset = malloc(sizeof(asset_t)); + + asset->type = asset_type; + asset->nb_refs = 1; + + return asset; +} + +void destroy_asset(asset_t *asset) +{ + free(asset->name); + + switch(asset->type) + { + case TEXTURE: + SDL_DestroyTexture(asset->data.texture); + + default: + return; + } + + free(asset); +} + void asset_manager_init(asset_manager_t *asset_manager) { + linked_list_init(&asset_manager->assets, sizeof(asset_t), (deleter_t)destroy_asset); } void asset_manager_exit(asset_manager_t *asset_manager) { + linked_list_clear(&asset_manager->assets); +} +// Only for this file +// No args +static inline bool condition_is_asset_unused(elem_t *elem, va_list args __attribute__((unused))) +{ + return !((asset_t *)elem->data)->nb_refs; +} + +inline void asset_manager_collect_garbage(asset_manager_t *asset_manager) +{ + linked_list_remove_if(&asset_manager->assets, condition_is_asset_unused); +} + +// Only for this file +// Arg : const char *asset_name +static inline bool condition_is_asset_name(elem_t *elem, va_list args) +{ + return !strcmp(((asset_t *)elem->data)->name, va_arg(args, const char *)); +} + +void asset_manager_load_asset(asset_manager_t *asset_manager, const char *asset_name, asset_type_t asset_type) +{ + asset_t *asset = linked_list_get_if(&asset_manager->assets, condition_is_asset_name, asset_name); + if(asset) + { + asset->nb_refs++; + return; + } + + asset = create_asset(asset_type); + asset->name = malloc(strlen(asset_name) + 1); + strcpy(asset->name, asset_name); + + // XXX LOAD ASSET FROM FILE XXX + + linked_list_push_back(&asset_manager->assets, asset); +} + +void asset_manager_let_go_asset(asset_manager_t *asset_manager, const char *asset_name) +{ + asset_t *asset = linked_list_get_if(&asset_manager->assets, condition_is_asset_name, asset_name); + if(asset) + { + asset->nb_refs--; + } } texture_t *asset_manager_get_texture(asset_manager_t *asset_manager, const char *asset_name) diff --git a/src/headers/asset_manager.h b/src/headers/asset_manager.h index 52fc530..636dca8 100644 --- a/src/headers/asset_manager.h +++ b/src/headers/asset_manager.h @@ -8,24 +8,36 @@ typedef SDL_Texture texture_t; +typedef enum asset_type_t { + TEXTURE +} asset_type_t; + typedef struct asset_t { + char *name; + union { texture_t *texture; } data; - enum { - TEXTURE - } type; + asset_type_t type; size_t nb_refs; } asset_t; +asset_t *create_asset(asset_type_t asset_type); + +void destroy_asset(asset_t *asset); + typedef struct asset_manager_t { linked_list_t assets; } asset_manager_t; void asset_manager_init(asset_manager_t *asset_manager); void asset_manager_exit(asset_manager_t *asset_manager); +void asset_manager_collect_garbage(asset_manager_t *asset_manager); + +void asset_manager_load_asset(asset_manager_t *asset_manager, const char *asset_name, asset_type_t asset_type); +void asset_manager_let_go_asset(asset_manager_t *asset_manager, const char *asset_name); texture_t *asset_manager_get_texture(asset_manager_t *asset_manager, const char *asset_name); void asset_manager_draw_texture(texture_t *texture, rect_t *src_rect, rect_t *dst_rect, bool flip);