diff --git a/source/code/main.cpp b/source/code/main.cpp index 89169b9..2b4df50 100644 --- a/source/code/main.cpp +++ b/source/code/main.cpp @@ -249,7 +249,7 @@ static void NFont_Write(SDL_Renderer* target, int x, int y, const char* text) { SDL_Window* sdlWindow; -std::unique_ptr dataHolder; +sago::SagoDataHolder dataHolder; void ResetFullscreen() { Mix_HaltMusic(); //We need to reload all data in case the screen type changes. Music must be stopped before unload. @@ -259,8 +259,8 @@ void ResetFullscreen() { else { SDL_SetWindowFullscreen(sdlWindow, 0); } - dataHolder.reset(new sago::SagoDataHolder(globalData.screen)); - globalData.spriteHolder.reset(new sago::SagoSpriteHolder( *(dataHolder.get()) ) ); + dataHolder.invalidateAll(globalData.screen); + globalData.spriteHolder.reset(new sago::SagoSpriteHolder( dataHolder ) ); InitImages(*(globalData.spriteHolder.get()) ); SDL_ShowCursor(SDL_DISABLE); } diff --git a/source/code/sago/SagoDataHolder.cpp b/source/code/sago/SagoDataHolder.cpp index 97b8bdf..926a048 100644 --- a/source/code/sago/SagoDataHolder.cpp +++ b/source/code/sago/SagoDataHolder.cpp @@ -49,33 +49,54 @@ static void printFileWeLoad(const std::string& value) { std::cout << "Loading " << value << "\n"; } +SagoDataHolder::SagoDataHolder() { + data = new SagoDataHolderData(); +} + SagoDataHolder::SagoDataHolder(SDL_Renderer* renderer) { data = new SagoDataHolderData(); data->renderer = renderer; } -SagoDataHolder::~SagoDataHolder() { +void SagoDataHolder::invalidateAll(SDL_Renderer* renderer) { + invalidateAll(); + data->renderer = renderer; +} + +void SagoDataHolder::invalidateAll() { for (auto& item : data->textures) { SDL_DestroyTexture(item.second); } + data->textures.clear(); for (auto& item : data->music) { Mix_FreeMusic(item.second); } + data->music.clear(); for (auto& item : data->sounds) { Mix_FreeChunk(item.second); } + data->sounds.clear(); for (auto& item : data->fonts) { for (auto& item2 : item.second) { TTF_CloseFont(item2.second); } } + data->fonts.clear(); for (auto& item : data->rwOpsToFree) { SDL_FreeRW(item); } + data->rwOpsToFree.clear(); +} + +SagoDataHolder::~SagoDataHolder() { + invalidateAll(); delete data; } SDL_Texture* SagoDataHolder::getTexturePtr(const std::string& textureName) const { + if (!data->renderer) { + throw std::runtime_error("SagoDataHolder used before setting the renderer"); + } SDL_Texture* ret = data->textures[textureName]; if (ret) { return ret; diff --git a/source/code/sago/SagoDataHolder.hpp b/source/code/sago/SagoDataHolder.hpp index f1cadff..389d098 100644 --- a/source/code/sago/SagoDataHolder.hpp +++ b/source/code/sago/SagoDataHolder.hpp @@ -36,9 +36,14 @@ namespace sago { class SagoDataHolder { public: + /** + * The renderer must be set before requesting a texture. + * If the constructor without elements is used then invalidateAll(SDL_Renderer*) must be called before getTexturePtr + */ + SagoDataHolder(); SagoDataHolder(SDL_Renderer* renderer); /** - * Return a pointer to the given texture. The pointer is valid for the lifetime of SagoDataHolder object it was taken from. + * Return a pointer to the given texture. The pointer is valid for the lifetime of SagoDataHolder object it was taken from or invalidateAll is called. * @param textureName Name of the texture * @return Pointer to the loaded texture */ @@ -47,6 +52,17 @@ public: Mix_Music* getMusicPtr(const std::string &musicName) const; Mix_Chunk* getSoundPtr(const std::string &soundName) const; void setVerbose(bool value); + /** + * Invalidates all pointers returned by any of the get variables + */ + void invalidateAll(); + /** + * Invalidates all pointers returned by any of the get variables. + * Also sets a new renderer. + * + * Setting a new renderer might cause all old textures to no longer match the renderer format. + */ + void invalidateAll(SDL_Renderer* renderer); virtual ~SagoDataHolder(); private: SagoDataHolder(const SagoDataHolder& base) = delete;