Hey zusammen,
bei meinem aktuellsten Projekt habe ich mich mal an eine neue Herangehensweise für meinen Resource-Manager gemacht, doch stoße auf ein Problem, von dem ich nicht recht weiß wie ich es lösen soll.
Nun aber erstmal eine kurze Erklärung zu meiner Struktur: (Immer nur das für die Problemstellung benötigte, der Rest mit "//..." ausgelassen
Mein Resource-Manager speichert alle Resourc-en(momentan Shader, Meshes und Texturen) in folgender Map
|
C-/C++-Quelltext
|
1
|
static std::map<resource_key, ResourceTupel> _resources;
|
ResourceTupel ist eine simple Struktur zur Verwaltung, resource_key meine Möglichkeit auf die einzelnen Objekte zuzugreifen. Dies ist auch der Wert, den später Objekte erhalten die die Resource nutzen wollen.
|
C-/C++-Quelltext
|
1
2
3
4
5
6
7
8
9
10
11
|
typedef unsigned long resource_key;
//...
struct ResourceTupel {
ResourceTupel() : resource(Resource(-1)), fileDir(""), users(-1) {};
Resource resource;
std::string fileDir;
int users;
};
|
Jede Resource ist folgendermaßen aufgebaut:
|
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
38
39
40
41
42
43
|
class Resource
{
public:
Resource(GLuint id);
//...
virtual void Bind() const;
//...
protected:
GLuint _id;
};
class Shader : public Resource {
public:
Shader(GLuint id);
//...
void Bind() const override;
//...
};
class Mesh : public Resource {
public:
Mesh(GLuint id);
//...
void Bind() const override;
};
class Texture : public Resource {
public:
Texture(GLuint id);
//...
void Bind() const override;
};
|
Meldet nun ein Nutzer an, eine bestimmte Resource benutzen zu wollen(Momentan Anfrage über Filename), erhält er einen key(Falls die Resource schon geladen wurde zu dieser Resource, sonst zu einer neu geladenen).
Nextkey zeigt immer auf den nächsten, nicht benutzten Index.
|
C-/C++-Quelltext
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
template<class T>
resource_key ResourceManager::UseResource(const std::string& fileDir) {
//...
_resources.insert(std::make_pair(_nextkey, ResourceTupel())); //Neues Objekt wird der Map hinzugefügt
//...
_resources[_nextkey].resource = T(ResourceLoader::LoadResource<T>(fileDir)); //Die eigentliche Resource wird erstellt; "LoadResource" liefert die jeweilige OpenGL-ID
//...
}
|
Will nun ein Objekt eine Resource binden, holt er sich eine Pointer mithilfe von GetResource, die Methode ResInMap überprüft, ob die Resource bereits geladen wurde.
|
C-/C++-Quelltext
|
1
2
3
4
5
6
7
8
9
|
Resource* ResourceManager::GetResource(resource_key key) {
if (ResInMap(key))
return &_resources[key].resource;
else
return &Resource(-1);
}
//Beispielhafter Aufruf von "Bind":
ResourceManager::GetResource(_texture)->Bind();
|
Hier taucht nun das Problem auf: Denn beim erstellen der Objekte wird noch der jeweilige Konstruktor aufgerufen(in dem Beispiel also von Texture), doch der Aufruf von Bind() führt immer in die Methoden der Überklasse Resource.
Da ich bereits eine Zeit lang nicht mehr programmiert habe, bin ich mir nun unsicher ob das
a) das Grundkonzept so nicht funktionieren kann oder
b) ich einfach einen Fehler gemacht habe
Ich hoffe ihr könnt mir helfen, danke im Vor raus!