I think this may be very helpfulI'm horrified that you're even considering resorting the draw list every frame. You're insane :shock:
You're basing the depth (Z) of each object on their y value, so it's unlikely to change much every frame. Maybe 15-20 per frame maximum. So why not pull each element out, shift it along left or right, and reinsert it again?
Hell, if the order doesn't change, you needn't even erase the element in the first place, and in practice 90% of the Drawables don't need to be moved each frame: you're effectively reinserting them back where they were before!
Here's some code that's technically O(n) in the worst case scenario, but in practice it generally works at O(1)
Drawable :: updatePosition()
{
if(movement.y )
Level::getInstance()->setDrawableDepth(this,position.y+movement.y)
position+=movement;
}
and
Level::setDrawableDepth(Drawable* drawable, uint newDepth)
{
short side = sign(newDepth - drawable->getDepth());
if(!sign) //no need to move: no change in depth
return;
if(sign > 0)
{
Draw_container::iterator i = drawable->getDrawNode();
if(i == draw_list.end()) //no need to move: highest depth
return;
i++; //'i' now points to element to this right of 'visible'
if((*i)->getDepth()>=newDepth) //no need to move: already sorted
return;
i++;
static bool added;
added = false;
while(!added && i != draw_list.end())
{
if((*i)->getDepth()>=newDepth)
{
draw_list.insert(i,visible); //add 'visible' in front of i
added = true;
i-- //move i back to point at 'visible'
}
else
i++;
}
if(!added) //i == draw_list.end()
{
draw_list.push_back(visible);
i = draw_list.end(); i--; //better safe than sorry ;-)
}
}
/* similar sort of thing for i < 0 */
//remember to remove the original reference to 'visible'
draw_list.erase(visible->getDrawNode());
//reset the draw node
visible->setDrawNode(i);
}
That's ~pseudocode written from memory, but PM me if you want to look at what I actually wrote. The point is that it works, and in stress tests performs a lot better than reinsertion from the beginning (eg - calling the function used to create the draw list in the first place).