Вектор теряет ссылку на записи после функции для добавления к векторам

Я внедряю Компонентную Систему Entity и испытываю проблемы, когда пытаюсь добавить Компонент к Entity. Структура этого выглядит следующим образом:

Ниже вы найдете сущность с идентификатором 0 и добавите к ней компонент Position.

m_entityManager->addComponentToEntityID(0, ComponentManager::POSITION);

void EntityManager::addComponentToEntityID(unsigned int entityID, ComponentManager::ComponentType componentType)
{
std::shared_ptr<Entity> tempEntity;

for (unsigned int index = 0; index < m_maximumEntities; ++index)
{
if (m_entityVector[index].getEntityID() == entityID)
{
addComponentToEntity(std::make_shared<Entity>(m_entityVector[index]), componentType);
break;
}
}
}

Вышеприведенное — это просто вспомогательная функция, которая сначала находит Entity, а затем вызывает следующую функцию:

void EntityManager::addComponentToEntity(std::shared_ptr<Entity> entity, ComponentManager::ComponentType componentType)
{
if (entity != nullptr)
{
switch (componentType)
{
case ComponentManager::POSITION:
entity->addComponent(m_componentManager->getUnassignedPositionComponent());
break;

default:
break;
}
}
}

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

PositionComponent& ComponentManager::getUnassignedPositionComponent()
{
for (unsigned int index = 0; index < m_positionComponentVector.size(); ++index)
{
if (m_positionComponentVector[index].isAssigned() == false)
{
m_positionComponentVector[index].assign();
return m_positionComponentVector[index];
}
}
}

Наконец, внутри Entity у нас есть эта функция:

void Entity::addComponent(Component& component)
{
m_componentVector.push_back(component);
}

Сущности содержатся внутри вектора внутри EntityManager, созданного как обычные объекты в стеке. Это то же самое для компонентов Position, находящихся внутри ComponentManager.

Моя цель — сохранить все Компоненты внутри ComponentManager, и системы отправят запрос в ComponentManager для какой-либо обработки компонента. Я хочу сохранить указатели или ссылки для каждой сущности на принадлежащие ей компоненты.

Моя проблема в том, что, когда Entity :: addComponent () завершен, вектор m_componentVector больше не содержит добавленный к нему компонент, как будто он выпадает из области видимости. Я думаю, что проблема где-то я передаю копию вместо ссылки? У меня изначально были параметры в качестве указателей, но я пытался их исправить.

3

Решение

Соответствующий факт из комментариев: Entity::m_componentVector определяется как

std::vector<Component> m_componentVector;

Это вектор, который хранит Component объекты, а не ссылки. Таким образом, в Entity::addComponent, линия

m_componentVector.push_back(component);

сделает копию объекта, на который ссылается component и добавить его в вектор. Эта копия не зависит от объекта, скопированного из.

Что еще хуже, component параметр для addComponent на самом деле ссылается на объект типа PositionComponent (который предположительно происходит от Component). При создании копии, указанной выше, только часть, соответствующая Component, базовый класс, будет скопирован. Это известно как нарезка — части, добавленные производным классом, просто «обрезаются».

Вы хотите сделать Entity’s m_componentVector ссылаться на компоненты, хранящиеся в ComponentManager, Вы не можете хранить ссылки в векторе. Вы можете хранить указатели, но указатели на векторные элементы могут быть недействительными, если к вектору добавлены дополнительные элементы (то есть, если вы сохраняете указатель на m_positionComponentVector[0]и позже добавляются дополнительные элементы m_positionComponentVector так что перераспределение необходимо, указатель, который вы сохранили, станет недействительным). Таким образом, хранение индексов — ваш самый безопасный вариант.

1

Другие решения


По вопросам рекламы ammmcru@yandex.ru
Adblock
detector