Objektmanagement sinnvoll gestalten
-
Du hast aus Type einen String gemacht? Na ja, wie auch immer, ich meinte eigentlich, wie du die add Funktion aufrufst.
-
Vorerst ein string ja.
Aufrufen tu ich noch gar nichts. Der Fehler tritt beim Compilieren auf. Also bisher existieren nur die Klassen.
-
Hm.. IDEOne rastet auch aus: http://ideone.com/xUQUz
Mir fällt gerade auf, dass ich gar nicht genau weiß, was der Standard da für Movables garantiert.. trotzdem, mein MinGW (4.6.1) macht das ohne zu murren.
-
cooky451 schrieb:
Hm.. IDEOne rastet auch aus: http://ideone.com/xUQUz
Mir fällt gerade auf, dass ich gar nicht genau weiß, was der Standard da für Movables garantiert.. trotzdem, mein MinGW (4.6.1) macht das ohne zu murren.Ich werde mal MinGW updaten.
Edit:
Fehlerfrei durchgelaufen!
evtl ein Bug im MinGW 4.5.2
Edit2:
Auch meine versionen von get/add lassen sich nun compilieren.
Also war ich wohl doch nicht so dumm
-
Erstmal komme ich gut voran. Stehe aber vor einer unschönheit mit meinen Smartpointern.
Ich habe nun einen simplen ResourceManager implementiert:
typedef boost::shared_ptr<Resource> ResourcePtr; class ResourceManager { private: map<string,ResourcePtr > m_Resources; public: ResourceManager(); virtual ~ResourceManager(); void addResource(ResourcePtr p_Resource,string p_ResourceID); void removeResource(string p_ResourceID); ResourcePtr getResource(string p_ResourceID); };
Da die Ressourcen in mehreren Entitäten benötigt werden habe ich shared_ptr anstatt unique_ptr verwendet (mit dem Hilfskonstrukt: "boost::shared_ptr<Resource> ResourcePtr;").
Resource ist eine abstrakte Klasse von der alle Ressourcentypen abgeleitet werden (Models, Texturen, Sounds etc).
So sieht nun meine Ressourcen Initialisierung aus:
initResources() { boost::shared_ptr<Model> tmp(new Model()); tmp->load("hawk.obj"); tmp->test(); m_ResourceManager.addResource(tmp,"Hawk"); //Hat es funktioniert?: Model *tmp2; tmp2=(Model*)m_ResourceManager.getResource("Hawk").get(); tmp2->test(); }
hierbei missfallem diese Zeilen etwas:
Model *tmp2; tmp2=(Model*)m_ResourceManager.getResource("Hawk").get();
Grund ist das ich meiner Entität einen shared_ptr geben möchte damit die Renderer Komponente zugriff auf die Modedaten hat. Dafür werden ja die beiden Zeilen benötigt die mir etwas missfallen. Gibt es vernünftige Alternativen?
-
Über Resource-Management kann man wahrscheinlich drei Bücher schreiben, aber solange du während der Laufzeit nichts hinzufügen oder wegnehmen musst, könntest du auch einfach mit einem unique_ptr für den Manager und einem direkten Pointer / einer Referenz auf die Ressource für die Objekte arbeiten.
Und PS:
Was soll das "hat es funktioniert"? Edit: Und warum hat dein Manager einen virtuellen Destruktor? Und was macht der Konstruktor? Und warum nutzt du nicht std::shared_ptr, falls du den wirklich brauchen solltest.
-
virtueller Destruktor:
ist noch ein überbleibsel von dem was die IDE erstellt hat. Kommt noch weg."Hat es funktioniert":
da schau ich ob ich auf die Resource zugreifen kann. Das kommt später weg (bzw is das nur nen Prototyp, wird später einfach aus nem Verzeichniss/Definitionsdatei geladen).
Aber auf diese weise werde ich wohl in meiner Renderer Componente auf die Daten zugreifen müssen(?).
Edit:
Aber vll mach ich das mit einem Rawpointer. Denn wenn die Resource freigegeben wird aber die Komponente darauf trotzdem zugreifen möchte habe ich eh einen Designfehler.
-
Ach ja, was mir noch aufgefallen ist: Wie wäre es mit
resourcemanager.add(std::unique_ptr<Model>(new Model("model.mdl")));
und der Konstruktor von Model wirft einfach eine Exception? (PS: Etwas offtopic, aber warum gibt's eigentlich kein make_unique? oO)
-
cooky451 schrieb:
Ach ja, was mir noch aufgefallen ist: Wie wäre es mit
resourcemanager.add(std::unique_ptr<Model>(new Model("model.mdl")));
und der Konstruktor von Model wirft einfach eine Exception? (PS: Etwas offtopic, aber warum gibt's eigentlich kein make_unique? oO)
Eine Exception bei was? Edit: File not Found? /Edit
Wenn ich keine shared_ptr benutze kann man es so machen wie du es vorgeschlagen hast. Bzw fällt auch wieder das Hilfskonstrukt weg.
wie meinst du das mit "make_unique"?
-
Cyphron schrieb:
Eine Exception bei was?
Wenn z.B. die Datei nicht geöffnet werden kann, sie das falsche Format hat oder bei sonst irgendeinem Fehler.
Cyphron schrieb:
wie meinst du das mit "make_unique"?
resourcemanager.add(std::make_unique<Model>("model.mdl"));
Und eine weitere Frage die sich auftut: Macht eine gemeinsame Resource-Basisklasse Sinn, oder könnte man nicht verschiedene mehrere Container für Textures, Models, etc. anlegen. Funktionieren tut beides, aber was davon jetzt sinnvoller ist, weiß ich leider auch nicht. Vielleicht hat ja jemand mehr Erfahrung damit?
-
Also das eine Ressource nicht doppelt vorhanden ist wird doch schon sichergestellt durch den Key in der Map (der wohl Dateiname ohne Endung sein wird).
Basisklasse Resource:
Damit ich über das Keyword alle Ressourcen verwalten kann. Auch hinzufügen und Entfernen ist somit immer gleich. Verbesserungsvorschlägen bin ich aber nicht abgeneigt.