Internal vs External Mapping of IDs to file paths from function perspective

An sf::Sprite can share the same sf::Texture object with multiple sf::Sprite objects, so I want to design a Texture Manager to not the same texture multiple times.

I’m using an identifier for referring to textures. A TextureID maps a texture to the file path corresponding to the file that contains the texture:

std::filesystem::path mapIdToFilepath(TextureID id);

In TextureManager I want to have a member function loadTexture(), I’m thinking either:

  1. having the loadTexture() accept a TextureID:

    sf::Texture& TextureManager::loadTexture(TextureID id);
    

    The function must then internally translate the identifier TextureID to the texture file path by calling mapIdToFilepath().

  2. or accepting the texture’s file path as argument:

    sf::Texture& TextureManager::loadTexture(std::filesystem::path filepath);
    

    The client code that calls this function must translate the identifier TextureID to the texture file path. However, this function doesn’t have to know about the existence of mapIdToFilepath because the mapping is done externally.

I think the first approach is more convenient but it couples TextureManager to mapIdToFilepath() because it internally does the TextureID to file path translation.

From an architectural perspective, what are the aspects I should keep in mind when considering these two different approaches?

Answer

I assume, in a broad aspect, you’re looking for something like an Asset Manager to load your assets (be it textures, sounds or fonts) only once and use them everywhere. You can use something I used long ago. Make an Asset Manager class which will have your textures in a map. Something like this:

class TexManager
{
public:

    TexManager* tex()  //to access your assets without creating multiple instances of this class
    {
         static Texmanager texMan;
         return &texMan;
    }

    void loadTexture(std::string name, std::string filepath) //to load textures
    { 
         sf::Texture tmp;
         tmp.loadFromFile(filepath);
         texMap.insert(std::make_pair(name, tmp));
    }

    sf::Texture& getTexture(st::string name) //to retrieve textures
    { 
         return texMap.at(name);
    }

private:
    std::map<std::string, sf::Texture> texMap;
}

Don’t use the code as it is since you’ll need to add conditionals for failed loading or incorrect key value for the map. Please let me know if you need something else or if I have answered incorrectly. Thank you. 🙂