3
\$\begingroup\$

I'm implementing a basic entity component system from http://entity-systems.wikidot.com/rdbms-with-code-in-systems#java in C++, but I don't quite understand how I could do multiple components (not the same component. I don't see a need to have 2 of the same components yet) in a system. In an inherited System, for example, MovementSystem, I want it to be able to act on all entities that have a position component and a velocity component. However, in my code, I would do

std::vector<Component *> positionComps = entityManager->GetAllComponentsOfType(POSITION_COMPONENT);
std::vector<Component *>::iterator it = components.begin();
for (; it != positionComps; it++) {
    PositionComponent *pos = dynamic_cast<PositionComponent *>(it);
    pos->x += velo->x;
}

I don't know how I could get the velocity component in there, as it is looping through the position components. I could get all of components of type velocity inside that loop and have a nested loop, but that would be bad on the performance. Also, how would you know which component goes with which? There is a function of GetAllEntitiesPossessingComponent which returns a list of integers so I can later then get the specific component of the entity and check if the entity has the two components. Also, if the component returned was NULL, I would have to check in the system before I do anything if it's NULL or not. But all of this doesn't seem right.

I COULD merge PositionComponent and VelocityComponent into one and then act on that in the system, but that wouldn't help me with future components.

\$\endgroup\$
1
\$\begingroup\$

You need to iterate on entities, not components. Each system maintains a list of all the entities that have all the components that system needs to do its thing. In your example, the system is your MovementSystem. The MovementSystem maintains a list of all the entities that have a Position and Velocity component. Then, when it's time to work, it just iterates on those entities. For each iteration it will fetch the Position and Velocity components from the entity, and use those in its calculation. See here for more details.

It's easy to maintain a list if you have your systems notified when an entity has a component added or removed. They can just check their bit mask against the entity mask. If you don't want to maintain a list, you need to make a GetAllEntitiesPossessingComponents that takes a bit mask defining the components to retrieve.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.