From 762d165cd14f0d4423c2de6f7f1659f7b36a4fd3 Mon Sep 17 00:00:00 2001 From: Sara Date: Mon, 27 Oct 2025 21:41:45 +0100 Subject: [PATCH] feat: added external resource management --- resources.cpp | 49 ++++++++++++++++++++++++++++++++++++++++++++++--- resources.h | 16 +++++++++++++++- 2 files changed, 61 insertions(+), 4 deletions(-) diff --git a/resources.cpp b/resources.cpp index 2798d80..8e6cf05 100644 --- a/resources.cpp +++ b/resources.cpp @@ -4,18 +4,34 @@ #include #include #include +#include + +#ifndef CERA_RESOURCE_REGISTRY_SIZE +#define CERA_RESOURCE_REGISTRY_SIZE 64 +#endif namespace cera { +struct ResourceRegistry { + void *data; + DestructorFn destructor; +}; + TTF_Font *defaultFont[FONT_MAX]; TTF_TextEngine *textEngine = nullptr; +ResourceRegistry resources[CERA_RESOURCE_REGISTRY_SIZE]{}; +size_t usedResources{0}; + void SetDefaultFont(char const *path) { - defaultFont[FONT_DEFAULT] = TTF_OpenFont(path, cera::baseFontSize * 5); - if (defaultFont[FONT_DEFAULT] == nullptr) { + // LOAD REGULAR FONT + defaultFont[FONT_REGULAR] = TTF_OpenFont(path, cera::baseFontSize * 5); + if (defaultFont[FONT_REGULAR] == nullptr) { SDL_LogError(SDL_LOG_CATEGORY_ERROR, "TTF_OpenFont failed: Failed to load default font '%s': %s", path, SDL_GetError()); exit(6); } - TTF_SetFontHinting(defaultFont[FONT_DEFAULT], TTF_HINTING_LIGHT_SUBPIXEL); + TTF_SetFontHinting(defaultFont[FONT_REGULAR], TTF_HINTING_LIGHT_SUBPIXEL); + StoreResource(defaultFont[FONT_REGULAR], (DestructorFn)&TTF_CloseFont); + // LOAD BOLD FONT defaultFont[FONT_BOLD] = TTF_OpenFont(path, cera::baseFontSize * 5); if (defaultFont[FONT_BOLD] == nullptr) { SDL_LogError(SDL_LOG_CATEGORY_ERROR, "TTF_OpenFont failed: Failed to load default bold font '%s': %s", path, SDL_GetError()); @@ -23,6 +39,33 @@ void SetDefaultFont(char const *path) { } TTF_SetFontHinting(defaultFont[FONT_BOLD], TTF_HINTING_LIGHT_SUBPIXEL); TTF_SetFontStyle(defaultFont[FONT_BOLD], TTF_STYLE_BOLD); + StoreResource(defaultFont[FONT_BOLD], (DestructorFn)&TTF_CloseFont); SDL_Log("SetDefaultFont: Success"); } + +void StoreResource(void *data, DestructorFn destructor) { + for (size_t i{0}; i < usedResources; ++i) { + if(resources[i].data == nullptr) { + resources[i].data = data; + resources[i].destructor = destructor; + return; + } + } + if(usedResources < CERA_RESOURCE_REGISTRY_SIZE) { + resources[usedResources].data = data; + resources[usedResources].destructor = destructor; + ++usedResources; + return; + } + SDL_LogError(SDL_LOG_CATEGORY_ERROR, "Failed to register resource, expect memory leaks. Consider using less resources or defining a higher CERA_RESOURCE_REGISTRY_SIZE at compile time"); +} + +void CleanupResources() { + for (size_t i{0}; i < usedResources; ++i) { + if(resources[i].data) { + resources[i].destructor(resources[i].data); + } + } + usedResources = 0; +} } diff --git a/resources.h b/resources.h index 3adc3cf..4d649ca 100644 --- a/resources.h +++ b/resources.h @@ -1,11 +1,13 @@ #ifndef RESOURCES_H #define RESOURCES_H +#include "SDL3/SDL_render.h" +#include #include namespace cera { enum Font { - FONT_DEFAULT = 0, + FONT_REGULAR = 0, FONT_BOLD = 1, FONT_MAX }; @@ -13,7 +15,19 @@ enum Font { extern TTF_TextEngine *textEngine; extern TTF_Font *defaultFont[FONT_MAX]; +typedef void (*DestructorFn)(void* data); + void SetDefaultFont(char const *path); +void StoreResource(void *data, DestructorFn destructor); +void CleanupResources(); + +static inline SDL_Texture *LoadAndStoreTexture(SDL_Renderer *renderer, char const *path) { + if(SDL_Texture *texture{IMG_LoadTexture(renderer, path)}) { + StoreResource(texture, (DestructorFn)&SDL_DestroyTexture); + return texture; + } + return nullptr; +} } #endif // !RESOURCES_H