Question

For my game I have built a small framework which among other things has:

  • Entities that own components.
  • Systems that hold pointers to the entities.
  • An Engine that owns the systems.
  • An EntityManager that owns the entities.

Every time I add a Component, the Entity passes it's "this" pointer to the Systems through an Engine pointer that it holds and they decide whether to register it or ignore it.

Now, since the Entities are elements of the EntityManager's container, am I right in assuming that if an insert operation to it causes shifts or reallocation, the systems won't hold valid pointers any more?

If so, what's a good container that can be used to prevent this from happening? If I understand things correctly this is similar to what happens with iterators and the same rules should apply when requiring non-invalidation with insertion.

Was it helpful?

Solution

If you store a vector of entities and then just store their iterators to access them: yes, a reallocation might invalidate all your data.

The suggested way is to store a vector of pointers (if you need memory collection capabilities you might want to go for a vector of smart pointers). This way you will be sure that the pointers are valid (assuming nothing else touched the objects) at every insertion/deletion regardless of the reallocation of the container's space.

From the question isn't clear but a word of advice if you're just storing objects in your containers instead of pointers: when inserting elements into a container like with

std::vector<T>::push_back()

you're storing a copy of the object. This is usually undesirable since brings additional copy overhead and might create problems if things aren't properly set up. See "shallow copies" and "deep copies" to learn more about this problem.

OTHER TIPS

Your pointer value will only change if a relocation of the actual value happens. This is the case where you manipulate arrays of objects instead of arrays of pointers to these objects. You should definitely not do the former.

I would suggest using standard collections like std::array or std::vector to manage the objects. With those, and provided you have instanciated the objects on the heap (read: with new), you won't have to worry about the value of this.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top