Должен ли я использовать статические классы в ECS? - PullRequest
4 голосов
/ 22 сентября 2019

Эй, я в настоящее время работаю над небольшой компонентной системой, в которой есть классы, такие как EntityManager, ComponentManager и SystemManager, которые создаются только один раз и активно взаимодействуют друг с другом.

Я создал класс world, который владеет всеми менеджерами и выступает в качестве центра всей коммуникации между менеджерами.Если сделать все Менеджеры статичными, многое станет намного проще, понятнее, и мне даже не понадобится мировой класс.

Хотя я знаю, что статические классы (я знаю, что «статические классы» не существуют)но я имею в виду классы, имеющие только статические члены), действующие так, как будто они глобальные, а глобальные переменные - Bad®.
Поэтому мне интересно, что рекомендуется делать в этом случае

Спасибо за ваши ответы

Че

Редактировать: Класс World выглядит следующим образом:

class World
{
public:
    EntityManager* entityManager;
    ComponentManager<PositionComponent>* componentManager;
    MovementSystem* movementSystem;
    Entity e;

public:
    World(sf::RenderWindow& window);
    void update();
};

Для общения каждый Менеджер нуждается в указателе на мир для доступа к другим менеджерам.Как это world->entityManager->getEntitys()

1 Ответ

1 голос
/ 23 сентября 2019

(я предлагаю, чтобы проект был игрой или чем-то близким к ней)

Я не предлагаю вам сделать все члены статичными.Основная проблема в том, что вы теряете контроль над временем жизни объекта.Вы не можете легко уничтожить и создать новый объект во время выполнения, потому что нет объекта.Например, если вы хотите сменить менеджера во время выполнения, вам придется внедрить код очистки вручную.В случае объектов C ++ C ++ помогает вам с ошибками / предупреждениями, значениями по умолчанию и членами класса по значению.

Существует несколько популярных способов реализации и использования менеджеров в gamedev:

  • ИспользованиеСинглтонВ этом случае у класса есть один статический метод, который возвращает ссылку на нестатический объект.
  • Передайте зависимости, которые метод требует при вызове метода вручную.

Шаблон синглтона Я думаю, для вас это лучший способ с точки зрения соотношения цены и качества.Несмотря на всю критику этого шаблона, он хорошо работает (в большинстве игровых проектов, которые я видел, использовался подход Singleton для реализации классов менеджера).

Есть одна важная вещь, которую я хотел бы предложить вам об этом шаблоне.Не используйте стандартную реализацию шаблона Singleton.Создайте методы для создания и уничтожения объекта вместо того, чтобы скрывать его внутри геттера.Вот простой пример связующего кода для менеджера:

class Manager {
private:
    static Manager* ms_manager;
public:
    static void CreateManager() { ms_manager = new Manager(); }
    static void DestroyManager() { delete ms_manager; }
    static Manager* GetInstance() { return ms_manager; }
};

Использование:

Manager::GetInstance()->SomeMethod();

Подход с передачей зависимостей имеет свои преимущества.Это может показаться слишком сложным, чтобы передать все в каждом методе обновления, но это не так.Вы можете создать контекстный класс, установить там все зависимости и передать его каждому методу, который в этом нуждается.Это почти как ваш класс World, но это должна быть структура с минимумом кода и без зависимостей.Не храните игровые объекты по значению (только примитивы, векторы геометрии и тому подобное).Это может быть что-то вроде этого:

struct Context {
    EntityManager* entityManager;
    ComponentManager<PositionComponent>* componentManager;
    MovementSystem* movementSystem;
    Entity* rootEntity;
};

Использование:

GameObject::Update(Context& context) { context.entityManager->SomeMethod(); }

Суть этого подхода в том, что вы можете настроить контекст для некоторых объектов во время выполнения.Например, если у вас есть LOD, вы можете сохранить в контексте текущий уровень LOD и изменить его во время выполнения для некоторых объектов, в зависимости от расстояния до камеры.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...