I am currently writing my own ECS in C++ and I am using std::bitset
.
I register a component at compile time and give it an ID.
Position has ID 1
Direction has ID 2
..
vector<bitset<numberOfComponents>>
And so on. The problem with this approach is the more components I register the bigger my bitset for every entity will get.
If I overshoot my goal a bit and say that I will have 1000 components and 5000 entities.
A std::bitset<1000> is 128 bytes big of my machine and for 5000 entities that is 640kbytes of overhead. To be fair that is actually not that big considering that many machines have 8 gigs of ram.
But I am wondering how you guys are doing it? How do you filter your entities? Are you also using something like a component mask?
Update based on congusbongus answer:
vector<DrawComponent> c1;
vector<MoveComponent> c2;
vector<Entity> draw = {1, 2, 8, 42,128}
vector<Entity> move = {8,128};
I assume that is how you think it works right? Two questions:
1.) How do you make vector<Entity> draw = {1, 2, 8, 42,128}
contiguous in memory? If the id is just the index into a vector there will be a lot of "holes".
2.) Because there is no filter, how do you then associate entities together? If you have system System<Draw,Move>
, you need the Draw and Move component and because of
vector<Entity> draw = {1, 2, 8, 42,128}
vector<Entity> move = {8,128};
if you just iterate over both of them it doesn't work. because move[0] = 8
, and draw[0] = 1
.
I mean if you draw something you actually need the draw and move component because u need to draw at a specific position.