SFML - Resource Manager

Aug 11, 2013 at 8:52am
closed account (3qX21hU5)
So what do you guys think of this class? Anything missing really? It's main use it to manage the heavyweight resources in SFML (Textures, Fonts and Soundbuffer. It can even work with sf::Shaders) and provide a central place to store them.

ResourceHolder.hpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <map>
#include <memory>
#include <string>
#include <cassert>
#include <stdexcept>

template <typename Resource, typename Identifier>
class ResourceHolder
{
    public:
        void                load(Identifier id, const std::string& filename);

        template <typename Parameter>
        void                load (Identifier id, const std::string& filename, const Parameter& secondParam);

        Resource&           get(Identifier id);
        const Resource&     get(Identifier id) const;

    private:
        std::map<Identifier, std::unique_ptr<Resource>> resourceMap;
};

#include "ResourceHolder.inl" 


ResourceHolder.inl

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
template <typename Resource, typename Identifier>
void ResourceHolder<Resource, Identifier>::load(Identifier id, const std::string& filename)
{
    std::unique_ptr<Resource> resource(new Resource());
    if (!resource->loadFromFile(filename))
        throw std::runtime_error("ResourceHolder::load - Failed to load " + filename);

    auto inserted = resourceMap.insert(std::make_pair(id, std::move(resource)));
    assert(inserted.second);
}

template <typename Resource, typename Identifier>
template <typename Parameter>
void ResourceHolder<Resource, Identifier>::load(Identifier id, const std::string& filename,
                                                const Parameter& secondParam)
{
    std::unique_ptr<Resource> resource(new Resource());
    if (!resource->loadFromFile(filename, secondParam))
        throw std::runtime_error("ResourceHolder::load - Failed to load " + filename);

    auto inserted = resourceMap.insert(std::make_pair(id, std::move(resource)));
    assert(inserted.second);
}

template <typename Resource, typename Identifier>
Resource& ResourceHolder<Resource, Identifier>::get(Identifier id)
{
    auto foundResource = resourceMap.find(id);
    assert(foundResource != resourceMap.end());

    return *foundResource->second;
}

template <typename Resource, typename Identifier>
const Resource& ResourceHolder<Resource, Identifier>::get(Identifier id) const
{
    auto foundResource = resourceMap.find(id);
    assert(foundResource != resourceMap.end());

    return *foundResource->second;
}


Been reading the new SFML book and it really has some good stuff in there would definitely recommend it for new game devs (Though fair warning it might be hard to follow if you aren't familiar with basic and advance C++ features though not impossible).
Last edited on Aug 11, 2013 at 9:15am
Aug 11, 2013 at 9:26am
Zereo wrote:
11
12
13
14
        void                load(Identifier id, const std::string& filename);

        template <typename Parameter>
        void                load (Identifier id, const std::string& filename, const Parameter& secondParam);
Could do with some variadic template magic.
11
12
template<typename... Args>
void load(Identifier const &id, std::string const &filename, Args... args);
Last edited on Aug 11, 2013 at 9:29am
Aug 11, 2013 at 9:44am
closed account (3qX21hU5)
Maybe but I don't really see the need for it at least right now since most of SFML resource's loadFromFile member functions take only 1 parameter. With the exception of Shaders and Textures. Mainly the extra overload is there just so you can use sf::Textures area parameter and to account for Shaders which require two parameters (Either loading a Vertex shader or Fragment shader or loading both).

I kinda wanted to add in sf::Music to it but as they said in the book it would be hard to do without breaking the generics of the class :(.
Aug 11, 2013 at 3:59pm
You don't have any way to unload a resource. Of course, if you did, you'd have to decide whether the user unloading a resource that is still in use is an issue you want to address.

Thor's approach is closer to the one I use:

http://www.bromeon.ch/libraries/thor/v2.0/tutorial-resources.html
Aug 11, 2013 at 4:46pm
One thing I do is have the filename actually be the ID... rather than have a separate integer ID. This way you do not have to assign arbitrary IDs to things... and resources can be loaded as needed (in the 'get' function if it isn't already in the manager)... rather than having to be pre-loaded first.
Topic archived. No new replies allowed.