Thread: Patterns and anti-patterns

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Now a resource manager needs to be globally accesible
    This assumption is the reason why singletons are used. But simple parameter passing and/or dependency injection make for better program structure IMO. So instead of being able to procure a resource manager anywhere, components that need one will need to have it passed in by whoever created them.

    Your unit tests will thank you.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  2. #2
    Internet Superhero
    Join Date
    Sep 2006
    Location
    Denmark
    Posts
    964
    Quote Originally Posted by CornedBee View Post
    This assumption is the reason why singletons are used. But simple parameter passing and/or dependency injection make for better program structure IMO. So instead of being able to procure a resource manager anywhere, components that need one will need to have it passed in by whoever created them.

    Your unit tests will thank you.
    I agree, the idea of a singleton wasn't appealing. But since i might have quite a few objects and methods that need to access resources, simply passing around the resource manager isn't ideal either.

    Here is what i ended up doing:

    Code:
    #ifndef RESOURCE_HPP
    #define RESOURCE_HPP
    
    #include <string>
    #include <map>
    #include <memory>
    
    template <class ResourceType>
    class Resource
    {
        public:
            template <class ResourceLoader>
            Resource(const std::string &p_path, ResourceLoader p_resourceloader) : m_path(p_path)
            {
                if(!m_resource_cache.Contains(m_path))
                {
                    m_resource_cache.AddResource(m_path, p_resourceloader(m_path));
                }
            }
            
            ResourceType& Get() const
            {
                return m_resource_cache.GetResource(m_path);
            }
            
        private:
            std::string m_path;
            
            class ResourceCache
            {
                public:
                    void AddResource(const std::string &p_path, std::unique_ptr<ResourceType> p_resource)
                    {
                        m_resourcemap[p_path] = std::move(p_resource);
                    }    
            
                    ResourceType& GetResource(const std::string &p_path) const
                    {
                        return *(m_resourcemap.at(p_path));
                    }
            
                    bool Contains(const std::string &p_path) const
                    {
                        return (m_resourcemap.end() != m_resourcemap.find(p_path));
                    }
            
                private:
                    std::map<std::string, std::unique_ptr<ResourceType> > m_resourcemap;
            };
            
            static ResourceCache m_resource_cache;
    };
    
    template<class ResourceType>
    typename Resource<ResourceType>::ResourceCache Resource<ResourceType>::m_resource_cache;
    
    #endif
    It's a slight variant of the third pattern i mentioned in the OP. To use it you need simply supply a path to whatever resource you want to load, and a functor/function that does the actual loading:

    Code:
    std::unique_ptr<sf::Texture> LoadTexture(const std::string &p_path)
    {
        std::unique_ptr<sf::Texture> texture(new sf::Texture);
        if(!texture->loadFromFile(p_path))
            throw std::runtime_error("Unable to load texture: " + p_path);
                
        return texture;
    }
    
    .....
    Resource<sf::Texture> texture(path, LoadTexture);
    FunctionThatNeedsTexture(texture.get());
    It's working out quite well so far, any thoughts?
    How I need a drink, alcoholic in nature, after the heavy lectures involving quantum mechanics.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Design patterns in C
    By sashaKap in forum C Programming
    Replies: 2
    Last Post: 04-26-2009, 08:32 AM
  2. c programming on patterns
    By himankinishah in forum C Programming
    Replies: 2
    Last Post: 01-27-2009, 03:54 PM
  3. Printing Patterns
    By ferniture in forum C Programming
    Replies: 11
    Last Post: 11-17-2008, 10:00 PM
  4. Creating Patterns
    By incognito in forum Game Programming
    Replies: 5
    Last Post: 03-16-2003, 09:02 AM
  5. Patterns
    By Unregistered in forum A Brief History of Cprogramming.com
    Replies: 6
    Last Post: 04-29-2002, 04:02 PM