Внутренние менеджеры 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 в противном случае
-
Entity createEntity()
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 – Идентификатор сущности
-
virtual void removeEntity(Entity entityId) = 0
-
template<typename T>
struct StorageView Структура для прямого доступа к внутренним векторам компонентов и сущностей
Позволяет эффективно итерировать по компонентам без повторных поисков.
-
template<typename T>
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() каждый вызыв. для всех включенных систем в порядке регистрации
См. также
-
template<typename T, typename ...Args>
ResourceManager
-
class ResourceManager
Менеджер ресурсов для управления глобальными данными в ECS-системе
Обеспечивает типобезопасное хранение и доступ к глобальным ресурсам, используя std::any для безопасного хранения объектов различных типов. Ресурсы представляют собой синглтон-подобные объекты, доступные всем системам сцены.
См. также
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 для обеспечения типобезопасного хранения ресурсов.
-
template<typename T>
Оптимизации
Пул сущностей - переиспользование ID
Раздельное хранение - компоненты по типам
Быстрый поиск - индексация сущностей по компонентам