I'm new to C++ and SDL, and I've written a Texture
manager class whose purpose is to help me manage sprites and other textures. I have a dispose
method which unloads all the textures from a map container. It works correctly but I'd like to ask if I am not causing any memory leaks, or other pointer related issues.
TextureManager.h
class TextureManager
{
public:
bool load(std::string fileName, std::string id, SDL_Renderer* pRenderer);
void draw(std::string id, int x, int y, int width, int height, int scale, SDL_Renderer* pRenderer,
SDL_RendererFlip flip = SDL_FLIP_NONE);
void drawFrame(std::string id, int x, int y, int width, int height, int scale, int currentRow, int currentFrame, SDL_Renderer* pRenderer,
SDL_RendererFlip flip = SDL_FLIP_NONE);
void dispose();
std::map<std::string, SDL_Texture*> m_textureMap;
static TextureManager* Instance()
{
if(s_pInstance == 0)
{
std::cout << "Created TextureManager singleton\n";
s_pInstance = new TextureManager();
return s_pInstance;
}
//point to same object (singleton pattern)
return s_pInstance;
}
private:
TextureManager(){}
static TextureManager* s_pInstance;
bool hasDisposed = false;
};
typedef TextureManager TheTextureManager; //should be used when calling singleton
#endif // TEXTUREMANAGER_H
TextureManager.cpp
#include "TextureManager.h"
TextureManager* TextureManager::s_pInstance = 0;
bool TextureManager::load(std::string fileName, std::string id, SDL_Renderer* pRenderer){
std::cout << "\n\t\\\\\\\\\TextureManager :\n";
SDL_Surface* pTempSurface = IMG_Load(fileName.c_str());
if(pTempSurface == 0){
std::cerr << "ERROR : Couldn't load Texture from file : " <<
fileName.c_str() << std::endl;
return false;
}
SDL_Texture* pTexture = SDL_CreateTextureFromSurface(pRenderer, pTempSurface);
//dispose Surface (not used)
SDL_FreeSurface(pTempSurface);
//everything OK, add Texture to map
if(pTexture != 0){
std::cout << "Loaded Texture from file : " << fileName << " successfully\n";
m_textureMap[id] = pTexture;
std::cout << "Allocated memory for : " << id << " at : " << pTexture << "\n";
return true;
}
//something wen't wrong...
std::cerr << "ERROR : couldn't register Texture from file : " <<
fileName.c_str() << std::endl;
return false;
}
void TextureManager::draw(std::string id, int x, int y, int width, int height, int scale, SDL_Renderer* pRenderer, SDL_RendererFlip flip){
SDL_Rect srcRect;
SDL_Rect destRect;
srcRect.x = 0;
srcRect.y = 0;
srcRect.w = width;
srcRect.h = height;
destRect.w = width * scale;
destRect.h = height * scale;
destRect.x = x;
destRect.y = y;
SDL_RenderCopyEx(pRenderer, m_textureMap[id],
&srcRect, &destRect, 0, 0, flip);
}
void TextureManager::drawFrame(std::string id, int x, int y, int width, int height, int scale, int currentRow, int currentFrame, SDL_Renderer* pRenderer, SDL_RendererFlip flip){
SDL_Rect srcRect;
SDL_Rect destRect;
srcRect.x = width * currentFrame;
srcRect.y = height * (currentRow - 1);
srcRect.w = width;
destRect.w = width * scale;
srcRect.h = height;
destRect.h = height * scale;
destRect.x = x;
destRect.y = y;
SDL_RenderCopyEx(pRenderer, m_textureMap[id],
&srcRect, &destRect, 0, 0, flip);
}
void TextureManager::dispose(){
if(m_textureMap.empty())//no textures were added
{
std::cout << "no need to unload textures : no textures loaded !\n";
return;
}
if(hasDisposed)
{
std::cout << "Textures have already been disposed !\n";
return;
}
//delete textures
std::cout << "\nDeleting textures : \n\n";
typedef std::map<std::string, SDL_Texture*>::iterator TextureIterator;
for(TextureIterator it = m_textureMap.begin(); it != m_textureMap.end(); ++it){
std::cout << "\ttextureMap [ID==" << it->first << "]" << " [allocation address==" << it->second << "] ";
SDL_DestroyTexture(it->second);//destroy texture
std::cout << "--> destroyed !\n";
}
hasDisposed = true;//cannot dispose more then once!
}