I am writing some auxiliary classes for the game engine I want to create with SFML. I want to write generic resource management code so I can then use mostly the same code to manage loading of images, sounds etc. I have a few questions about how to write it. Sorry if this post is a bit long or poorly worded!
This is my Resource abstract base class. The Load functions are for loading resources (from file, memory or other) and similarly for saving them. The saving functions are not pure virtual since not all resources should be able to be saved. Freeing of resources is handled by overriding the pure virtual destructor.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
class Resource {
public:
Resource() { }
virtual ~Resource() { }
virtual void Load(std::string arg)=0;
virtual void Load(char* arg)=0; // I have used char* for memory pointer since
// I need void* for generic arguments
virtual void Load(void* arg)=0;
virtual void Save(std::string arg) {}
virtual void Save(char* arg) {}
virtual void Save(void* arg) {}
};
|
I want to support loading from generic arguments so the user can choose write custom loading functions not only given an std::string argument or a memory pointer argument but also any other argument type they might want. At the moment I have implemented this using a void* type. However, this means that if the user of the library wants to write two custom loading functions with different argument types, it will get very cumbersome (the void* would have to contain data to tell the function which loading method to use etc).
My question, therefore, is whether there is a better way to allow the user to implement loading and saving functions given an arbitrary argument type?
My other questions regard the resource management class. Here is the code for it so far.
Possibility 1
1 2 3 4 5 6 7 8 9 10 11 12
|
template <class T> class ResourceManager {
std::map<std::string, T*> resources;
public:
std::string Load(void* arg);
void Save(void* arg);
T* GetResource(std::string ref);
};
|
My first question here is: is it too inefficient for a game resource manager to refer to resources using an std::string and std::map? (The reason I have done it is that it will make it easy to see if a file has already been loaded by giving the loaded resource it's relative file path as an identifier).
The second, more important question is this. Should I make it a template class so the user can use a different instance of the template for each Resource type? In this case, is there any way I could force the user to only use types derived from Resource (like interfaces in C#).
Alternately, should I just use
std::map<std::string, Resource*>
and make the user provide custom loading and saving functions (which I have placed as template arguments above)?
In this case the code would be something like:
1 2 3 4 5 6 7 8 9 10 11 12
|
template <void (*Loader)(void*), void (*Saver)(void*)=0> class ResourceManager {
std::map<std::string, Resource*> resources;
public:
std::string Load(void* arg);
void Save(void* arg);
Resource* GetResource(std::string ref);
};
|
Thanks in advance for any help.