dimanche 24 mai 2020

Inserting into templated resource holder - any design pattern to use?

I am wondering what's wrong with my design, and how to fix it.

I have a following (simplified) classes diagram:

enter image description here

And here's minimum possible code:

Resource holder:

template <typename Key, typename Resource>
class ResourceHolder {
public:
    template <typename... Args>
    void insert(const Key& key, Args&&... args) {
        // <resPtr points to a resource>
        resources.emplace(key, std::move(resPtr));
    }

    Resource& get(const Key& key) const {
        if (auto resource = resources.find(key); resource != std::end(resources)) {
            return *(resource->second);
        } throw std::invalid_argument{"No such resource id."};
    }

private:
    std::unordered_map<Key, std::unique_ptr<Resource>> resources;
};

ResourceManager:

class ResourceManager {
public:
    ResourceManager() {
        loadTextures();
        loadSounds();
    }

private:
    ResourceHolder<res::Texture, sf::Texture> textures;
    ResourceHolder<res::Sound, sf::SoundBuffer> sounds;

    void loadTextures() {
        textures.insert(res::Texture::Wizard, "wizard.png");
        textures.insert(res::Texture::Gray,   "gray.png");
        textures.insert(res::Texture::Orange, "orange.png");
    }

    void loadSounds() {
        sounds += ResourceInserter(res::Sound::Bullet, "boing.wav");
        sounds += ResourceInserter(res::Sound::Bing,   "boing_long.wav");
        sounds += ResourceInserter(res::Sound::Poof,   "poof.wav");
    }
};

Can you tell me what's wrong with the code from the OOP/design patterns stand-point and can you suggest a fix, please? Also, perhaps there's something confusing about the classes names?

I am particularly wondering about inserting resources into resource holders.

Currently, if I want to add a new ResourceHolder to a ResourceMananger, I need to do the following inside ResourceManager class:

  1. create new getter e.g. getImages()
  2. create new load function e.g. loadImages()
  3. call loadImages() in ResourceManager's constructor

Is it okay or bad design?

Aucun commentaire:

Enregistrer un commentaire