Внутренние менеджеры ECS

EntityManager

class EntityManager

Менеджер для создания и управления сущностями

Обеспечивает создание, удаление и валидацию сущностей с использованием пула идентификаторов

Public Functions

Entity createEntity()

Создает новую сущность

Использует свободные ID из пула при наличии, иначе генерирует новый

Результат:

Идентификатор созданной сущности

bool destroyEntity(Entity entityId)

Удаляет сущность и освобождает ее ID.

Освобожденный ID помещается в пул для повторного использования

Параметры:

entityId – Идентификатор сущности для удаления

Результат:

true если сущность успешно удалена, false если ID невалиден

bool isEntityValid(Entity entityId) const

Проверяет валидность идентификатора сущности

Параметры:

entityId – Идентификатор сущности для проверки

Результат:

true если сущность существует и валидна, false в противном случае

Private Members

Entity nextEntityId

Следующий доступный идентификатор сущности

std::queue<Entity> freeList

Очередь свободных идентификаторов для повторного использования

ComponentManager

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

Внутреннее устройство хранилища:

  • std::vector<T> components – плотный массив самих компонентов (cache‑friendly).

  • std::vector<Entity> entities – параллельный массив идентификаторов сущностей.

  • std::unordered_map<Entity, size_t> entityToIndex – хеш-таблица для отображения сущности на индекс в векторах.

Основные операции:

  • Добавление компонента: если компонент уже существует – заменяем, иначе добавляем в конец векторов (O(1) амортизированно).

  • Удаление компонента: используется техника swap with last – удаляемый элемент заменяется последним, затем последний удаляется. Индексы корректируются (O(1)).

  • Получение компонента по сущности: поиск в хеш-таблице (O(1) в среднем).

  • Проверка наличия: аналогично.

Публичный интерфейс для пользователей (доступен через класс Scene):

  • addComponent<T>(entity, value) – добавляет или заменяет компонент.

  • removeComponent<T>(entity) – удаляет компонент.

  • hasComponent<T>(entity) – проверяет наличие.

  • getComponent<T>(entity) – возвращает указатель на компонент.

  • getEntitiesWith<T>() const – возвращает ссылку на вектор сущностей, имеющих компонент T. Это позволяет эффективно итерировать.

  • getEntitiesWithAll<Components...>() const – возвращает вектор сущностей, имеющих все указанные компоненты. Алгоритм оптимизирован: выбирается наименьший вектор кандидатов, и для каждой его сущности проверяется наличие остальных компонентов.

  • view<T>() const – возвращает структуру с константными ссылками на внутренние векторы компонентов и сущностей для максимально эффективной массовой обработки (без повторных поисков).

Производительность: благодаря плотным массивам и минимизации косвенных обращений, итерация по компонентам одного типа выполняется со скоростью линейного прохода по памяти. Пересечение типов требует O(min_n * k) операций, где min_n – размер наименьшего набора, k – количество типов.

Примечание: тип сущности (Entity) является 32‑битным целым числом, что позволяет при необходимости заменить unordered_map на плоский массив (sparse set) для ещё более быстрого доступа, но текущая реализация уже обеспечивает хороший баланс между производительностью и гибкостью.

class ComponentManager

Менеджер для управления компонентами сущностей

Обеспечивает хранение, добавление, удаление и поиск компонентов Компоненты хранятся в плотных массивах (cache-friendly) с использованием техники «sparse set» для быстрого доступа. Это обеспечивает отличную локальность данных при массовой обработке.

Public Functions

template<typename T>
inline bool addComponent(Entity entityId, T &&component)

Добавляет компонент к сущности

Если компонент у сущности уже существует, он будет заменён. Благодаря perfect forwarding избегаются лишние копирования.

Параметры шаблона:

T – Тип компонента

Параметры:
  • entityId – Идентификатор сущности

  • component – Компонент для добавления (может быть lvalue или rvalue)

Результат:

true если компонент успешно добавлен, false в противном случае

template<typename T>
inline bool removeComponent(Entity entityId)

Удаляет компонент у сущности

Параметры шаблона:

T – Тип компонента

Параметры:

entityId – Идентификатор сущности

Результат:

true если компонент существовал и был удален, false в противном случае

template<typename T>
inline bool hasComponent(Entity entityId) const

Проверяет, есть ли у сущности компонент типа T.

template<typename T>
inline T *getComponent(Entity entityId)

Получает указатель на компонент сущности

Параметры шаблона:

T – Тип компонента

Параметры:

entityId – Идентификатор сущности

Результат:

Указатель на компонент или nullptr, если компонент не найден

template<typename T>
inline const std::vector<Entity> &getEntitiesWith() const

Получает все сущности, имеющие компонент указанного типа

Параметры шаблона:

T – Тип компонента

Результат:

Константная ссылка на * *вектор * *сущностей с компонентом. Вектор является частью внутреннего хранилища и обладает отличной локальностью данных. Время жизни ссылки ограничено временем жизни менеджера, но она остаётся валидной при добавлении/удалении других сущностей (кроме удаления последней сущности с компонентом T).

template<typename T>
inline StorageView<T> view() const

Возвращает view на хранилище компонентов типа T.

Результат:

StorageView, содержащий ссылки на внутренние векторы. Если хранилище не создано, возвращает view с пустыми векторами.

template<typename ...ComponentTypes>
inline std::vector<Entity> getEntitiesWithAll() const

Получает все сущности, имеющие все указанные типы компонентов

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

Параметры шаблона:

ComponentTypes – Типы компонентов для поиска

Результат:

Вектор сущностей, содержащих все запрошенные компоненты

void removeAllComponents(Entity entityId)

Удаляет все компоненты у сущности

Параметры:

entityId – Идентификатор сущности

Private Functions

template<typename T>
inline ComponentStorage<T> &getComponentStorage()

Получает или создаёт хранилище для конкретного типа компонента

Параметры шаблона:

T – Тип компонента

Результат:

Ссылка на хранилище компонентов типа T

template<typename T>
struct ComponentStorage : public prism::scene::ComponentManager::IComponentStorage

Конкретная реализация хранилища для типа компонента

Параметры шаблона:

T – Тип компонента

Public Members

std::vector<T> components

Плотный массив компонентов

struct IComponentStorage

Базовый интерфейс хранилища компонентов

Public Functions

virtual void removeEntity(Entity entityId) = 0

Удаляет все компоненты сущности из хранилища

Параметры:

entityId – Идентификатор сущности

template<typename T>
struct StorageView

Структура для прямого доступа к внутренним векторам компонентов и сущностей

Позволяет эффективно итерировать по компонентам без повторных поисков.

Public Members

const std::vector<T> &components

Плотный массив компонентов

const std::vector<Entity> &entities

Соответствующие сущности

SystemManager

class SystemManager

Менеджер систем для регистрации, включения/выключения и обновления систем.

Управляет коллекцией систем, обновляя их в порядке регистрации.

Public Functions

template<typename T, typename ...Args>
inline SystemId registerSystem(Args&&... args)

Регистрирует новую систему в менеджере.

Создает экземпляр системы и добавляет его в список управления

Параметры шаблона:
  • T – Тип системы (должен быть производным от ISystem).

  • Args – Типы аргументов для конструктора системы.

Параметры:

args – Аргументы для передачи конструктору системы.

Результат:

Идентификатор зарегистрированной системы.

void enableSystem(SystemId systemId)

Включает систему по идентификатору.

Параметры:

systemId – Идентификатор системы, которую нужно включить.

void disableSystem(SystemId systemId)

Выключает систему по идентификатору.

Параметры:

systemId – Идентификатор системы, которую нужно выключить.

void update()

Обновляет все активные системы, при первом бызове еще и вызывает start()

Вызывает: 1) start() в системах с неактивным started. 2) update() каждый вызыв. для всех включенных систем в порядке регистрации

Private Members

std::vector<std::unique_ptr<ISystem>> systems

Массив зарегистрированных систем

std::vector<ISystem*> activeSystems

Кэш активных систем для оптимизации обновления

ResourceManager

class ResourceManager

Менеджер ресурсов для управления глобальными данными в ECS-системе

Обеспечивает типобезопасное хранение и доступ к глобальным ресурсам, используя std::any для безопасного хранения объектов различных типов. Ресурсы представляют собой синглтон-подобные объекты, доступные всем системам сцены.

См. также

prism::scene::Resource

Public Functions

template<typename T>
inline void set(T resource)

Устанавливает или заменяет ресурс указанного типа

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

Примеры использования :

// Создание ресурса с конструктором по умолчанию
resources.set<TimeResource>(TimeResource{});

// Создание ресурса с параметрами
resources.set<WindowConfig>(WindowConfig{1280, 720, "My Game"});

Параметры шаблона:

T – Тип ресурса

Параметры:

resource – Объект ресурса для сохранения

template<typename T>
inline T *get()

Получает указатель на ресурс указанного типа

Обеспечивает быстрый доступ к ресурсу через безопасное приведение типа с помощью std::any_cast. Возвращает неконстантный указатель для возможности модификации ресурса.

/// Примеры использования:

// Получение ресурса для модификации
if (auto* time = resources.get<TimeResource>()) {
    time->update(deltaTime);
    time->setScale(2.0f);
}

// Цепочка вызовов
resources.get<WindowConfig>()->setResolution(1920, 1080);

Параметры шаблона:

T – Тип запрашиваемого ресурса

Результат:

Указатель на ресурс или nullptr если ресурс не найден

template<typename T>
inline const T *get() const

Получает константный указатель на ресурс указанного типа

Предназначен для безопасного доступа только для чтения. Используется в константных контекстах для гарантии неизменяемости ресурса.

/// Примеры использования:

// В константном методе системы
void render(const ResourceManager& resources) {
    if (const auto* config = resources.get<Config>()) {
        // config доступен только для чтения
        drawUI(config->getWidth(), config->getHeight());
    }
}

// Для отладочного вывода
void debugPrint(const ResourceManager& resources) {
    if (const auto* time = resources.get<TimeResource>()) {
        std::cout << "Game time: " << time->getTotalTime() << std::endl;
    }
}

Параметры шаблона:

T – Тип запрашиваемого ресурса

Результат:

Константный указатель на ресурс или nullptr если ресурс не найден

template<typename T>
inline bool has() const

Проверяет наличие ресурса указанного типа

Быстрая проверка существования ресурса без его загрузки. Используется для условной логики и ленивой инициализации ресурсов.

Примеры использования:

// Ленивая инициализация ресурса
if (!resources.has<Audio>()) {
    resources.set<Audio>(Audio{});
    resources.get<Audio>()->initialize();
}

// Условная логика системы
if (resources.has<DebugInfo>()) {
    drawDebugOverlay();
}

Параметры шаблона:

T – Тип проверяемого ресурса

Результат:

true если ресурс существует, false в противном случае

template<typename T>
inline bool remove()

Удаляет ресурс указанного типа

Освобождает память, занимаемую ресурсом. std::any гарантирует корректный вызов деструктора хранимого объекта при удалении.

Примеры использования:

// Удаление временного ресурса
resources.remove<DebugOverlay>();

// Удаление при перезагрузке
resources.remove<Config>();
resources.set<Config>(loadConfigFromFile());

// Проверка успешности удаления
if (resources.remove<ObsoleteResource>()) {
    std::cout << "Obsolete resource removed" << std::endl;
}

Параметры шаблона:

T – Тип удаляемого ресурса

Результат:

true если ресурс был удален, false если ресурс не существовал

inline void clear()

Очищает все ресурсы

Удаляет все зарегистрированные ресурсы. Используется в деструкторе и может быть вызван явно для принудительной очистки всех ресурсов.

Пример использования:

// При перезапуске игры
resources.clear();
initializeDefaultResources(resources);

inline ~ResourceManager()

Деструктор

Автоматически очищает все ресурсы при уничтожении менеджера. Гарантирует корректное освобождение памяти и вызов деструкторов для всех хранимых объектов через механизмы std::any.

Private Members

std::unordered_map<std::type_index, std::any> resources

Хранилище ресурсов

Использует комбинацию std::type_index и std::any для обеспечения типобезопасного хранения ресурсов.

Оптимизации

  • Пул сущностей - переиспользование ID

  • Раздельное хранение - компоненты по типам

  • Быстрый поиск - индексация сущностей по компонентам