-1

The title describes the situation, but the underlying problem might be something completely different.

I am trying to make a simple ECS game engine. I have a bunch of entities where each one contains a vector<shared_ptr<Component>>. Component is the base class for all the derived components.

During the game loop i have different Systems that update entities with certain components. The way I get the correct component for the system is with the following function

        template <typename T> 
        inline T& GetComponent(std::uint32_t type)
        {
            std::shared_ptr<Component> baseComponent = this->components[this->typeToIndexMap[type]];
            std::shared_ptr<T> component = std::static_pointer_cast<T>(baseComponent);
            return *(component.get());
        }

The issue is that when I try to modify the component in the system (inputComponent.lastX = 5.f;) it does not work. The next frame the values are the same. I am guessing that there happens some kind of cutoff because i am storing Component but am not sure how to solve this. Any ideas if that is actually the case and how I can solve it ?

Edit : Additional info

Entity holds components in a vector<shared_ptr<Component>>

Adding a Component

void Entity::AddComponent(std::shared_ptr<Component> component)
{
    this->components.push_back(component);
    this->componentBitset = this->componentBitset | component->GetComponentType();
    this->typeToIndexMap[component->GetComponentType()] = this->components.size() - 1;
}

Component Creation

std::shared_ptr<InputComponent> inputComponent = std::make_shared<InputComponent>(InputComponent());
entity->AddComponent(inputComponent);

Component Structure

class Component
{
public:
    // Constructor / Destructor
    Component(std::uint32_t type);
    ~Component();
    std::uint32_t GetComponentType();

private:
    std::uint32_t type;
};

Input Component

class InputComponent : public Component
{
    public:
        InputComponent();
        ~InputComponent();

        double lastX;
        double lastY;
};

Finally we have the system

void InputSystem::Update(GLFWwindow* window, std::vector<std::shared_ptr<Entity>>& entities)
{
    for (int i = 0; i < entities.size(); i++)
    {
        if (entities[i]->IsEligibleForSystem(this->primaryBitset))
        {
            InputComponent component = entities[i]->GetComponent<InputComponent>(ComponentType::Input);
            double x, y;
            glfwGetCursorPos(window, &x, &y);
            // some other things are happening here
            component.lastX = x;
            component.lastY = y;
        }
    }
}
Martin Spasov
  • 315
  • 3
  • 7
  • 23

1 Answers1

1

The problem is here:

InputComponent component = entities[i]->GetComponent<InputComponent>(ComponentType::Input);

You actually gets the InputComponent by value. Try to change GetComponent so it will return T*, and the first line I mentioned here change to:

InputComponent *component = entities[i]->GetComponent<InputComponent>(ComponentType::Input);
Coral Kashri
  • 3,436
  • 2
  • 10
  • 22