2016-06-06 1 views
1

Прежде всего, я прошу прощения, если на этот вопрос уже был дан ответ, но я просто не могу быть уверен в своем выборе.Организация глобального доступа к системе в игровом движке с современным C++

Я работаю над движком C++ и хочу, чтобы он соответствовал современным стандартам. Я написал его в стиле ООП, и у меня есть основной класс под названием ENGINE. Внутри него есть несколько экземпляров классов, которые представляют конкретные подсистемы: WINDOW, D3D11_RENDERER и т. Д. У меня также есть система регистрации (LOGGER), которая должна быть доступна для всех подсистем.

Теперь этот глобальный доступ к регистратору представляет собой проблему. Я не уверен, должен ли я объявлять его как статический, вне класса ENGINE и иметь функцию, которая возвращает ссылку на нее или экземпляр внутри ENGINE, и все подсистемы указывают на нее.

Чтобы лучше понять, о чем я говорю, я опубликовал упрощенные версии этих сценариев (учтите, что я удалил много бессмысленных функций).

Первое решение:

class LOGGER {...}; 

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

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

class ENGINE 
{ 
private: 
    WINDOW Window; 
} 

Обратите внимание, что Irrlicht двигатель делает это так:

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

И это может быть глобально доступны как это:

os::Printer::Write(); 

Второе решение:

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; 
} 

Я не знаю, что является лучшим решением, и я был бы рад, если бы вы могли бы указать мне правильный. Заранее спасибо.

ответ

3

Я думаю, что эта схема представляет собой лучше, что вам нужно:

enter image description here

Ваши компоненты должны быть лог-агностик, так как их функции не зависят от возможности регистрации. Эта функция должна быть делегирована движку.

Само устройство может содержать компонент Logger, который обрабатывает де-факто протоколирование.

Итак, давайте посмотрим некоторые основные кода:

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 
} 

Надеется, что это помогает.

+0

Действительно, это то, что мне нужно. Я об этом не думал. Спасибо за помощь! –

 Смежные вопросы

  • Нет связанных вопросов^_^