Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

Dave

Alter Hase

  • »Dave« ist der Autor dieses Themas

Beiträge: 757

Wohnort: Berlin

  • Private Nachricht senden

1

10.01.2005, 15:15

Engine-Desing / Log

ich bin gerade am design meiner zukünftigen engine ;)
ist alles komplett objektorientiert. meine logsystem-klasse ist member der hauptklasse. wollte mir jetzt ein paar defines einbauen, mit welchen ich etwas in die logdatei schreiben kann -> problem ist ich weiß ja nicht wo diese defines aufgerufen werden, sprich woher bekomm ich den zeiger auf meine logsystem-klasse?
erste idee war ne globale variable, finde ich allerdings unangenehm und ist ja auch schlechter stil *g*
zweiter ansatz war jeder klasse nen zeiger auf die hauptklasse zu spendieren. dürfte ich eigentlich sowieso nicht drumherum kommen, oder? nachteil wäre natürlich was ich mache, wenn man in einer eigenen klasse (die nicht zur engine gehört) was in die logdatei schreiben will....
wie würdet oder habt ihr das gemacht??

Till

Alter Hase

Beiträge: 378

Wohnort: Lincoln College, Oxford

Beruf: Student

  • Private Nachricht senden

2

10.01.2005, 16:39

Re: Engine-Desing / Log

Zitat von »"Dave"«

zweiter ansatz war jeder klasse nen zeiger auf die hauptklasse zu spendieren. dürfte ich eigentlich sowieso nicht drumherum kommen, oder?


Genauso ging's mir auch mal... :-D ...ich hab's dann auch so gemacht - das Ergebnis war eine relativ unflexible benutzerunfreundliche Engine. Aber die Sache mit den Logfiles geht überhaupt nicht richtig elegant habe ich das Gefühl, auch die ZFX-Engine benutzt dabei globale Symbole, glaube ich.
DOMINVS ILLVMINATIO MEA
---
Es lebe unmanaged Code!
---
>> Meine Uni <<

DrthM2001

Alter Hase

Beiträge: 721

Wohnort: Karlsruhe

  • Private Nachricht senden

3

10.01.2005, 16:42

machs wie ich ;) du hast eine globals.h mit allen wichtigen sachen, includes<> und den defines und deiner hauptklasse GameClass. Am ende dieses headers steht:

C-/C++-Quelltext

1
2
3
4
#if  !defined(GAMECLASSGAMEDECLARED)
#define GAMECLASSGAMEDECLARED
extern GameClass Game;
#endif


und nur in einer datei schreibst du

C-/C++-Quelltext

1
2
#define GAMECLASSGAMEDECLARED
#include "globals.h"


und sonst immer #include "globals.h". dann hast du in deiner globals die zeile:

C-/C++-Quelltext

1
#define LOG                 Game.Print

So ist exakt meine lösung. wobei mir grad auffällt dass Print kein guter name ist. egal. Dann kann ich einfach LOG("String1337 ist %s", stringggg); machen.

Dave

Alter Hase

  • »Dave« ist der Autor dieses Themas

Beiträge: 757

Wohnort: Berlin

  • Private Nachricht senden

4

10.01.2005, 17:36

@DrthM2001: ja, so ähnlich hatte ichs auch, danke.

5

10.01.2005, 17:51

Global Header die alles includieren sind immer schlecht, da sie die compilierzeit drastisch erhöhen. Eine Header sollte nur die Header einbinden die sie auch wircklich brauch.

Es gibt sehr elegante Möglichkeiten wie man ein Log-System auf die Beine bekommt und dieser Weg führt nicht über globale Variablen oder Defines. Das Stichwort heißt hier Singleton.

Teile dein Log-System in drei Teile auf.
1: Den Logger:
Diese Klasse beschreibt wie ein Log-Eintrag in das Log-File geschrieben wird. Das ermöglicht später das du sowohl auf eine Konsol, TXT-Datei oder auch in eine HTML Datei schreiben kannst.
2: Der Log-Server:
Der Log-Server ist ein Singleton und somit Systemweit erreichbar. Der Log-Server hält den Logger, oder vieleicht auch mehrere Logger. Der Server nimmt den Log-Eintrag entgegen und reich ihn dann an den Logger weiter. Dies ermöglicht später eine Syncronisation der Log-Einträge, falls nötig.
3: Der Log-Client:
Man könnt ihn auch als Log-Buffer beschreiben. Name der Klasse ist einfach "Log". Die Klasse stellt vorrangig einen Buffer zur verfügung. In diesen Buffer wird der Log-String gespeichert und bei einem "Flush" wird dann der Log-String an den Log-Server weitergereicht.
Für eine bessere Handhabung, sollte die Log-Klasse die Stream-Operatoren "<<" überladen.

Vorteil des Systems:
Keine Globals. Sehr flexibel. Erweiterbar und poppe einfach in der Handhabung. Man erstellt einfach irgendwo eine Instanz des Log-Clients und macht seine Log-Einträge. Den Rest macht das System.
Wichtig! Ich übernehme keinerlei Verantwortung für eventl. Datenverlust oder Schäden am Rechner ;D

Dave

Alter Hase

  • »Dave« ist der Autor dieses Themas

Beiträge: 757

Wohnort: Berlin

  • Private Nachricht senden

6

10.01.2005, 21:45

so ganz hab ich das noch nicht verstanden...
wieso ist der server systemweit erreichbar? ein singleton ist doch nur ne klasse von welcher nur genau eine instanz existieren kann. man benötigt also immernoch nen zeiger darauf, woher soll man den bekommen?
und wo würdest du den/die client(s) erzeugen? läuft das nicht darauf hinaus, dass ich ne ganze menge clients kreieren muss?

7

10.01.2005, 22:14

Natürlich ist der Systemweit/Programmweit (ist wohl besser ausgedrückt) zu erreichen.

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
class Singleton
{
public:
  void foo();
public:
  static Singleton& instance() { return *instance_; }

private:
  static Singleton* instance_;
};

// Irgendwo im Code

Singleton::instance().foo();

So...und wo ist nun das Problem? Wo brauch ich nun eine Referenz im Code? Macht alles das Singleton ;)


Und natürlich hast mehrer Clients und das ist ja auch gewollt 8)
Beispiel:
Du hast eine Klasse Engine. Die bekommt als Member den Log-Client. Nun kann man in jeder Methode der Klasse Engine

C-/C++-Quelltext

1
log_ << "Log eintrag" << LOG_FLUSH;

schreiben. Ist doch super. Nicht nur das. Man kann so auch sehr einfach Gruppen erzeugen. Hier z.B. eine Gruppe "Engine". Dann kannes z.B. eine Gruppe "Renderer" geben. Die Render-Klasse hat ebenfalls eine Instanz eines Log-Clients.

Nun gut. Ist natürlich jedem selbst überlassen, wie er das macht. Ist ja nur ein Vorschlag wie man es machen könnte. Der Speicheroverhead hält sich in Grenzen. Natürlich, wenn man während der gesamten Laufzeit nie den Buffer des Log-Clients löscht, kann sich so einiges ansammeln. Aber auch hier kann man eine Grenze einbauen. Wenn die überschritten wird, wird eben Automatisch alles geflushed.
Wichtig! Ich übernehme keinerlei Verantwortung für eventl. Datenverlust oder Schäden am Rechner ;D

Dave

Alter Hase

  • »Dave« ist der Autor dieses Themas

Beiträge: 757

Wohnort: Berlin

  • Private Nachricht senden

8

11.01.2005, 12:18

macht sinn ;)
werde das mal so implementieren. vielen dank.

Dave

Alter Hase

  • »Dave« ist der Autor dieses Themas

Beiträge: 757

Wohnort: Berlin

  • Private Nachricht senden

9

12.01.2005, 17:10

komme mit dem überladen des <<-operators nicht ganz klar...
zwei parameter akzeptiert er nicht, was ich nicht ganz verstehe, da mans in vielen texten so sieht. wenn ich nur einen parameter habe, muss ich ja irgendwie an meinen buffer ran kommen, hab das mit this gemacht. klappt auch, zumindest solange ich es nicht verschachtel. bei soetwas hat er probleme:

C-/C++-Quelltext

1
2
// test vom typ Log

test << "hallo" << " du";

im buffer habe ich dann nur "hallo". wenn ich das ganze nacheinander aufrufe klappts.

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Log
{
public:
    Log operator<<(std::string str) {
        this->buf += str;
        return *this;
    }

    void ausgabe() {
        std::cout << buf << std::endl;
    }

private:
    std::string buf;
};

Till

Alter Hase

Beiträge: 378

Wohnort: Lincoln College, Oxford

Beruf: Student

  • Private Nachricht senden

10

12.01.2005, 17:47

als so wie ich das sehe, gibt dein Operator den Typ Log zurück, dieser wird dann (bei der Verschachtelung) als wieder Parameter eingesetzt, was ja nicht geht...

aber wieso geht das nicht zweiparametrig?

C-/C++-Quelltext

1
std::ostream &operator<<(std::ostream &stream, std::string str);
DOMINVS ILLVMINATIO MEA
---
Es lebe unmanaged Code!
---
>> Meine Uni <<

Werbeanzeige