2016-06-06 7 views
1

Zunächst bitte ich um Entschuldigung, wenn diese Frage bereits beantwortet wurde, aber ich kann mir meiner Entscheidung nicht sicher sein.Organisation eines globalen Systemzugriffs in einer modernen C++ - Engine

Ich arbeite an einer C++ Game Engine und möchte, dass sie den modernen Standards entspricht. Ich schrieb es in OOP-Manier und ich habe eine Hauptklasse namens ENGINE. Darin befinden sich einige Klasseninstanzen, die bestimmte Subsysteme darstellen: WINDOW, D3D11_RENDERER usw. Ich habe auch ein Protokollierungssystem (LOGGER), das für alle Subsysteme verfügbar sein muss.

Jetzt ist dieser globale Zugriff auf den Logger ein Problem. Ich bin unsicher, ob ich es als statisch deklarieren sollte, außerhalb der ENGINE Klasse, und habe eine Funktion, die einen Verweis darauf zurückgibt oder es innerhalb ENGINE vorstellt und alle Subsysteme darauf zeigen lässt.

Um Ihnen eine bessere Vorstellung davon zu geben, worüber ich spreche, postete ich vereinfachte Versionen dieser Szenarien (berücksichtigen Sie, dass ich viele sinnlose Funktionen entfernte).

Erste Lösung:

class LOGGER {...}; 

LOGGER* GetLogger() 
{ 
    static LOGGER Logger; 
    return &Logger; 
} 

// Just one example. 
class WINDOW 
{ 
    void Function() 
    { 
     GetLogger()->Write(); 
    } 
}; 

class ENGINE 
{ 
private: 
    WINDOW Window; 
} 

Beachten Sie, dass Irrlicht Motor funktioniert es wie folgt aus:

class Printer 
{ 
public: 
    static void Write(); 
    static LOGGER* Logger; 
}; 

Und es kann global wie folgt zugegriffen werden:

os::Printer::Write(); 

Zweite Lösung:

class LOGGER() {...}; 

// Same example. 
class WINDOW 
{ 
public: 
    void Initialize(LOGGER* pLogger) 
    { 
     Logger = pLogger; 
    } 

    void Function() 
    { 
     Logger->Write(); 
    } 

private: 
    LOGGER* Logger; 
}; 

class ENGINE 
{ 
public: 
    void Initialize() 
    { 
     Window.Initialize(&Logger); 
    } 

private: 
    WINDOW Window; 
    LOGGER Logger; 
} 

Ich weiß nicht, was die beste Lösung ist, und ich würde mich freuen, wenn Sie mich nach rechts ein Punkt könnte. Vielen Dank im Voraus.

Antwort

3

Ich denke, das Diagramm besser repräsentiert, was Sie brauchen:

enter image description here

Ihre Komponenten einbucht unabhängig sein, da ihre Funktion auf Protokollierungsfunktionen abhängen. Diese Funktion sollte an die Engine delegiert werden.

Die Engine selbst kann eine Logger Komponente enthalten, die die de-facto-Protokollierung behandelt.

Also lassen Sie uns einige grundlegende Code sehen:

class Engine { 
    private: 
     Logger& mLogger; 
     EngineComponent mComponents[10]; 
    public: 
     Engine(Logger& logger): 
      mLogger(logger) { 
     } 

     void addComponent(EngineComponent& c, int pos) { 
      mComponents[pos] = c; 
      c.setEngine(this); 
     } 

     void log(const std::string& message) { 
      mLogger.write(message); 
     } 
} 

class EngineComponent { 
    private: 
     Engine* mEngine; 
    protected: 
     EngineComponent() {} 
    public: 
     void setEngine(Engine* engine) { 
      mEngine = engine; 
     } 

     void log(const std::string& message) { 
      if (mEngine != NULL) { 
       mEngine->log(message); 
      } 
     } 
} 

class Window : public EngineComponent { 
    // add implementation 
} 

class D3d11Renderer : public EngineComponent { 
    // add implementation 
} 

class Logger { 
    protected: 
     Logger() {} 
} 

class FileLogger : public Logger { 
    // add implementation 
} 

Hoffe, es hilft.

+0

In der Tat ist es das, was ich brauche. Daran habe ich nicht gedacht. Danke für Ihre Hilfe! –

Verwandte Themen