Globales Ausgabesystem [Ideensuche]



  • Hallo und guten Abend!

    Ich bin an einer 2D-Engine dran und möchte nun eine Möglichkeit erstellen, Fehler usw auszugeben. Um das zu veranschaulichen, hier etwas Pseudocode:

    void Klasse::func1(typ blabla)
    {
        HRESULT hr = CreateSomething(blabla);
        if (FAILED(hr))
            OutputDEBUG("Fehler beim Erstellen von etwas");
    }
    

    Die Meldungen sollen irgendwie angezeigt werden können(am Besten im DX-Fenster).
    Nun ist nur die Frage, wie ich das elegant umsetze.
    Ich habe alle Teile der Engine natürlich auf verschiedene Header-Dateien verteilt. Ich habe eine World-Klasse, die das eigentliche Fenster verwaltet. Jede Klasse der Engine includiert diese.
    Die Frage ist nicht, wie ich das mit DX anzeige! Ich möchte lediglich etwas haben, was aus jedem Teil der Engine Nachrichten ans Hauptfenster schicken kann.

    Eine Idee(oder auch mehrere), wie ich das umsetzen kann?

    Ich bedanke mich im Voraus!



  • meinst du eine Singleton log-klasse?



  • Könntest du vielleicht mehr dazu sagen? Der Wikipedia-Eintrag dazu ist sehr verwirrend, obwohl die Funktion dieses Musters wahrscheinlich genau das ist, was ich suche.

    Sollte etwa das machen, was OutputDebugString macht, nur dass die Ausgabe eben im Fenster (oder per MessageBox) erfolgen sollte.



  • dein Stichwort ist "designpattern singleton"
    http://de.wikipedia.org/wiki/Singleton_(Entwurfsmuster)

    du erstellst damit eine Klasse die keinen öffentlichen Konstruktor hat.
    zB:

    class Log
    {
    public:
       static Log& Get(){static Log instance; return instance;}
    
       bool LogMsg(const char* str);
       ~Log();
    
    private:
       Log();        
       Log(const Log&);
       Log operator= (const Log&);
    };
    

    damit kannst von überall eine LogMsg() aufrufen, solange der Header eingebunden ist.

    einfach über

    Log::Get().LogMsg("Mein Fehler");
    

    keine Garantie auf vollständigkeit. ich habe das jetzt schnell so hingetippt



  • OK, ich habe das jetzt so eingebaut:

    .h

    class Singleton {
    public:
       static Singleton* GetInstance();
       ~Singleton();
    private:
       Singleton();
       static Singleton* pSingleton;		// singleton instance
    };
    

    .cpp

    Singleton* Singleton::pSingleton= NULL;
    
    Singleton::Singleton()
    {
       // do init stuff
    }
    
    Singleton::~Singleton()
    {
       // destructor
    }
    
    Singleton* Singleton::GetInstance()
    {
    	if (pSingleton== NULL) {
    		pSingleton = new Singleton();
    	}
    	return pSingleton;
    }
    

    Ich hab jetzt nur das Problem, dass der Destruktor nicht automatisch aufgerufen wird, daher muss ich ihn selbst aufrufen:

    //WinMain...
    	dbERROR::Run()->~dbERROR();
    	return (int)msg.wParam;
    }
    

    Jemand einen Vorschlag, wie man das lösen könnte?



  • Die einfachste Lösung ist immer erstmal

    Singleton* Singleton::GetInstance()
    {
        static Singleton instance;
        return &instance;
    }
    

    Das kannste eigentlich so benutzen bis du Probleme mit Multithreading hast.
    Zum eingentlich Problem. Was spricht dagegen einfach eine Exception zu werfen und die im Hauptfenster zu fangen und die Meldung anzuzeigen?



  • brotbernd schrieb:

    Zum eingentlich Problem. Was spricht dagegen einfach eine Exception zu werfen und die im Hauptfenster zu fangen und die Meldung anzuzeigen?

    Es handelt sich um eine Engine, also muss das, was der Benutzer selbst schreiben muss, sehr begrenzt sein. Exception-Handling sollte im Engine-Code geschehen und nicht vom User erwartet werden.

    brotbernd schrieb:

    Die einfachste Lösung ist immer erstmal

    Singleton* Singleton::GetInstance()
    {
        static Singleton instance;
        return &instance;
    }
    

    Hm, damit habe ich auf jeden Fall das Problem mit dem Destruktoraufruf gelöst. Können da vielleicht Schwierigkeiten auftreten, wenn das so genutzt wird?

    Erstmal danke für die Hilfe! Ich wäre sonst fast verzweifelt... :p



  • Ich mach das mit einem erweiterbaren Log:
    http://code.google.com/p/nightlighttv/source/browse/NightLight/trunk/NightLightDLL/NLLog.cpp
    http://code.google.com/p/nightlighttv/source/browse/NightLight/trunk/NightLightDLL/NLILogWriter.hpp
    http://code.google.com/p/nightlighttv/source/browse/NightLight/trunk/NightLightDLL/NLTextWriter.cpp
    http://code.google.com/p/nightlighttv/source/browse/NightLight/trunk/NightLightDLL/NLHtmlWriter.cpp

    Geht in HTML und normalem Text derzeit, je nachdem welchen Writer man verwendet.
    Man könnte das jetzt einfach darum erweitern, dass alle Log-Ausgaben auch im Spiel direkt ausgegeben werden, oder eine zusätzliche Konsole allokieren die das anzeigt, etc etc.
    Aber es funktioniert, für mich persönlich, ganz gut.
    (Ich nutze google-code nur um meinen Code zu sichern)


Anmelden zum Antworten