Gamedev Framework (gf)  0.16.0
A C++14 framework for 2D games
ResourceManager.h
1 /*
2  * Gamedev Framework (gf)
3  * Copyright (C) 2016-2019 Julien Bernard
4  *
5  * This software is provided 'as-is', without any express or implied
6  * warranty. In no event will the authors be held liable for any damages
7  * arising from the use of this software.
8  *
9  * Permission is granted to anyone to use this software for any purpose,
10  * including commercial applications, and to alter it and redistribute it
11  * freely, subject to the following restrictions:
12  *
13  * 1. The origin of this software must not be misrepresented; you must not
14  * claim that you wrote the original software. If you use this software
15  * in a product, an acknowledgment in the product documentation would be
16  * appreciated but is not required.
17  * 2. Altered source versions must be plainly marked as such, and must not be
18  * misrepresented as being the original software.
19  * 3. This notice may not be removed or altered from any source distribution.
20  */
21 #ifndef GF_RESOURCE_MANAGER_H
22 #define GF_RESOURCE_MANAGER_H
23 
24 #include <functional>
25 #include <initializer_list>
26 #include <map>
27 #include <memory>
28 #include <stdexcept>
29 
30 #include "AssetManager.h"
31 #include "Font.h"
32 #include "Portability.h"
33 #include "Texture.h"
34 
35 namespace gf {
36 #ifndef DOXYGEN_SHOULD_SKIP_THIS
37 inline namespace v1 {
38 #endif
39 
49  template<typename T>
50  class ResourceCache {
51  public:
55  using Loader = std::function<std::unique_ptr<T>(const Path&)>;
56 
62  explicit ResourceCache(Loader loader)
63  : m_loader(std::move(loader))
64  {
65 
66  }
67 
71  ResourceCache(const ResourceCache&) = delete;
72 
76  ResourceCache& operator=(const ResourceCache&) = delete;
77 
90  T& getResource(AssetManager& assetManager, const Path& filename) {
91  std::size_t h = boost::filesystem::hash_value(filename);
92 
93  auto it = m_cache.find(h);
94 
95  if (it != m_cache.end()) {
96  return *it->second;
97  }
98 
99  Path absolutePath = assetManager.getAbsolutePath(filename);
100 
101  if (absolutePath.empty()) {
102  throw std::runtime_error("Path not found");
103  }
104 
105  auto ptr = m_loader(absolutePath);
106 
107  if (!ptr) {
108  throw std::runtime_error("Resource not loaded");
109  }
110 
111  auto inserted = m_cache.emplace(h, std::move(ptr));
112 
113  if (inserted.second) {
114  return *inserted.first->second;
115  }
116 
117  throw std::runtime_error("Resource not inserted in the cache");
118  }
119 
120  private:
121  Loader m_loader;
122  std::map<std::size_t, std::unique_ptr<T>> m_cache;
123  };
124 
125 
132  class GF_API ResourceManager : public AssetManager {
133  public:
137  ResourceManager();
138 
142  ResourceManager(std::initializer_list<Path> paths);
143 
151  Texture& getTexture(const Path& path) {
152  return m_textures.getResource(*this, path);
153  }
154 
162  Font& getFont(const Path& path) {
163  return m_fonts.getResource(*this, path);
164  }
165 
166  private:
167  ResourceCache<Texture> m_textures;
168  ResourceCache<Font> m_fonts;
169  };
170 
171 #ifndef DOXYGEN_SHOULD_SKIP_THIS
172 }
173 #endif
174 }
175 
176 #endif // GF_RESOURCE_MANAGER_H
Texture & getTexture(const Path &path)
Get a texture.
Definition: ResourceManager.h:151
Font & getFont(const Path &path)
Get a font.
Definition: ResourceManager.h:162
ResourceCache(Loader loader)
Constructor.
Definition: ResourceManager.h:62
STL namespace.
An asset manager.
Definition: AssetManager.h:44
A texture for colored images.
Definition: Texture.h:309
T & getResource(AssetManager &assetManager, const Path &filename)
Get a resource.
Definition: ResourceManager.h:90
The namespace for gf classes.
Definition: Action.h:35
A character font.
Definition: Font.h:109
A resource manager.
Definition: ResourceManager.h:132
A generic cache for resources.
Definition: ResourceManager.h:50
boost::filesystem::path Path
A path in the filesystem.
Definition: Path.h:44
std::function< std::unique_ptr< gf::Texture >(const Path &)> Loader
A resource loader.
Definition: ResourceManager.h:55
Path getAbsolutePath(const Path &relativePath) const
Search a file in the search directories.