|
JLI Spieleprogrammierung
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
Kampfhund Super JLI'ler
Alter: 42 Anmeldedatum: 20.07.2002 Beiträge: 408
Medaillen: Keine
|
Verfasst am: 13.07.2004, 11:38 Titel: ClassFactory |
|
|
Hi,
ich habe in letzter Zeit an einer ClassFactory gearbeitet.
Mit einer ClassFactory kann man Instanzen von Klassen, die zB in einer Dll implementiert sind, dynamisch erzeugen indem man einfach die CreateInstance Methode der CF aufruft und ihr zB einen String übergibt welcher den Namen der Klasse enthält.
Benutzung:
Bevor man dies tun kann, muss man die Klassen, die über die CF instantiiert werden sollen, registrieren.
Zuerst wird die ClassFactory oder der FactoryManager wie ich es genannt habe angelegt:
CPP: | FactoryManager<std::string,BASISKLASSE> gFactoryManager;
|
Nun können neue Klassen registriert werden ( diese müssen von BASISKLASSE abgeleitet sein).
CPP: | gFactoryManager.Register<KLASSE>(NAME);
|
Eine Instanz der registrierten Klasse wird dann so erstellt:
CPP: | BASISKLASSE* pKlasse = gFactoryManager.CreateInstance(NAME);
|
Nun kann man die virtuellen methoden von pKlasse aufrufen die von der Basisklasse geerbt wurden.
Löschen geht ganz einfach über:
(EDIT 1)
Die CF kann man nun mit Dlls zusammen benutzen (natürlich auch ohne), dh in der exe befindet sich die CF sowie die Basisklasse. In der Dll befinden sich von der Basisklasse abgeleitete Klassen.
Die Dll exportiert zwei Funktionen:
- RegisterContent:
Hier werden die abgeleiteten Klassen in der CF der exe registriert (wie oben gezeigt).
Dazu muss der Funktion die CF aus der exe übergeben werden.
- UnregisterContent:
Hier werden die Klassen, die registriert wurden, wieder gelöscht.
Dazu muss wieder die CF aus der exe übergeben werden.
Beispiel:
Nehmen wir an, die angesprochene Basisklasse ist die Basisklasse für alle Gegenstände im Spiel und in der Dll befinden sich nun konkrete Gegenstand-Klassen (Stein, Baum, ...). Eine Map-Datei enthält dann zB die Namen der benötigten Dlls für die Gegenstände und eine Liste von Gegenstandnamen und Initialisierungsdaten (für die Gegenstände die auf der Map zu sehen sein sollen).
Map-Datei:
Code: |
[DLLs]
Dll[1] = "Game/Content/Dlls/ScienceFiction.dll"
Dll[2] = "..."
[Gegenstände]
Gegenstand[1] = "Name='Baum';Position=(128,24)"
Gegenstand[2] = "..."
|
Die exe lädt nun die Map und die in der Map-Datei angegebenen Dll-Dateien und ruft dann deren RegisterContent-Funktion auf. Nun sind alle Gegenstand-Klassen in der CF registriert. Anschließend wird die Gegenstandliste der Map-Datei durchgegangen und die Namen der Gegenstände an die CreateInstance Methode der CF übergeben, welche dann eine Instanz der konkreten Gegenstandklasse zurückgibt. Jeder Gegenstand könnte dann eine Init() Methode besitzen der man einen String mit Positionsdaten (aus der Map-Datei) übergeben könnte.
So können einem Spiel im Nachhinein neue Gegenstände hinzugefügt werden, ohne dass die exe veränder und neu kompiliert werden muss.
Programmiertechnisches(EDIT 1):
Ich verwende eine STL-map zum speichern der Konkreten Factorys.
Die Instanzen, die durch die Factory erzeugt werden, werden via new im Speicher der dll platziert, so dass die Instanzen auch wieder in der dll gelöscht werden müssen.
Dies geschieht über pInstanz->Destroy().
Warnung:
Die FactoryManager-Klasse ist ein Klassen-Template und die Register<Klasse>(...) Methode ist ein Methoden-Template. Die FactoryManager-Klasse lässt sich deshalb nur auf neueren Compilern kompilieren ( VS.NET ) (war bei mir jedenfalls so).
PS:
Die ClassFactory/FactoryManager ist noch nicht fertig.
Den Quellcode+Test Dll könnt ihr euch trotzdem Hier runterladen.
Verbesserungsvorschläge sind erwünscht
Problemstellen:
- Fehlerüberprüfung
Da hab ich noch keine Zeit drin investiert, mir gings erstmal darum, die CF zum laufen zu bekommen.
- Placement new + delete
Hier bin ich mir nicht ganz sicher ob das mit dem placement new + delete funktioniert.
Ich bekomme zwar keine Access Violations oder Compiler errors,
aber es könnte ja sein, dass sich da ein Memory Leak eingeschlichen hat...
(EDIT 1): Das placement new/delete Problem habe ich jetzt über die Destroy-Methode umgangen. Müsste jetzt eigentlich ohne Probleme funktionieren.
- Optimierung
kommt immer zum schluss! Hab ich also noch nicht gemacht.
- Fehler in Verbindung mit der STL
Ich benutze die STL hier eigentlich zum ersten mal,
dh es ist gut möglich dass ich dort noch einige Fehler gemacht habe. _________________ Kochen ist ein NP-schweres Optimierungsproblem.
Zuletzt bearbeitet von Kampfhund am 25.03.2006, 19:50, insgesamt 5-mal bearbeitet |
|
Nach oben |
|
|
Fallen JLI MVP
Alter: 40 Anmeldedatum: 08.03.2003 Beiträge: 2860 Wohnort: Münster Medaillen: 1 (mehr...)
|
Verfasst am: 13.07.2004, 13:32 Titel: |
|
|
Könntest du mal konkrete Beispiele nennen wozu man das speziell besonders gut gebrauchen kann ? Sieht schon alles richtig gut aus nur fällt mir um diese Uhrzeit noch kein gutes Beispiel ein ^^ _________________ "I have a Core2Quad at 3.2GHz, 4GB of RAM at 1066 and an Nvidia 8800 GTS 512 on Vista64 and this game runs like ass whereas everything else I own runs like melted butter over a smokin' hot 18 year old catholic schoolgirl's arse." |
|
Nach oben |
|
|
Kampfhund Super JLI'ler
Alter: 42 Anmeldedatum: 20.07.2002 Beiträge: 408
Medaillen: Keine
|
Verfasst am: 13.07.2004, 13:40 Titel: |
|
|
Wenn du einen Mod für das Spiel schreiben willst und im Mod neue Gegnertypen sind. Du kannst den Mod einfach als Dll kompilieren und in den Map Dateien, die die neuen Gegnertypen verwenden einfach den Namen der Dll angeben wo diese neuen Gegnertypen implementiert sind. Die Dll wird dann von der Exe geladen und die neuen Gegnertypen werden in der CF registriert so dass einem nun all diese neuen Gegnertypen zur verfügung stehen ohne dass man an der exe etwas veränder musste.
ZB bei HL Mods. Da gibts ja neue Spielprinzipien, Gegner usw.
Da läuft das soweit ich weiß auch alles über eine CF und Dlls.
Der Mod ist in ner Dll und registriert in der CF der exe alle neuen Gegnertypen.
EDIT: Vielleicht wirds ja ein wenig deutlicher wenn du dir den Beispiel-Quellcode anschaust. _________________ Kochen ist ein NP-schweres Optimierungsproblem. |
|
Nach oben |
|
|
Fallen JLI MVP
Alter: 40 Anmeldedatum: 08.03.2003 Beiträge: 2860 Wohnort: Münster Medaillen: 1 (mehr...)
|
Verfasst am: 14.07.2004, 10:16 Titel: |
|
|
Dachte ichs mir schon, das mit HalfLife ist mir spontan nicht eingefallen.
Da haste dir ja richtig Mühe damit gegeben, nur schade das die meisten hier sich vermutlich nicht die Arbeit machen werden sich das extra einzubauen :/
Aber wenn man sowas mal sucht wird es sicherlich sehr nützlich sein. _________________ "I have a Core2Quad at 3.2GHz, 4GB of RAM at 1066 and an Nvidia 8800 GTS 512 on Vista64 and this game runs like ass whereas everything else I own runs like melted butter over a smokin' hot 18 year old catholic schoolgirl's arse." |
|
Nach oben |
|
|
|
|
Du kannst keine Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum nicht antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen.
|
Powered by phpBB © 2001, 2005 phpBB Group Deutsche Übersetzung von phpBB.de
|