Strukturproblem in meinem Projekt
-
Hallo,
ich habe (vor einiger Zeit)angefangen an einer kleinen Funktionssammlung für Spiele zu schreiben.
Jetzt möchte ich diese Sammlung Struckturieren.Ich habe mir schon einige Bücher zum Thema engine Design angeschaut (u.a. das hier: Stefan Zerbst 3D Game Engine Programming.) Leider versuchen sämtliche Autoren solcher Bücher den code so "einfach" wie möglich zu struckturieren um Seiten zu sparen sagen sie dann immer. Meistens wird dann der Ganze Code in eine Superklasse gepackt. Mit ein paar globalen Zeigern wird dann zugriffen und eigentlich exestiert nur ein grober Ansatz an struckur im Projekt.
Vieleicht ist es in einem Buch auch zu schwierig, ich hab noch nie eins geschrieben.Meine Überlegungen sind jetzt auf jedenfall so weit.
Ich habe eine statische Bibliothek - diese muss immer mit dem jeweiligen Spiel
gelinkt werden.
In dieser lib habe ich nur eine Klasse die nennen wir hier mal (kreativ)--engine--. Diese Klasse kann Dlls zur Laufzeit laden und ein Objekt einer in der Dll liegenden Klasse erzuegen und einen Zeiger darauf zurückgeben.
In dieser Statik lib sind auch die Abstrakten Versionen der Klassen enthalten die dann über die engine Klasse erzeugt werden können.
Sagen wir mal es gibt die Klasse --videoClass--in der Video.DLL.
Das Spiel erzeugt ein Object der engine klasse und ein Zeiger der videoClass (das ist möglich weil die Abstrakte Version dieser Klasse ja in der Statik Lib vorhanden und für das spiel zugänglch ist).
Dann ruft das Spiel die Funktionengine.CreateVideoObject(Video.DLL)
Jetzt wird ein Objekt der echter Video Klasse liegend in der DLL erzeugt und ein zeiger zurückgegeben. Dieser Zeiger wird dem Zeiger der Abstrakten Klasse übergeben und das Spiel bekommt Zugriff auf das videoModul der engine.
Über die VideoClass in der dll soll die gesammte Funktionalität der engine im Bereich Graphik bereitgestellt werden.
Und hier komme ich irgindwie nicht weiter.
Sollte ich in der VideoClass alle Funktionen unterBringen die die engine bereit stellt oder sollte diese Klasse nur Zeiger auf erzeugte Objekte zurückgeben und diese beinhalten dann die Funktionen.Ich tendiere zum zweiten aber ich bin mir nicht sicher wie ich dass machen soll.
Das spiel darf ja nicht von diesen Klassen wissen muss aber einen zeiger davon erzeugen können. Wenn es einen zeiger davon erzeugen kann kann es auch ein Object davon erzeugen und mein ganzes Hick hacK wäre irgenwie sinnlos.Ich hoffe es ist nicht zu kompliziert den Ansatz nachzuvollziehen. Sonst fragt mich gerne.
Ich bin auch gerne bereit das ganze noch mal ganz umzukremmpeln und bitte sich mit Kritik und Vorschlägen nicht zurückzuhalten.
Danke.
Gruß.
-
socco schrieb:
Das spiel darf ja nicht von diesen Klassen wissen muss aber einen zeiger davon erzeugen können. Wenn es einen zeiger davon erzeugen kann kann es auch ein Object davon erzeugen und mein ganzes Hick hacK wäre irgenwie sinnlos.
Das stimmt so nicht ganz. Es reicht eine forward-declaration aus um einen Zeiger zu erstellen - allerdings kannst du dann natürlich keine Funktionen auf dem Objekt, auf welches der Zeiger zeigt aufrufen. Und da du Klasse nur deklariert wude aber nicht definiert wurde, können auch keine Objekte erzeugt werden.
Also folgendes geht natürlich problemlos:class Cube; int main() { Cube * p = 0; // funktioniert Cube obj; // funktioniert nicht };
Ich hab das Konzept mit der videoClass noch nicht ganz verstanden - bzw. nicht ganz verstanden für was die nun letztendlich alles zuständig ist, aber du könntest dir beispielsweise dann ein Objekt von der engine erstellen lassen, erhälst einen pointer auf dieses Objekt und gibst diesen dann weiter an die videoClass um das Objekt beispielsweise rendern zu lassen.
VideoClass * vc = engine.CreateVideoObject(Video.DLL); RenderAbleObject * cube1 = engine.CreateObjekt(CUBE, 10, 10,...); // irgendwas halt (könnte ne Factory genutzt werden) vc->Render(cube1);
Da muss ich selbst ja nichts über Cube wissen und auch keine erstellen können. Das eigentliche Objekt (hier ein Cube - wobei Cube von einer abstr. Basisklasse RenderAbleObjectwird abgeleitet ist) von einer Factory erstellt, ich erhalte einen Basisklassen-Pointer zurück und liefer den an die VideoClass.
Diese weiss natürlich intern über RenderAbleObject etc. bescheid und ruft nun beispielsweise die virtuelle Funktion render() vom Objekt auf (Polymorphismus).Falls ich das Problem komplett falsch verstanden hab, musst du wohl nochmal ein wenig weiter ausholen.
-
Die videoClass soll die Klasse sein die alles implementiert.
Z.B. habe ich eine Renderer Klasse und eine SceneGraph Klasse. Diese Klassen können rendern, Scenen laden, objecte bewegen, usw.Das Spiel hat Zugriff auf die video klasse die viedeo klasse hat zugriff auf die Rendderer u.andere Klassen.
Meine Frage ist sollte die video Klasse alle funktionen selbst anbieten oder sollte sie nur die Objekte der "unterklassen" erzeugen (Renderer, sceneGraph usw.) und die Zeiger dieser Objekte an das Spiel zurückgeben. Damit das Spiel dann deren Funktionen nutzen kann.
Wie gesagt gefällt mir die 2te variante besser aber wenn die video Klasse die zEiger an das Spiel zurückgibt muss das Spiel diese zeiger ja irgenwo speichern. Das bedeutet ich muss einen zeiger Renderer *myRenderer im Spiel erzeugen und diesem dann die addresse des Objects über die video Klasse übergeben.
Wenn ich aber Renderer *myRenderer erzeugen will muss die Headerdatei ja im Spiel vorhanden sein.
Ist sie das kann ich auch ja sofort ein Renderer object erstellen.
Diese möchte ich aber nicht erlauben, nur die video Klasse soll ja dieses Object erstellen können und an das Spiel übergeben.Insgesamt möchte ich eine struktur ereichen die so aussieht:
Das Spiel erzeugt eine engine klasse, die engine klasse erzeugt eine video klasse die video klasse erzuegt die Renderer klasse und gibt die Funktionalität dieser klasse an das Spiel.
Hoffe es ist jetzt verständlicher.
Gruß.
-
Ist das eine Factory oder eine Gottklasse?
"Die alles implementiert" hört sich stark nach Gottklasse an. Das wäre nicht so toll.
Sie kann aber über Funktionen Zeiger auf diese Klassen zurückgeben.
Schau Dir mal diesen Header an:
http://code.google.com/p/nightlighttv/source/browse/NightLight/trunk/NightLightDLL/NLSystemController.hppDas ist so ein System. Die Klasse gibt aber nur Referenzen auf die Unterklassen zurück bzw erzeugt Klassen die vorher nur über ein pure virtual Interface bekannt gemacht wurden.
Innerhalb dieser Unterklassen wurden auch noch Factories für versch. Klassen wie Texturen etc implementiert.edit:
Beispiel in PseudoCode:class TextureLoader { public: TextureHandle* loadTexture(); }; class Renderer { public: void drawTriangle(...); }; class FactoryOderController { public: TextureLoader& getTextureLoader() { return m_texture_loader; } // Oder: TextureHandle* createTexture() { return m_texture_loader.loadTexture(); } Renderer& get Renderer() { return m_renderer; } private: TextureLoader m_texture_loader; Renderer renderer; };
-
Also muss man doch noch eine pure virtual klasse dazwischen shieben.
Die Anwendung greift ja über eine pure virtual Klasse auf videoClass zu.
VideoClass ist in diesem Fall die Factory und gibt an die Anwendung die Referenz
von Renderer zurück. Die Anwendung erzeugt einen zeiger von Renderer mit hilfe der pureVirtual Renderer Klasse und speichert hier die Aresse der Referenz.
Jetzt hat die Anwendung Zugriff auf Renderer kann diesen aber nur mithilfe von der VideoClass berkommen. So wie es sein sollte.Habe ich das richtig verstanden.
Und vielen dank für deine Mühe.
Gruß.