I've done some some research on my own, so I hope someone can help me finish it. I'm trying to replicate the design of an extensible asset manager featured in this answer.
At the moment I have created this and have no clue on how to proceed.
class ResourceManager {
public:
template<typename T>
bool addFactory( std::unique_ptr<ResourceFactory<T>> factory ) {
std::type_index ti = std::type_index(typeid(T));
auto searchResult = factories.find(ti);
if(searchResult != factories.end()) {
return false;
} else {
factories[ti] = std::move(factory);
return true;
}
}
template <typename T>
ResourceHandle<T> load(const std::string &path) {
std::type_index ti = std::type_index(typeid(T));
auto searchResult = factories.find(ti);
if(searchResult == factories.end()) {
throw NoValidFactory(std::string("No registered factory of type ") +
ti.name());
}
// TODO SOMEHOW DO LOADING
//return searchResult->second->load(path);
}
private:
std::unordered_map<std::type_index,
std::unique_ptr<ResourceFactoryI>> factories;
};
I assume that TextureHandle
featured in the answer is probably a typedef
for something like a custom reference counted smart pointer (e.g. ResouceHandle<Texture>
, like in my engine) but how do I return something like that? I'm not (YET) good with templates but I know that it's impossible to have a virtual specifier with a template method, so I CAN'T do something like this:
class ResourceFactoryInterface {
public:
template <typename T>
virtual ResourceHandle<T> load(const std::string &path) = 0;
};
template <typename T>
class ResourceFactory : public ResourceFactoryInterface {
public:
ResourceHandle<T> load(const std::string &path) {
// loading
}
};
// TODO Template specializations for object types? Inherit from ResourceFactory?
What should I do? Am I even close or am I doing a complete nonsense? How should I proceed?
If someone wants to know why I need something like that: at the moment I have one huge, difficult to maintain and extend ResourceManager
class with a different method (loadTexture, loadMesh, loadSound, etc.) for each resource type. Having something that can be extended dynamically would make my hobby engine's resource management system more reusable. Moreover, I have a few places where I'd benefit from instantiating separate resource managers with only several registered (level specific) resource types.