I'm working on an entity-component system (ECS), inspired on Bitsquid's blog series. My ECS is composed of two main classes: System (responsible for creating/destroying entities) and Property (responsible for storing a std::vector of a component, for a given System).
When an Entity is created/destroyed, the System triggers some signals to keep the Property instances aware of the state-change on Systems, in order to keep the data contiguous and well-mapped.
Follow below a simple example of a system of cars, and each car has two properties: point2d position, std::string name.
System<Car> cars;
Property<Car, point2d> positions(cars);
Property<Car, std::string> names(cars);
auto car0 = cars.add();
auto car1 = cars.add();
positions[car0] = {0.0, 0.0};
names[car0] = "Car 0";
positions[car1] = {1.0, 2.0};
names[car1] = "Car 1";
This way I can keep the data in separate "arrays".
Let's suppose I want to add 1000 Entities. I could do it calling std::vector::reserve(1000) on all of the properties, and then doing 1000 push_back on each one of them.
I've identified a problem on such approach: I would need 1+N reserves, if I have N properties. I was wondering if I could use a std::vector<tuple<point2d, std::string>> for handling the memory allocations, but manage the data pretending (reinterpret cast?) I have the all the point2d stored contiguously, followed by the strings.
This way I could take advantage of std::vector api for saving notifying/reserve/resizing operations. Although I'd have to adapt the accessing methods (like vector::at, operator[], begin, end).
Do you have any ideas on how to achieve that? Or any alternate suggestions if you think this is not a good idea?
Aucun commentaire:
Enregistrer un commentaire