ПрограммированиеФорумОбщее

Архитектура движка, как правильно спроектировать интерфейсы (2 стр)

Страницы: 1 2 3 Следующая »
#15
19:10, 5 июня 2016

Kartonagnick
> у вас дергается изнутри соседней подсистемы???
Почему нет? Если система сообщений хорошо спроектирована (стандартизована, кхм?), то подобные подсистемы могут подключаться/отключаться в любой момент

#16
19:16, 5 июня 2016

Kartonagnick
> у вас дергается изнутри соседней подсистемы???
Да. Но я пока не уверен насчет этого решения.

#17
19:19, 5 июня 2016

Laynos
> Почему нет?
потому что если А знает про Б, значит зависит от Б жесткой хардкордной связью.
без Б она у вас даже не скомпилируется.

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

а ведь изначально это разные подсистемы.
зачем сращивать то, что изначально существует,
как нечто самодостаточное и автономное?

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

#18
19:22, 5 июня 2016

-Eugene-
> Да. Но я пока не уверен насчет этого решения.
я как то встречал на практике такую ситуацию,
когда упал интернет, все - гуй не работает.
кто-то вот так взял, и завязал узелки:
панельки таскали данные напрямки из сетевой подсистемы.
да так лихо, что без сети они тупо не запускались.
нельзя было подсунуть им тестовые данные.
нельзя было просто так запустить,
что б посмотреть на красоту,
и что нибудь поправить.
и ничего с этим нельзя было поделать.
там только хирургическое вмешательство.

#19
19:56, 5 июня 2016

Вставлю свои 5 копеек. Есть неплохая (относительно) книга на http://gameprogrammingpatterns.com/
Есть её перевод на http://live13.livejournal.com/462582.html
Разобрано о архитектуре многое.

#20
20:39, 5 июня 2016

Laynos
> А как тогда работать с менеджерами ресурсов/памяти?
Ресурсы обычно существуют не сами по себе, а в каком-то контексте, например графическом. А память, выделяемая из большого куска относится к аллокатору.
Вместо ограничения количества таких контекстов одним синглотоном лучше сделать их полноправным объектом и хранить на них ссылку там, где они нужны.

#21
23:48, 5 июня 2016

Решил я попробовать сделать так, как и планировал, один синглтон ядра, дабы не плодить их много. Через него можно получить все подсистемы. Но есть одно но, касаемо dll-ок. Хотелось бы засунуть все это в несколько динамических библиотек: core.dll (собственно, ядро), graphics, audio, framework и т.д., core.dll использует либы подсистем, а клиент движка (тобишь сама игра) - сам core.dll. И есть у меня одна dll utilities.dll, содержащая логи, вспомогательные функции и прочую лобуду. Естественно, когда я лог (который занимает всего строк 300 и является синглтоном, отдельной от самого движка утилитой) включаю и в core.dll, и в игровой проект одновременно, этот синглтон дважды создается. Стоит ли вобще убирать все это в dll, и как можно такую проблему обойти... ладно бы лог, но такая ситуация может быть и с важными подсистемами. Dll пытаюсь сделать для модульности, например, для редактора в последующем.. Да и проще пересобрать dll чем весь проект, если нужно будет поменять, допустим, рендер.

Код самого лога, мб как-то изменить его... но всеравно проблемы не решает, исполняемые модули разные

#ifndef BAT_LOGGER_H
#define BAT_LOGGER_H

#include <string>
#include <fstream>
#include <vector>
#include <ctime>
#include <cstdarg>

#include "bat_sys_macroses.h"

namespace BAT_UTILS
{
  struct SLogChannel
  {
    SLogChannel(const std::string& fileName, const std::string& channelName, const std::string& filePath)
    {
      file = new std::ofstream;
      _fileName = fileName;
      _channelName = channelName;
      _filePath = filePath;
      file->open(_filePath + _fileName, std::ios_base::app);
      *file << "START SESSION AT " << GetTimeStamp().c_str() << "\n\n\n";
    }
    template<typename T>
    void Write(const T& msg)
    {
      *file << msg;
    }
    template<> void Write<>(const std::string& msg)
    {
      *file << msg.c_str();
    }
    void Destroy()
    {
      if(file)
      {
        *file << "\n\nEND SESSION AT " << GetTimeStamp().c_str() << '\n'
          << "--------------------------------------------------------------------\n\n";
        file->close();
        delete file;
      }
    }
    std::string GetTimeStamp()
    {
      time_t rawtime;
      tm * timeinfo;
      time(&rawtime);
      timeinfo = localtime(&rawtime);
      std::string info = "";
      if(timeinfo->tm_mday < 10)
        info += '0' + std::to_string(timeinfo->tm_mday) + '.';
      else
        info += std::to_string(timeinfo->tm_mday) + '.';
      if(timeinfo->tm_mon < 10)
        info += '0' + std::to_string(timeinfo->tm_mon) + '.';
      else
        info += std::to_string(timeinfo->tm_mon) + '.';
      info += std::to_string(timeinfo->tm_year + 1900) + " | ";
      if(timeinfo->tm_hour < 10)
        info += '0' + std::to_string(timeinfo->tm_hour) + ':';
      else
        info += std::to_string(timeinfo->tm_hour) + ':';
      if(timeinfo->tm_min < 10)
        info += '0' + std::to_string(timeinfo->tm_min) + ':';
      else
        info += std::to_string(timeinfo->tm_min) + ':';
      if(timeinfo->tm_sec < 10)
        info += '0' + std::to_string(timeinfo->tm_sec);
      else
        info += std::to_string(timeinfo->tm_sec);
      return info;
    }

    void PrintTimeStamp()
    {
      *file << GetTimeStamp() << "-> ";
    }

    std::ofstream* file;
    std::string _fileName;
    std::string _channelName;
    std::string _filePath;
  };

  class DLLEXP CLogManager
  {
  public:
    CLogManager();

    static CLogManager* Instance()
    {
      static CLogManager _instance;
      return &_instance;
    }

    void AddLogChannel(const std::string& channelName, const std::string& logFilename);

    void RLog(const std::string& channelName, const char* i, ...);

    void DebugLog(const std::string& channelName, const char* i, ...);

    ~CLogManager();

  private:
    std::string m_FilePath;
    std::vector<SLogChannel> m_LogChannelsList;

  };
}

#define ILog BAT_UTILS::CLogManager::Instance()

#define DEBUG_Log(channel, ...) ILog->DebugLog(channel, __VA_ARGS__)
#define RELEASE_Log(channel, ...) ILog->RLog(channel, __VA_ARGS__)

#endif
#22
0:24, 6 июня 2016

phoenix76
> Хотелось бы засунуть все это в несколько динамических библиотек: core.dll
> (собственно, ядро), graphics, audio, framework и т.д
Ну сам же себе создаёшь проблемы. Сделай одну engine.dll на всё и не парься. Или даже просто game.exe без dll, если проект на движке пока один и несколько не скоро будет. Хотя раз ты планируешь редактор, то я бы остановился на одной dll.


phoenix76
> Да и проще пересобрать dll чем весь проект, если нужно будет поменять,
> допустим, рендер.
Да ладно, чего там. Весь мой движок включая все велосипеды, которые я создал на замену STL, компилируется на ноуте за 15 секунд. К тому же студия в любом случае будет компилировать только те .cpp, которые изменились, неважно в каком они проекте. А если изменились хидеры, то отдельные проекты тоже ничем не помогут, так как студия будет компилировать все проекты, которые изменились. Только на времени линковки можно будет выиграть, но не так уж это существенно, особенно если учесть, что оптимизация всей программы будет работать менее эффективно и вообще суммарный размер бинарников станет больше.
Если хочется модульности, достаточно реализовать её на уровне исходного кода.

#23
4:20, 6 июня 2016

А зачем вообще стартовать с такого низкого уровня?

Пока вы доведёте свой движок до законченного, оттестированного, портируемого состояния, у вас уйдут человекогоды.

Для примера - исходники ClanLib содержат 502 .cpp файла размером 3,9 мегабайт и 684 .h файла на 3,1 мегабайт. При этом код чистый и качественный, без индийского "копи-пасте" стиля и к сожалению без комментариев более чем наполовину (с). Если бы мне нужен был процесс, а не результат, я бы начал с передирания архитектуры существующих библиотек.

#24
10:49, 6 июня 2016

Срочно переходи на C# - только там можно со спокойной совестью проектировать архитектуру.
C++ и архитектура - это нереально, уйдут столетия.

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

#25
10:51, 6 июня 2016

aRpi
Как архитектура связана с языком?

#26
10:56, 6 июня 2016

будет очень трудно расслабиться и работать над архитектурой,
вместо того чтобы думать об архитектуре,
целый день будешь писать на этом С++, до бесконечности...
С++ заставляет делать лишнюю работу
а когда архитектурой заниматься то... и времени не останется.

#27
12:46, 6 июня 2016

aRpi
> будет очень трудно расслабиться и работать над архитектурой,
Тогда берем и пилим архитектуру в пеинте, или на бумажке. Чо, полный расслабон. Не нужно вообще писать код.
Возможно писать код - не твое? :)

#28
13:28, 6 июня 2016

aRpi
> будет очень трудно расслабиться и работать над архитектурой,
> вместо того чтобы думать об архитектуре,
> целый день будешь писать на этом С++, до бесконечности...
> С++ заставляет делать лишнюю работу
> а когда архитектурой заниматься то... и времени не останется.

"C++ сложный, пишите на %SOME_LANGUAGE%". Если хочешь проектировать - рисуй UML'ки, "расслабляйся"

#29
14:14, 6 июня 2016

Движок писать на C#, можно для низкоуровневых подсистем оставить Си. Наследование заменить на агрегацию, избавится от синглтонов, в коре сделать методы доступа к уже проинициализированным системам get {return sound;}

Страницы: 1 2 3 Следующая »
ПрограммированиеФорумОбщее

Тема в архиве.