Mit einer Interface-Klasse für Ressourcen wäre das kein Problem.
Ja, das stimmt. Vermutlich würde das auf eine
Resource<Type>-Klasse und eine
ResourceBase-Klasse hinauslaufen. Er muss hier ja den Weg über Komposition gehen, weil Ressourcenklassen beteiligt sind, die keine gemeinsame Interface-Klasse haben (z.B.
sf::Texture,
sf::SoundBuffer + eigene Ressourcenklassen). Im Endeffekt wäre das also meinem Vorschlag sehr ähnlich, allerdings mit dem Unterschied, dass anstatt der Container die Ressourcen "gewrappt" wären.
@FreezingEngine
Du könntest auch mal einen Blick auf
std::type_index werfen:
The type_index class is a wrapper class around a std::type_info object, that can be used as index in associative and unordered associative containers.
Damit kannst du z.B. für den Texturencontainer direkt
sf::Texture anstatt den String "texture" als Schlüssel in deiner Ressourcenmap verwenden. Das ließe sich natürlich auf jede Art von Ressource übertragen.
So habe ich es auch in meinem Ressourcenmanager gemacht (hier auf das Nötigste zusammengekürzt):
|
C-/C++-Quelltext
|
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
|
class ResourceProvider : sf::NonCopyable
{
public:
///
/// \brief Gets a resource with a certain key.
///
template <typename ResourceType>
auto getResource(const std::string& key) -> ResourceType&
{
return getResourceStorage<ResourceType>().getResource(key);
}
private:
typedef std::unique_ptr<ResourceStorageBase> StoragePointer;
typedef std::unordered_map<std::type_index, StoragePointer> StorageMap;
///
/// \brief Gets the storage for a certain type of resource.
///
template <typename ResourceType>
auto getResourceStorage() -> ResourceStorage<ResourceType>&
{
auto iterator = m_storageMap.find(typeid(ResourceType));
assert(iterator != m_storageMap.end());
assert(dynamic_cast<ResourceStorage<ResourceType>*>(iterator->second.get()) != nullptr);
return static_cast<ResourceStorage<ResourceType>&>(*(iterator->second.get()));
}
///
/// \brief Map holding the resource storages.
///
StorageMap m_storageMap;
};
|
ResourceStorageBase und
ResourceStorage entsprechen ungefähr den Klassen
TypeErasedMapWrapper und
MapWrapper aus meinem ersten Beispiel.
Vielleicht inspiriert dich das ja.