Original Post
I've been reading up on using data-oriented design principles (I now use c++, but came into programming through Java and strict OOP) and component based design, and trying to bend my head round towards the newer way of thinking about things.
One part I'm having trouble with is containers to actually hold the assorted components. In an OOP design (or at least, the things I've been writing in the past) any new objects are created on the heap, and a collection of pointers stored in say, a std::vector. This lets you store multiple pointers to the objects in various lists and also lets you add and delete objects happily. A problem is that because the objects are created dynamically, they're all over the place in memory which is really bad for cache misses, hence the more modern movement over to data oriented design. Am I right so far?
This involves splitting big classes with lots of inheritance into smaller components dealing with specific tasks and linking everything together with composition. The components themselves are stored in contiguous memory and this plus their smaller size means that as these containers are iterated over, several objects can be loaded into the cache at once from memory, improving performance significantly. Again, please correct me if I've got this wrong.
My problem is how are the containers of components to be implemented? To keep the memory they use contiguous, the objects have to be created on the stack and the objects themselves stored in a container, rather than just storing pointers in a container. How then do you cope when you have a changing number of objects? You can't use a std::vector because as you add more objects to the world, the vector would reassign it's arrays and have to create all the components again. This would also mean you wouldn't be able to store pointers to them as the memory location of the components would change if the vector changes size.
You could use an ordinary array, resized to some large arbitrary size (or a vector, and use reserve) but this would mean keeping every object you ever create in memory, and reserving memory for every object you are ever going to create, which is plainly ridiculous.
Can anyone guide me in the right direction?
One part I'm having trouble with is containers to actually hold the assorted components. In an OOP design (or at least, the things I've been writing in the past) any new objects are created on the heap, and a collection of pointers stored in say, a std::vector. This lets you store multiple pointers to the objects in various lists and also lets you add and delete objects happily. A problem is that because the objects are created dynamically, they're all over the place in memory which is really bad for cache misses, hence the more modern movement over to data oriented design. Am I right so far?
This involves splitting big classes with lots of inheritance into smaller components dealing with specific tasks and linking everything together with composition. The components themselves are stored in contiguous memory and this plus their smaller size means that as these containers are iterated over, several objects can be loaded into the cache at once from memory, improving performance significantly. Again, please correct me if I've got this wrong.
My problem is how are the containers of components to be implemented? To keep the memory they use contiguous, the objects have to be created on the stack and the objects themselves stored in a container, rather than just storing pointers in a container. How then do you cope when you have a changing number of objects? You can't use a std::vector because as you add more objects to the world, the vector would reassign it's arrays and have to create all the components again. This would also mean you wouldn't be able to store pointers to them as the memory location of the components would change if the vector changes size.
You could use an ordinary array, resized to some large arbitrary size (or a vector, and use reserve) but this would mean keeping every object you ever create in memory, and reserving memory for every object you are ever going to create, which is plainly ridiculous.
Can anyone guide me in the right direction?