Uses std::sort()

Uses std::sort() for inserting the nodes.

This code is not final, but preliminary results show that std::sort() is 60% faster

Signed-off-by: Ricardo Quesada <ricardoquesada@gmail.com>
This commit is contained in:
Ricardo Quesada 2013-08-24 10:56:07 -07:00
parent 364288cf66
commit ea8eb601af
6 changed files with 182 additions and 52 deletions

View File

@ -709,8 +709,33 @@ void Node::reorderChild(Node *child, int zOrder)
child->_setZOrder(zOrder);
}
#if CC_USE_ARRAY_VECTOR
static bool objectComparisonLess(const RCPtr<Object>& pp1, const RCPtr<Object>& pp2)
{
Object *p1 = static_cast<Object*>(pp1);
Object *p2 = static_cast<Object*>(pp2);
Node *n1 = static_cast<Node*>(p1);
Node *n2 = static_cast<Node*>(p2);
return( n1->getZOrder() < n2->getZOrder() ||
( n1->getZOrder() == n2->getZOrder() && n1->getOrderOfArrival() < n2->getOrderOfArrival() )
);
}
#else
static bool objectComparisonLess(Object* p1, Object* p2)
{
Node *n1 = static_cast<Node*>(p1);
Node *n2 = static_cast<Node*>(p2);
return( n1->getZOrder() < n2->getZOrder() ||
( n1->getZOrder() == n2->getZOrder() && n1->getOrderOfArrival() < n2->getOrderOfArrival() )
);
}
#endif
void Node::sortAllChildren()
{
#if 0
if (_reorderChildDirty)
{
int i,j,length = _children->count();
@ -737,6 +762,12 @@ void Node::sortAllChildren()
_reorderChildDirty = false;
}
#else
if( _reorderChildDirty ) {
std::sort( std::begin(*_children), std::end(*_children), objectComparisonLess );
_reorderChildDirty = false;
}
#endif
}

View File

@ -64,24 +64,6 @@ Object::~Object()
}
}
void Object::release()
{
CCASSERT(_reference > 0, "reference count should greater than 0");
--_reference;
if (_reference == 0)
{
delete this;
}
}
void Object::retain()
{
CCASSERT(_reference > 0, "reference count should greater than 0");
++_reference;
}
Object* Object::autorelease()
{
PoolManager::sharedPoolManager()->addObject(this);

View File

@ -26,6 +26,7 @@ THE SOFTWARE.
#define __CCOBJECT_H__
#include "cocoa/CCDataVisitor.h"
#include "ccMacros.h"
#ifdef EMSCRIPTEN
#include <GLES2/gl2.h>
@ -93,7 +94,14 @@ public:
*
* @see retain, autorelease
*/
void release();
inline void release()
{
CCASSERT(_reference > 0, "reference count should greater than 0");
--_reference;
if (_reference == 0)
delete this;
}
/**
* Retains the ownership.
@ -102,7 +110,11 @@ public:
*
* @see release, autorelease
*/
void retain();
inline void retain()
{
CCASSERT(_reference > 0, "reference count should greater than 0");
++_reference;
}
/**
* Release the ownership sometime soon automatically.

View File

@ -241,11 +241,36 @@ void SpriteBatchNode::removeAllChildrenWithCleanup(bool bCleanup)
_textureAtlas->removeAllQuads();
}
#if CC_USE_ARRAY_VECTOR
static bool objectComparisonLess(const RCPtr<Object>& pp1, const RCPtr<Object>& pp2)
{
Object *p1 = static_cast<Object*>(pp1);
Object *p2 = static_cast<Object*>(pp2);
Node *n1 = static_cast<Node*>(p1);
Node *n2 = static_cast<Node*>(p2);
return( n1->getZOrder() < n2->getZOrder() ||
( n1->getZOrder() == n2->getZOrder() && n1->getOrderOfArrival() < n2->getOrderOfArrival() )
);
}
#else
static bool objectComparisonLess(Object* p1, Object* p2)
{
Node *n1 = static_cast<Node*>(p1);
Node *n2 = static_cast<Node*>(p2);
return( n1->getZOrder() < n2->getZOrder() ||
( n1->getZOrder() == n2->getZOrder() && n1->getOrderOfArrival() < n2->getOrderOfArrival() )
);
}
#endif
//override sortAllChildren
void SpriteBatchNode::sortAllChildren()
{
if (_reorderChildDirty)
{
#if 0
int i = 0,j = 0,length = _children->count();
// insertion sort
@ -267,6 +292,9 @@ void SpriteBatchNode::sortAllChildren()
}
_children->fastSetObject(tempI, j+1);
}
#else
std::sort(std::begin(*_children), std::end(*_children), objectComparisonLess);
#endif
//sorted now check all children
if (_children->count() > 0)

View File

@ -39,6 +39,7 @@ static std::function<NodeChildrenMainScene*()> createFunctions[] =
CL(CallFuncsSpriteSheetCMacro),
CL(AddSpriteSheet),
CL(GetSpriteSheet),
CL(RemoveSpriteSheet),
CL(ReorderSpriteSheet),
CL(SortAllChildrenSpriteSheet),
@ -516,14 +517,13 @@ void AddSpriteSheet::update(float dt)
if( totalToAdd > 0 )
{
auto sprites = Array::createWithCapacity(totalToAdd);
Sprite **sprites = new Sprite*[totalToAdd];
int *zs = new int[totalToAdd];
// Don't include the sprite creation time and random as part of the profiling
for(int i=0; i<totalToAdd; i++)
{
auto sprite = Sprite::createWithTexture(batchNode->getTexture(), Rect(0,0,32,32));
sprites->addObject(sprite);
sprites[i] = Sprite::createWithTexture(batchNode->getTexture(), Rect(0,0,32,32));
zs[i] = CCRANDOM_MINUS1_1() * 50;
}
@ -532,7 +532,7 @@ void AddSpriteSheet::update(float dt)
for( int i=0; i < totalToAdd;i++ )
{
batchNode->addChild((Node*) (sprites->getObjectAtIndex(i)), zs[i], kTagBase+i);
batchNode->addChild( sprites[i], zs[i], kTagBase+i);
}
batchNode->sortAllChildren();
@ -542,9 +542,10 @@ void AddSpriteSheet::update(float dt)
// remove them
for( int i=0;i < totalToAdd;i++)
{
batchNode->removeChildByTag(kTagBase+i, true);
batchNode->removeChild( sprites[i], true);
}
delete [] sprites;
delete [] zs;
}
}
@ -564,6 +565,72 @@ const char* AddSpriteSheet::profilerName()
return "add sprites";
}
////////////////////////////////////////////////////////
//
// GetSpriteSheet
//
////////////////////////////////////////////////////////
void GetSpriteSheet::update(float dt)
{
// reset seed
//srandom(0);
// 15 percent
int totalToAdd = currentQuantityOfNodes * 0.15f;
if( totalToAdd > 0 )
{
Sprite **sprites = new Sprite*[totalToAdd];
int *zs = new int[totalToAdd];
// Don't include the sprite creation time and random as part of the profiling
for(int i=0; i<totalToAdd; i++)
{
sprites[i] = Sprite::createWithTexture(batchNode->getTexture(), Rect(0,0,32,32));
zs[i] = CCRANDOM_MINUS1_1() * 50;
}
for( int i=0; i < totalToAdd;i++ )
{
batchNode->addChild( sprites[i], zs[i], kTagBase+i);
}
batchNode->sortAllChildren();
CC_PROFILER_START( this->profilerName() );
for( int i=0; i < totalToAdd;i++ )
{
batchNode->getChildByTag(kTagBase+1);
}
CC_PROFILER_STOP(this->profilerName());
// remove them
for( int i=0;i < totalToAdd;i++)
{
batchNode->removeChild( sprites[i], true);
}
delete [] sprites;
delete [] zs;
}
}
std::string GetSpriteSheet::title()
{
return "G - getChildByTag from spritesheet";
}
std::string GetSpriteSheet::subtitle()
{
return "Get sprites using getChildByTag(). See console";
}
const char* GetSpriteSheet::profilerName()
{
return "get sprites";
}
////////////////////////////////////////////////////////
//
// RemoveSpriteSheet
@ -578,36 +645,35 @@ void RemoveSpriteSheet::update(float dt)
if( totalToAdd > 0 )
{
auto sprites = Array::createWithCapacity(totalToAdd);
Sprite **sprites = new Sprite*[totalToAdd];
// Don't include the sprite creation time as part of the profiling
for(int i=0;i<totalToAdd;i++)
{
auto sprite = Sprite::createWithTexture(batchNode->getTexture(), Rect(0,0,32,32));
sprites->addObject(sprite);
sprites[i] = Sprite::createWithTexture(batchNode->getTexture(), Rect(0,0,32,32));
}
// add them with random Z (very important!)
for( int i=0; i < totalToAdd;i++ )
{
batchNode->addChild((Node*) (sprites->getObjectAtIndex(i)), CCRANDOM_MINUS1_1() * 50, kTagBase+i);
batchNode->addChild( sprites[i], CCRANDOM_MINUS1_1() * 50, kTagBase+i);
}
// remove them
CC_PROFILER_START( this->profilerName() );
for( int i=0;i < totalToAdd;i++)
{
batchNode->removeChildByTag(kTagBase+i, true);
batchNode->removeChild( sprites[i], true);
}
CC_PROFILER_STOP( this->profilerName() );
delete [] sprites;
}
}
std::string RemoveSpriteSheet::title()
{
return "G - Del from spritesheet";
return "H - Del from spritesheet";
}
std::string RemoveSpriteSheet::subtitle()
@ -634,46 +700,43 @@ void ReorderSpriteSheet::update(float dt)
if( totalToAdd > 0 )
{
auto sprites = Array::createWithCapacity(totalToAdd);
Sprite **sprites = new Sprite*[totalToAdd];
// Don't include the sprite creation time as part of the profiling
for(int i=0; i<totalToAdd; i++)
{
auto sprite = Sprite::createWithTexture(batchNode->getTexture(), Rect(0,0,32,32));
sprites->addObject(sprite);
sprites[i] = Sprite::createWithTexture(batchNode->getTexture(), Rect(0,0,32,32));
}
// add them with random Z (very important!)
for( int i=0; i < totalToAdd;i++ )
{
batchNode->addChild((Node*) (sprites->getObjectAtIndex(i)), CCRANDOM_MINUS1_1() * 50, kTagBase+i);
batchNode->addChild( sprites[i], CCRANDOM_MINUS1_1() * 50, kTagBase+i);
}
batchNode->sortAllChildren();
// reorder them
CC_PROFILER_START( this->profilerName() );
for( int i=0;i < totalToAdd;i++)
{
auto node = (Node*) (batchNode->getChildren()->getObjectAtIndex(i));
batchNode->reorderChild(node, CCRANDOM_MINUS1_1() * 50);
batchNode->reorderChild(sprites[i], CCRANDOM_MINUS1_1() * 50);
}
batchNode->sortAllChildren();
CC_PROFILER_STOP( this->profilerName() );
// remove them
for( int i=0;i < totalToAdd;i++)
{
batchNode->removeChildByTag(kTagBase+i, true);
batchNode->removeChild( sprites[i], true);
}
delete [] sprites;
}
}
std::string ReorderSpriteSheet::title()
{
return "H - Reorder from spritesheet";
return "I - Reorder from spritesheet";
}
std::string ReorderSpriteSheet::subtitle()
@ -700,19 +763,18 @@ void SortAllChildrenSpriteSheet::update(float dt)
if( totalToAdd > 0 )
{
auto sprites = Array::createWithCapacity(totalToAdd);
Sprite **sprites = new Sprite*[totalToAdd];
// Don't include the sprite's creation time as part of the profiling
for(int i=0; i<totalToAdd; i++)
{
auto sprite = Sprite::createWithTexture(batchNode->getTexture(), Rect(0,0,32,32));
sprites->addObject(sprite);
sprites[i] = Sprite::createWithTexture(batchNode->getTexture(), Rect(0,0,32,32));
}
// add them with random Z (very important!)
for( int i=0; i < totalToAdd;i++ )
{
batchNode->addChild((Node*) (sprites->getObjectAtIndex(i)), CCRANDOM_MINUS1_1() * 50, kTagBase+i);
batchNode->addChild( sprites[i], CCRANDOM_MINUS1_1() * 50, kTagBase+i);
}
batchNode->sortAllChildren();
@ -720,21 +782,26 @@ void SortAllChildrenSpriteSheet::update(float dt)
// reorder them
for( int i=0;i < totalToAdd;i++)
{
auto node = (Node*) (batchNode->getChildren()->getObjectAtIndex(i));
batchNode->reorderChild(node, CCRANDOM_MINUS1_1() * 50);
batchNode->reorderChild(sprites[i], CCRANDOM_MINUS1_1() * 50);
}
CC_PROFILER_START( this->profilerName() );
batchNode->sortAllChildren();
CC_PROFILER_STOP( this->profilerName() );
batchNode->removeAllChildrenWithCleanup(true);
// remove them
for( int i=0;i < totalToAdd;i++)
{
batchNode->removeChild( sprites[i], true);
}
delete [] sprites;
}
}
std::string SortAllChildrenSpriteSheet::title()
{
return "H - Sort All Children from spritesheet";
return "J - Sort All Children from spritesheet";
}
std::string SortAllChildrenSpriteSheet::subtitle()

View File

@ -128,6 +128,16 @@ public:
virtual const char* profilerName();
};
class GetSpriteSheet : public AddRemoveSpriteSheet
{
public:
virtual void update(float dt);
virtual std::string title();
virtual std::string subtitle();
virtual const char* profilerName();
};
class RemoveSpriteSheet : public AddRemoveSpriteSheet
{
public: