-
Notifications
You must be signed in to change notification settings - Fork 5
/
resource_manager.h
116 lines (94 loc) · 3.55 KB
/
resource_manager.h
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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#ifndef RESOURCE_MANAGER_H
#define RESOURCE_MANAGER_H
#include <memory>
#include <unordered_map>
#include <iostream>
template<typename TResource>
class ResourceManager
{
public:
ResourceManager() = default;
~ResourceManager() = default;
ResourceManager(const ResourceManager&) = delete;
ResourceManager& operator=(const ResourceManager&) = delete;
ResourceManager(ResourceManager&&) = default;
ResourceManager& operator=(ResourceManager&&) = default;
template<typename TResourceLoader, typename... Args>
std::shared_ptr<TResource> loadResource(const std::string& resourceID, Args&&... args);
template<typename TResourceLoader, typename... Args>
std::shared_ptr<TResource> loadUnmanagedResource(Args&&... args) const;
std::shared_ptr<TResource> getResource(const std::string& resourceID) const;
bool containsResource(const std::string& resourceID) const noexcept;
void stopManagingResource(const std::string& resourceID) noexcept;
void stopManagingAllResources() noexcept;
private:
std::unordered_map<std::string, std::shared_ptr<TResource>> mResources;
};
template<typename TResource>
template<typename TResourceLoader, typename... Args>
std::shared_ptr<TResource> ResourceManager<TResource>::loadResource(const std::string& resourceID, Args&&... args)
{
std::shared_ptr<TResource> resource{};
auto it = mResources.find(resourceID);
if (it == mResources.cend())
{
resource = TResourceLoader{}.loadResource(std::forward<Args>(args)...);
// We only store the resource if it is not a nullptr
// We expect the loaders to print an error message when they are unable to load a resource successfully, which is why we don't print anything here
if (resource)
{
mResources[resourceID] = resource;
}
}
else
{
std::cout << "Warning - ResourceManager::loadResource - A resource with the following ID already exists: " << resourceID << "\n";
resource = it->second;
}
return resource;
}
template<typename TResource>
template<typename TResourceLoader, typename... Args>
std::shared_ptr<TResource> ResourceManager<TResource>::loadUnmanagedResource(Args&&... args) const
{
// We expect the loaders to print an error message when they are unable to load a resource successfully, which is why we don't print anything here
return TResourceLoader{}.loadResource(std::forward<Args>(args)...);
}
template<typename TResource>
std::shared_ptr<TResource> ResourceManager<TResource>::getResource(const std::string& resourceID) const
{
auto it = mResources.find(resourceID);
if (it != mResources.end())
{
return it->second;
}
else
{
std::cout << "Error - ResourceManager::getResource - A resource with the following ID does not exist: " << resourceID << "\n";
return nullptr;
}
}
template<typename TResource>
bool ResourceManager<TResource>::containsResource(const std::string& resourceID) const noexcept
{
return (mResources.find(resourceID) != mResources.cend());
}
template<typename TResource>
void ResourceManager<TResource>::stopManagingResource(const std::string& resourceID) noexcept
{
auto it = mResources.find(resourceID);
if (it != mResources.end())
{
mResources.erase(it);
}
else
{
std::cout << "Error - ResourceManager::stopManagingResource - A resource with the following ID does not exist: " << resourceID << "\n";
}
}
template<typename TResource>
void ResourceManager<TResource>::stopManagingAllResources() noexcept
{
mResources.clear();
}
#endif