I have an Entity
class that can be either dead or alive.
I store entities contiguously in a resizable array. During an update()
, some alive entities can become dead, and some new entities can be added at the end of the array.
The range [0 .. size)
contains all non-newly-created entities.
The range [size .. sizeNext)
contains all newly-created entities (guaranteed to be alive).
After update()
, I call refresh()
. This function does:
Swap around entities making sure that all alive entities are stored contiguously at the beginning of the array (and that all dead entities are stored contiguously at the end of the array).
Deinitialize all dead entities.
Update
size
andsizeNext
.
Basically, the algorithm uses two iterators:
iD
moves from left to right, looking for dead entities.iA
moves from right to left, looking for alive entities.
When iD
and iA
find an entity, the entities are swapped and the iterators advance.
Here's a quick drawing of the algorithm:
And here's the current code:
void refresh()
{
// `sizeNext` is unsigned - copy it as a signed value
// to store its initial value and compare it to integers.
const int intSizeNext(sizeNext);
// `iD` walks from left to right, looking for dead entities.
// `iA` walks from right to left, looking for alive entities.
int iD{0}, iA{intSizeNext - 1};
do
{
// Find dead item from left
for(; true; ++iD)
{
// No more dead items
if(iD > iA) goto finishRefresh;
if(isDeadAt(iD)) break;
}
// Find alive item from right
for(; true; --iA)
{
// No more alive items
if(iA <= iD) goto finishRefresh;
if(isAliveAt(iA)) break;
}
assert(isDeadAt(iD) && isAliveAt(iA));
std::swap(items[iD], items[iA]);
assert(isAliveAt(iD) && isDeadAt(iA));
// Advance both iterators
++iD; --iA;
}
while(true);
finishRefresh:
for(iA = iA - 1; iA >= 0; --iA)
{
assert(isAliveAt(iA));
}
msize = sizeNext = iD;
for(; iD < intSizeNext; ++iD)
{
assert(isDeadAt(iD));
deinitAt(iD);
}
}
- Can the code be improved/optimized?
- Can the
goto
instructions be avoided? - Is there a more efficient algorithm that achieves the same results?