Merge branch 'develop' of https://github.com/cocos2d/cocos2d-x into iss2433-lua-bindings-generator-new

This commit is contained in:
samuele3hu 2013-09-02 10:55:31 +08:00
commit 71e0c4064a
11 changed files with 329 additions and 188 deletions

View File

@ -54,6 +54,30 @@ THE SOFTWARE.
NS_CC_BEGIN NS_CC_BEGIN
#if CC_USE_ARRAY_VECTOR
bool nodeComparisonLess(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
bool nodeComparisonLess(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
// XXX: Yes, nodes might have a sort problem once every 15 days if the game runs at 60 FPS and each frame sprites are reordered. // XXX: Yes, nodes might have a sort problem once every 15 days if the game runs at 60 FPS and each frame sprites are reordered.
static int s_globalOrderOfArrival = 1; static int s_globalOrderOfArrival = 1;
@ -714,30 +738,6 @@ void Node::reorderChild(Node *child, int zOrder)
child->_setZOrder(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() void Node::sortAllChildren()
{ {
#if 0 #if 0
@ -769,7 +769,7 @@ void Node::sortAllChildren()
} }
#else #else
if( _reorderChildDirty ) { if( _reorderChildDirty ) {
std::sort( std::begin(*_children), std::end(*_children), objectComparisonLess ); std::sort( std::begin(*_children), std::end(*_children), nodeComparisonLess );
_reorderChildDirty = false; _reorderChildDirty = false;
} }
#endif #endif

View File

@ -66,6 +66,12 @@ enum {
kNodeOnCleanup kNodeOnCleanup
}; };
#if CC_USE_ARRAY_VECTOR
bool nodeComparisonLess(const RCPtr<Object>& pp1, const RCPtr<Object>& pp2);
#else
bool nodeComparisonLess(Object* p1, Object* p2);
#endif
/** @brief Node is the main element. Anything that gets drawn or contains things that get drawn is a Node. /** @brief Node is the main element. Anything that gets drawn or contains things that get drawn is a Node.
The most popular Nodes are: Scene, Layer, Sprite, Menu. The most popular Nodes are: Scene, Layer, Sprite, Menu.

View File

@ -107,6 +107,8 @@ Array* Array::createWithArray(Array* otherArray)
Array* Array::createWithCapacity(int capacity) Array* Array::createWithCapacity(int capacity)
{ {
CCASSERT(capacity>=0, "Invalid capacity");
Array* array = new Array(); Array* array = new Array();
if (array && array->initWithCapacity(capacity)) if (array && array->initWithCapacity(capacity))
@ -182,6 +184,8 @@ bool Array::initWithObjects(Object* object, ...)
bool Array::initWithCapacity(int capacity) bool Array::initWithCapacity(int capacity)
{ {
CCASSERT(capacity>=0, "Invalid capacity");
data.reserve(capacity); data.reserve(capacity);
return true; return true;
} }
@ -446,6 +450,8 @@ Array* Array::createWithArray(Array* otherArray)
Array* Array::createWithCapacity(int capacity) Array* Array::createWithCapacity(int capacity)
{ {
CCASSERT(capacity>=0, "Invalid capacity");
Array* array = new Array(); Array* array = new Array();
if (array && array->initWithCapacity(capacity)) if (array && array->initWithCapacity(capacity))
@ -527,7 +533,7 @@ bool Array::initWithObjects(Object* object, ...)
bool Array::initWithCapacity(int capacity) bool Array::initWithCapacity(int capacity)
{ {
CCASSERT(!data, "Array cannot be re-initialized"); CCASSERT(capacity>=0 && !data, "Array cannot be re-initialized");
data = ccArrayNew(capacity); data = ccArrayNew(capacity);
return true; return true;

View File

@ -25,6 +25,8 @@ THE SOFTWARE.
****************************************************************************/ ****************************************************************************/
#include "CCSpriteBatchNode.h" #include "CCSpriteBatchNode.h"
#include <string.h>
#include <algorithm>
#include "CCAnimation.h" #include "CCAnimation.h"
#include "CCAnimationCache.h" #include "CCAnimationCache.h"
#include "ccConfig.h" #include "ccConfig.h"
@ -44,7 +46,7 @@ THE SOFTWARE.
#include "support/CCProfiling.h" #include "support/CCProfiling.h"
// external // external
#include "kazmath/GL/matrix.h" #include "kazmath/GL/matrix.h"
#include <string.h>
using namespace std; using namespace std;
@ -693,6 +695,7 @@ void Sprite::sortAllChildren()
{ {
if (_reorderChildDirty) if (_reorderChildDirty)
{ {
#if 0
int i = 0, j = 0, length = _children->count(); int i = 0, j = 0, length = _children->count();
// insertion sort // insertion sort
@ -714,6 +717,9 @@ void Sprite::sortAllChildren()
} }
_children->fastSetObject(tempI, j+1); _children->fastSetObject(tempI, j+1);
} }
#else
std::sort(std::begin(*_children), std::end(*_children), nodeComparisonLess);
#endif
if ( _batchNode) if ( _batchNode)
{ {
@ -904,7 +910,7 @@ void Sprite::updateColor(void)
// renders using batch node // renders using batch node
if (_batchNode) if (_batchNode)
{ {
if (_atlasIndex != kSpriteIndexNotInitialized) if (_atlasIndex != INDEX_NOT_INITIALIZED)
{ {
_textureAtlas->updateQuad(&_quad, _atlasIndex); _textureAtlas->updateQuad(&_quad, _atlasIndex);
} }
@ -1024,7 +1030,7 @@ void Sprite::setBatchNode(SpriteBatchNode *spriteBatchNode)
// self render // self render
if( ! _batchNode ) { if( ! _batchNode ) {
_atlasIndex = kSpriteIndexNotInitialized; _atlasIndex = INDEX_NOT_INITIALIZED;
setTextureAtlas(NULL); setTextureAtlas(NULL);
_recursiveDirty = false; _recursiveDirty = false;
setDirty(false); setDirty(false);
@ -1102,7 +1108,7 @@ void Sprite::setTexture(Texture2D *texture)
{ {
Image* image = new Image(); Image* image = new Image();
bool isOK = image->initWithRawData(cc_2x2_white_image, sizeof(cc_2x2_white_image), 2, 2, 8); bool isOK = image->initWithRawData(cc_2x2_white_image, sizeof(cc_2x2_white_image), 2, 2, 8);
CCAssert(isOK, "The 2x2 empty texture was created unsuccessfully."); CCASSERT(isOK, "The 2x2 empty texture was created unsuccessfully.");
texture = TextureCache::getInstance()->addUIImage(image, CC_2x2_WHITE_IMAGE_KEY); texture = TextureCache::getInstance()->addUIImage(image, CC_2x2_WHITE_IMAGE_KEY);
CC_SAFE_RELEASE(image); CC_SAFE_RELEASE(image);

View File

@ -83,7 +83,7 @@ class CC_DLL Sprite : public NodeRGBA, public TextureProtocol
{ {
public: public:
static const int kSpriteIndexNotInitialized = -1; /// Sprite invalid index on the SpriteBatchNode static const int INDEX_NOT_INITIALIZED = -1; /// Sprite invalid index on the SpriteBatchNode
/// @{ /// @{
/// @name Creators /// @name Creators

View File

@ -49,7 +49,7 @@ NS_CC_BEGIN
* creation with Texture2D * creation with Texture2D
*/ */
SpriteBatchNode* SpriteBatchNode::createWithTexture(Texture2D* tex, int capacity/* = kDefaultSpriteBatchCapacity*/) SpriteBatchNode* SpriteBatchNode::createWithTexture(Texture2D* tex, int capacity/* = DEFAULT_CAPACITY*/)
{ {
SpriteBatchNode *batchNode = new SpriteBatchNode(); SpriteBatchNode *batchNode = new SpriteBatchNode();
batchNode->initWithTexture(tex, capacity); batchNode->initWithTexture(tex, capacity);
@ -62,7 +62,7 @@ SpriteBatchNode* SpriteBatchNode::createWithTexture(Texture2D* tex, int capacity
* creation with File Image * creation with File Image
*/ */
SpriteBatchNode* SpriteBatchNode::create(const char *fileImage, int capacity/* = kDefaultSpriteBatchCapacity*/) SpriteBatchNode* SpriteBatchNode::create(const char *fileImage, int capacity/* = DEFAULT_CAPACITY*/)
{ {
SpriteBatchNode *batchNode = new SpriteBatchNode(); SpriteBatchNode *batchNode = new SpriteBatchNode();
batchNode->initWithFile(fileImage, capacity); batchNode->initWithFile(fileImage, capacity);
@ -81,9 +81,9 @@ bool SpriteBatchNode::initWithTexture(Texture2D *tex, int capacity)
_blendFunc = BlendFunc::ALPHA_PREMULTIPLIED; _blendFunc = BlendFunc::ALPHA_PREMULTIPLIED;
_textureAtlas = new TextureAtlas(); _textureAtlas = new TextureAtlas();
if (0 == capacity) if (capacity == 0)
{ {
capacity = kDefaultSpriteBatchCapacity; capacity = DEFAULT_CAPACITY;
} }
_textureAtlas->initWithTexture(tex, capacity); _textureAtlas->initWithTexture(tex, capacity);
@ -175,13 +175,13 @@ void SpriteBatchNode::addChild(Node *child, int zOrder, int tag)
{ {
CCASSERT(child != NULL, "child should not be null"); CCASSERT(child != NULL, "child should not be null");
CCASSERT(dynamic_cast<Sprite*>(child) != NULL, "CCSpriteBatchNode only supports Sprites as children"); CCASSERT(dynamic_cast<Sprite*>(child) != NULL, "CCSpriteBatchNode only supports Sprites as children");
Sprite *pSprite = (Sprite*)(child); Sprite *sprite = static_cast<Sprite*>(child);
// check Sprite is using the same texture id // check Sprite is using the same texture id
CCASSERT(pSprite->getTexture()->getName() == _textureAtlas->getTexture()->getName(), "CCSprite is not using the same texture id"); CCASSERT(sprite->getTexture()->getName() == _textureAtlas->getTexture()->getName(), "CCSprite is not using the same texture id");
Node::addChild(child, zOrder, tag); Node::addChild(child, zOrder, tag);
appendChild(pSprite); appendChild(sprite);
} }
void SpriteBatchNode::addChild(Node *child) void SpriteBatchNode::addChild(Node *child)
@ -212,63 +212,40 @@ void SpriteBatchNode::reorderChild(Node *child, int zOrder)
// override remove child // override remove child
void SpriteBatchNode::removeChild(Node *child, bool cleanup) void SpriteBatchNode::removeChild(Node *child, bool cleanup)
{ {
Sprite *pSprite = (Sprite*)(child); Sprite *sprite = static_cast<Sprite*>(child);
// explicit null handling // explicit null handling
if (pSprite == NULL) if (sprite == NULL)
{ {
return; return;
} }
CCASSERT(_children->containsObject(pSprite), "sprite batch node should contain the child"); CCASSERT(_children->containsObject(sprite), "sprite batch node should contain the child");
// cleanup before removing // cleanup before removing
removeSpriteFromAtlas(pSprite); removeSpriteFromAtlas(sprite);
Node::removeChild(pSprite, cleanup); Node::removeChild(sprite, cleanup);
} }
void SpriteBatchNode::removeChildAtIndex(unsigned int uIndex, bool bDoCleanup) void SpriteBatchNode::removeChildAtIndex(int index, bool doCleanup)
{ {
removeChild((Sprite*)(_children->getObjectAtIndex(uIndex)), bDoCleanup); CCASSERT(index>=0 && index < _children->count(), "Invalid index");
removeChild( static_cast<Sprite*>(_children->getObjectAtIndex(index)), doCleanup);
} }
void SpriteBatchNode::removeAllChildrenWithCleanup(bool bCleanup) void SpriteBatchNode::removeAllChildrenWithCleanup(bool doCleanup)
{ {
// Invalidate atlas index. issue #569 // Invalidate atlas index. issue #569
// useSelfRender should be performed on all descendants. issue #1216 // useSelfRender should be performed on all descendants. issue #1216
arrayMakeObjectsPerformSelectorWithObject(_descendants, setBatchNode, NULL, Sprite*); arrayMakeObjectsPerformSelectorWithObject(_descendants, setBatchNode, NULL, Sprite*);
Node::removeAllChildrenWithCleanup(bCleanup); Node::removeAllChildrenWithCleanup(doCleanup);
_descendants->removeAllObjects(); _descendants->removeAllObjects();
_textureAtlas->removeAllQuads(); _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 //override sortAllChildren
void SpriteBatchNode::sortAllChildren() void SpriteBatchNode::sortAllChildren()
{ {
@ -297,7 +274,7 @@ void SpriteBatchNode::sortAllChildren()
_children->fastSetObject(tempI, j+1); _children->fastSetObject(tempI, j+1);
} }
#else #else
std::sort(std::begin(*_children), std::end(*_children), objectComparisonLess); std::sort(std::begin(*_children), std::end(*_children), nodeComparisonLess);
#endif #endif
//sorted now check all children //sorted now check all children
@ -308,12 +285,12 @@ void SpriteBatchNode::sortAllChildren()
int index=0; int index=0;
Object* pObj = NULL; Object* obj = NULL;
//fast dispatch, give every child a new atlasIndex based on their relative zOrder (keep parent -> child relations intact) //fast dispatch, give every child a new atlasIndex based on their relative zOrder (keep parent -> child relations intact)
// and at the same time reorder descendants and the quads to the right index // and at the same time reorder descendants and the quads to the right index
CCARRAY_FOREACH(_children, pObj) CCARRAY_FOREACH(_children, obj)
{ {
Sprite* child = static_cast<Sprite*>(pObj); Sprite* child = static_cast<Sprite*>(obj);
updateAtlasIndex(child, &index); updateAtlasIndex(child, &index);
} }
} }
@ -324,7 +301,7 @@ void SpriteBatchNode::sortAllChildren()
void SpriteBatchNode::updateAtlasIndex(Sprite* sprite, int* curIndex) void SpriteBatchNode::updateAtlasIndex(Sprite* sprite, int* curIndex)
{ {
unsigned int count = 0; int count = 0;
Array* array = sprite->getChildren(); Array* array = sprite->getChildren();
if (array != NULL) if (array != NULL)
{ {
@ -362,10 +339,10 @@ void SpriteBatchNode::updateAtlasIndex(Sprite* sprite, int* curIndex)
needNewIndex = false; needNewIndex = false;
} }
Object* pObj = NULL; Object* obj = NULL;
CCARRAY_FOREACH(array,pObj) CCARRAY_FOREACH(array,obj)
{ {
Sprite* child = static_cast<Sprite*>(pObj); Sprite* child = static_cast<Sprite*>(obj);
if (needNewIndex && child->getZOrder() >= 0) if (needNewIndex && child->getZOrder() >= 0)
{ {
oldIndex = sprite->getAtlasIndex(); oldIndex = sprite->getAtlasIndex();
@ -397,6 +374,8 @@ void SpriteBatchNode::updateAtlasIndex(Sprite* sprite, int* curIndex)
void SpriteBatchNode::swap(int oldIndex, int newIndex) void SpriteBatchNode::swap(int oldIndex, int newIndex)
{ {
CCASSERT(oldIndex>=0 && oldIndex < _descendants->count() && newIndex >=0 && newIndex < _descendants->count(), "Invalid index");
V3F_C4B_T2F_Quad* quads = _textureAtlas->getQuads(); V3F_C4B_T2F_Quad* quads = _textureAtlas->getQuads();
//update the index of other swapped item //update the index of other swapped item
@ -438,7 +417,7 @@ void SpriteBatchNode::increaseAtlasCapacity(void)
// if we're going beyond the current TextureAtlas's capacity, // if we're going beyond the current TextureAtlas's capacity,
// all the previously initialized sprites will need to redo their texture coords // all the previously initialized sprites will need to redo their texture coords
// this is likely computationally expensive // this is likely computationally expensive
unsigned int quantity = (_textureAtlas->getCapacity() + 1) * 4 / 3; int quantity = (_textureAtlas->getCapacity() + 1) * 4 / 3;
CCLOG("cocos2d: SpriteBatchNode: resizing TextureAtlas capacity from [%lu] to [%lu].", CCLOG("cocos2d: SpriteBatchNode: resizing TextureAtlas capacity from [%lu] to [%lu].",
(long)_textureAtlas->getCapacity(), (long)_textureAtlas->getCapacity(),
@ -452,105 +431,106 @@ void SpriteBatchNode::increaseAtlasCapacity(void)
} }
} }
unsigned int SpriteBatchNode::rebuildIndexInOrder(Sprite *pobParent, unsigned int uIndex) int SpriteBatchNode::rebuildIndexInOrder(Sprite *parent, int index)
{ {
Array *children = pobParent->getChildren(); CCASSERT(index>=0 && index < _children->count(), "Invalid index");
Array *children = parent->getChildren();
if (children && children->count() > 0) if (children && children->count() > 0)
{ {
Object* pObject = NULL; Object* object = NULL;
CCARRAY_FOREACH(children, pObject) CCARRAY_FOREACH(children, object)
{ {
Sprite* child = static_cast<Sprite*>(pObject); Sprite* child = static_cast<Sprite*>(object);
if (child && (child->getZOrder() < 0)) if (child && (child->getZOrder() < 0))
{ {
uIndex = rebuildIndexInOrder(child, uIndex); index = rebuildIndexInOrder(child, index);
} }
} }
} }
// ignore self (batch node) // ignore self (batch node)
if (! pobParent->isEqual(this)) if (! parent->isEqual(this))
{ {
pobParent->setAtlasIndex(uIndex); parent->setAtlasIndex(index);
uIndex++; index++;
} }
if (children && children->count() > 0) if (children && children->count() > 0)
{ {
Object* pObject = NULL; Object* object = NULL;
CCARRAY_FOREACH(children, pObject) CCARRAY_FOREACH(children, object)
{ {
Sprite* child = static_cast<Sprite*>(pObject); Sprite* child = static_cast<Sprite*>(object);
if (child && (child->getZOrder() >= 0)) if (child && (child->getZOrder() >= 0))
{ {
uIndex = rebuildIndexInOrder(child, uIndex); index = rebuildIndexInOrder(child, index);
} }
} }
} }
return uIndex; return index;
} }
unsigned int SpriteBatchNode::highestAtlasIndexInChild(Sprite *pSprite) int SpriteBatchNode::highestAtlasIndexInChild(Sprite *sprite)
{ {
Array *children = pSprite->getChildren(); Array *children = sprite->getChildren();
if (! children || children->count() == 0) if (! children || children->count() == 0)
{ {
return pSprite->getAtlasIndex(); return sprite->getAtlasIndex();
} }
else else
{ {
return highestAtlasIndexInChild((Sprite*)(children->getLastObject())); return highestAtlasIndexInChild( static_cast<Sprite*>(children->getLastObject()));
} }
} }
unsigned int SpriteBatchNode::lowestAtlasIndexInChild(Sprite *pSprite) int SpriteBatchNode::lowestAtlasIndexInChild(Sprite *sprite)
{ {
Array *children = pSprite->getChildren(); Array *children = sprite->getChildren();
if (! children || children->count() == 0) if (! children || children->count() == 0)
{ {
return pSprite->getAtlasIndex(); return sprite->getAtlasIndex();
} }
else else
{ {
return lowestAtlasIndexInChild((Sprite*)(children->getObjectAtIndex(0))); return lowestAtlasIndexInChild(static_cast<Sprite*>(children->getObjectAtIndex(0)));
} }
} }
unsigned int SpriteBatchNode::atlasIndexForChild(Sprite *sprite, int nZ) int SpriteBatchNode::atlasIndexForChild(Sprite *sprite, int nZ)
{ {
Array *pBrothers = sprite->getParent()->getChildren(); Array *siblings = sprite->getParent()->getChildren();
unsigned int uChildIndex = pBrothers->getIndexOfObject(sprite); int childIndex = siblings->getIndexOfObject(sprite);
// ignore parent Z if parent is spriteSheet // ignore parent Z if parent is spriteSheet
bool bIgnoreParent = (SpriteBatchNode*)(sprite->getParent()) == this; bool ignoreParent = (SpriteBatchNode*)(sprite->getParent()) == this;
Sprite *pPrevious = NULL; Sprite *prev = NULL;
if (uChildIndex > 0 && if (childIndex > 0 && childIndex != -1)
uChildIndex < UINT_MAX)
{ {
pPrevious = (Sprite*)(pBrothers->getObjectAtIndex(uChildIndex - 1)); prev = static_cast<Sprite*>(siblings->getObjectAtIndex(childIndex - 1));
} }
// first child of the sprite sheet // first child of the sprite sheet
if (bIgnoreParent) if (ignoreParent)
{ {
if (uChildIndex == 0) if (childIndex == 0)
{ {
return 0; return 0;
} }
return highestAtlasIndexInChild(pPrevious) + 1; return highestAtlasIndexInChild(prev) + 1;
} }
// parent is a Sprite, so, it must be taken into account // parent is a Sprite, so, it must be taken into account
// first child of an Sprite ? // first child of an Sprite ?
if (uChildIndex == 0) if (childIndex == 0)
{ {
Sprite *p = (Sprite*)(sprite->getParent()); Sprite *p = static_cast<Sprite*>(sprite->getParent());
// less than parent and brothers // less than parent and brothers
if (nZ < 0) if (nZ < 0)
@ -565,13 +545,13 @@ unsigned int SpriteBatchNode::atlasIndexForChild(Sprite *sprite, int nZ)
else else
{ {
// previous & sprite belong to the same branch // previous & sprite belong to the same branch
if ((pPrevious->getZOrder() < 0 && nZ < 0) || (pPrevious->getZOrder() >= 0 && nZ >= 0)) if ((prev->getZOrder() < 0 && nZ < 0) || (prev->getZOrder() >= 0 && nZ >= 0))
{ {
return highestAtlasIndexInChild(pPrevious) + 1; return highestAtlasIndexInChild(prev) + 1;
} }
// else (previous < 0 and sprite >= 0 ) // else (previous < 0 and sprite >= 0 )
Sprite *p = (Sprite*)(sprite->getParent()); Sprite *p = static_cast<Sprite*>(sprite->getParent());
return p->getAtlasIndex() + 1; return p->getAtlasIndex() + 1;
} }
@ -582,37 +562,37 @@ unsigned int SpriteBatchNode::atlasIndexForChild(Sprite *sprite, int nZ)
// add child helper // add child helper
void SpriteBatchNode::insertChild(Sprite *pSprite, unsigned int uIndex) void SpriteBatchNode::insertChild(Sprite *sprite, int index)
{ {
pSprite->setBatchNode(this); sprite->setBatchNode(this);
pSprite->setAtlasIndex(uIndex); sprite->setAtlasIndex(index);
pSprite->setDirty(true); sprite->setDirty(true);
if(_textureAtlas->getTotalQuads() == _textureAtlas->getCapacity()) if(_textureAtlas->getTotalQuads() == _textureAtlas->getCapacity())
{ {
increaseAtlasCapacity(); increaseAtlasCapacity();
} }
V3F_C4B_T2F_Quad quad = pSprite->getQuad(); V3F_C4B_T2F_Quad quad = sprite->getQuad();
_textureAtlas->insertQuad(&quad, uIndex); _textureAtlas->insertQuad(&quad, index);
_descendants->insertObject(pSprite, uIndex); _descendants->insertObject(sprite, index);
// update indices // update indices
unsigned int i = uIndex+1; int i = index+1;
Sprite* child = nullptr; Sprite* child = nullptr;
for(; i<_descendants->count(); i++){ for(; i < _descendants->count(); i++){
child = static_cast<Sprite*>(_descendants->getObjectAtIndex(i)); child = static_cast<Sprite*>(_descendants->getObjectAtIndex(i));
child->setAtlasIndex(child->getAtlasIndex() + 1); child->setAtlasIndex(child->getAtlasIndex() + 1);
} }
// add children recursively // add children recursively
Object* pObj = nullptr; Object* obj = nullptr;
CCARRAY_FOREACH(pSprite->getChildren(), pObj) CCARRAY_FOREACH(sprite->getChildren(), obj)
{ {
child = static_cast<Sprite*>(pObj); child = static_cast<Sprite*>(obj);
unsigned int idx = atlasIndexForChild(child, child->getZOrder()); int idx = atlasIndexForChild(child, child->getZOrder());
insertChild(child, idx); insertChild(child, idx);
} }
} }
@ -629,7 +609,7 @@ void SpriteBatchNode::appendChild(Sprite* sprite)
} }
_descendants->addObject(sprite); _descendants->addObject(sprite);
unsigned int index=_descendants->count()-1; int index=_descendants->count()-1;
sprite->setAtlasIndex(index); sprite->setAtlasIndex(index);
@ -638,10 +618,10 @@ void SpriteBatchNode::appendChild(Sprite* sprite)
// add children recursively // add children recursively
Object* pObj = nullptr; Object* obj = nullptr;
CCARRAY_FOREACH(sprite->getChildren(), pObj) CCARRAY_FOREACH(sprite->getChildren(), obj)
{ {
Sprite* child = static_cast<Sprite*>(pObj); Sprite* child = static_cast<Sprite*>(obj);
appendChild(child); appendChild(child);
} }
} }
@ -655,7 +635,7 @@ void SpriteBatchNode::removeSpriteFromAtlas(Sprite *sprite)
sprite->setBatchNode(NULL); sprite->setBatchNode(NULL);
int index = _descendants->getIndexOfObject(sprite); int index = _descendants->getIndexOfObject(sprite);
if (index != UINT_MAX) if (index != -1)
{ {
_descendants->removeObjectAtIndex(index); _descendants->removeObjectAtIndex(index);
@ -776,10 +756,10 @@ SpriteBatchNode * SpriteBatchNode::addSpriteWithoutQuad(Sprite*child, int z, int
// XXX: optimize with a binary search // XXX: optimize with a binary search
int i=0; int i=0;
Object* pObject = NULL; Object* object = NULL;
CCARRAY_FOREACH(_descendants, pObject) CCARRAY_FOREACH(_descendants, object)
{ {
Sprite* child = static_cast<Sprite*>(pObject); Sprite* child = static_cast<Sprite*>(object);
if (child && (child->getAtlasIndex() >= z)) if (child && (child->getAtlasIndex() >= z))
{ {
++i; ++i;

View File

@ -61,19 +61,19 @@ class Sprite;
*/ */
class CC_DLL SpriteBatchNode : public Node, public TextureProtocol class CC_DLL SpriteBatchNode : public Node, public TextureProtocol
{ {
static const int kDefaultSpriteBatchCapacity = 29; static const int DEFAULT_CAPACITY = 29;
public: public:
/** creates a SpriteBatchNode with a texture2d and capacity of children. /** creates a SpriteBatchNode with a texture2d and capacity of children.
The capacity will be increased in 33% in runtime if it run out of space. The capacity will be increased in 33% in runtime if it run out of space.
*/ */
static SpriteBatchNode* createWithTexture(Texture2D* tex, int capacity = kDefaultSpriteBatchCapacity); static SpriteBatchNode* createWithTexture(Texture2D* tex, int capacity = DEFAULT_CAPACITY);
/** creates a SpriteBatchNode with a file image (.png, .jpeg, .pvr, etc) and capacity of children. /** creates a SpriteBatchNode with a file image (.png, .jpeg, .pvr, etc) and capacity of children.
The capacity will be increased in 33% in runtime if it run out of space. The capacity will be increased in 33% in runtime if it run out of space.
The file will be loaded using the TextureMgr. The file will be loaded using the TextureMgr.
*/ */
static SpriteBatchNode* create(const char* fileImage, int capacity = kDefaultSpriteBatchCapacity); static SpriteBatchNode* create(const char* fileImage, int capacity = DEFAULT_CAPACITY);
SpriteBatchNode(); SpriteBatchNode();
virtual ~SpriteBatchNode(); virtual ~SpriteBatchNode();
@ -110,16 +110,16 @@ public:
/** removes a child given a certain index. It will also cleanup the running actions depending on the cleanup parameter. /** removes a child given a certain index. It will also cleanup the running actions depending on the cleanup parameter.
@warning Removing a child from a SpriteBatchNode is very slow @warning Removing a child from a SpriteBatchNode is very slow
*/ */
void removeChildAtIndex(unsigned int index, bool doCleanup); void removeChildAtIndex(int index, bool doCleanup);
void insertChild(Sprite *child, unsigned int index); void insertChild(Sprite *child, int index);
void appendChild(Sprite* sprite); void appendChild(Sprite* sprite);
void removeSpriteFromAtlas(Sprite *sprite); void removeSpriteFromAtlas(Sprite *sprite);
unsigned int rebuildIndexInOrder(Sprite *parent, unsigned int index); int rebuildIndexInOrder(Sprite *parent, int index);
unsigned int highestAtlasIndexInChild(Sprite *sprite); int highestAtlasIndexInChild(Sprite *sprite);
unsigned int lowestAtlasIndexInChild(Sprite *sprite); int lowestAtlasIndexInChild(Sprite *sprite);
unsigned int atlasIndexForChild(Sprite *sprite, int z); int atlasIndexForChild(Sprite *sprite, int z);
/* Sprites use this to start sortChildren, don't call this manually */ /* Sprites use this to start sortChildren, don't call this manually */
void reorderBatch(bool reorder); void reorderBatch(bool reorder);

View File

@ -72,9 +72,9 @@ void ccArrayEnsureExtraCapacity(ccArray *arr, int extra)
{ {
while (arr->max < arr->num + extra) while (arr->max < arr->num + extra)
{ {
// CCLOG("cocos2d: ccCArray: resizing ccArray capacity from [%lu] to [%lu].", CCLOG("cocos2d: ccCArray: resizing ccArray capacity from [%lu] to [%lu].",
// (long) arr->max, (long) arr->max,
// (long) arr->max*2); (long) arr->max*2);
ccArrayDoubleCapacity(arr); ccArrayDoubleCapacity(arr);
} }

View File

@ -38,8 +38,10 @@ static std::function<NodeChildrenMainScene*()> createFunctions[] =
CL(CallFuncsSpriteSheetForEach), CL(CallFuncsSpriteSheetForEach),
CL(CallFuncsSpriteSheetCMacro), CL(CallFuncsSpriteSheetCMacro),
CL(AddSprite),
CL(AddSpriteSheet), CL(AddSpriteSheet),
CL(GetSpriteSheet), CL(GetSpriteSheet),
CL(RemoveSprite),
CL(RemoveSpriteSheet), CL(RemoveSpriteSheet),
CL(ReorderSpriteSheet), CL(ReorderSpriteSheet),
CL(SortAllChildrenSpriteSheet), CL(SortAllChildrenSpriteSheet),
@ -151,6 +153,7 @@ void NodeChildrenMainScene::initWithQuantityOfNodes(unsigned int nNodes)
updateQuantityOfNodes(); updateQuantityOfNodes();
updateProfilerName(); updateProfilerName();
CC_PROFILER_PURGE_ALL(); CC_PROFILER_PURGE_ALL();
srandom(0);
}); });
decrease->setColor(Color3B(0,200,20)); decrease->setColor(Color3B(0,200,20));
auto increase = MenuItemFont::create(" + ", [&](Object *sender) { auto increase = MenuItemFont::create(" + ", [&](Object *sender) {
@ -162,6 +165,7 @@ void NodeChildrenMainScene::initWithQuantityOfNodes(unsigned int nNodes)
updateQuantityOfNodes(); updateQuantityOfNodes();
updateProfilerName(); updateProfilerName();
CC_PROFILER_PURGE_ALL(); CC_PROFILER_PURGE_ALL();
srandom(0);
}); });
increase->setColor(Color3B(0,200,20)); increase->setColor(Color3B(0,200,20));
@ -182,6 +186,7 @@ void NodeChildrenMainScene::initWithQuantityOfNodes(unsigned int nNodes)
updateQuantityLabel(); updateQuantityLabel();
updateQuantityOfNodes(); updateQuantityOfNodes();
updateProfilerName(); updateProfilerName();
srandom(0);
} }
std::string NodeChildrenMainScene::title() std::string NodeChildrenMainScene::title()
@ -296,7 +301,7 @@ void IterateSpriteSheetForLoop::update(float dt)
std::string IterateSpriteSheetForLoop::title() std::string IterateSpriteSheetForLoop::title()
{ {
return "A - Iterate SpriteSheet"; return "Iterate SpriteSheet";
} }
std::string IterateSpriteSheetForLoop::subtitle() std::string IterateSpriteSheetForLoop::subtitle()
@ -334,7 +339,7 @@ void IterateSpriteSheetCArray::update(float dt)
std::string IterateSpriteSheetCArray::title() std::string IterateSpriteSheetCArray::title()
{ {
return "B - Iterate SpriteSheet"; return "Iterate SpriteSheet";
} }
std::string IterateSpriteSheetCArray::subtitle() std::string IterateSpriteSheetCArray::subtitle()
@ -372,7 +377,7 @@ void IterateSpriteSheetIterator::update(float dt)
std::string IterateSpriteSheetIterator::title() std::string IterateSpriteSheetIterator::title()
{ {
return "C - Iterate SpriteSheet"; return "Iterate SpriteSheet";
} }
std::string IterateSpriteSheetIterator::subtitle() std::string IterateSpriteSheetIterator::subtitle()
@ -413,7 +418,7 @@ void CallFuncsSpriteSheetForEach::update(float dt)
std::string CallFuncsSpriteSheetForEach::title() std::string CallFuncsSpriteSheetForEach::title()
{ {
return "D - 'map' functional call"; return "'map' functional call";
} }
std::string CallFuncsSpriteSheetForEach::subtitle() std::string CallFuncsSpriteSheetForEach::subtitle()
@ -446,7 +451,7 @@ void CallFuncsSpriteSheetCMacro::update(float dt)
std::string CallFuncsSpriteSheetCMacro::title() std::string CallFuncsSpriteSheetCMacro::title()
{ {
return "E - 'map' functional call"; return "'map' functional call";
} }
std::string CallFuncsSpriteSheetCMacro::subtitle() std::string CallFuncsSpriteSheetCMacro::subtitle()
@ -511,6 +516,69 @@ const char* AddRemoveSpriteSheet::testName()
return "none"; return "none";
} }
////////////////////////////////////////////////////////
//
// AddSprite
//
////////////////////////////////////////////////////////
void AddSprite::update(float dt)
{
// reset seed
//srandom(0);
// 100 percent
int totalToAdd = currentQuantityOfNodes * 1;
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;
}
// add them with random Z (very important!)
CC_PROFILER_START( this->profilerName() );
for( int i=0; i < totalToAdd;i++ )
{
this->addChild( sprites[i], zs[i], kTagBase+i);
}
CC_PROFILER_STOP(this->profilerName());
batchNode->sortAllChildren();
// remove them
for( int i=0;i < totalToAdd;i++)
{
this->removeChild( sprites[i], true);
}
delete [] sprites;
delete [] zs;
}
}
std::string AddSprite::title()
{
return "Node::addChild()";
}
std::string AddSprite::subtitle()
{
return "Adds sprites with random z. See console";
}
const char* AddSprite::testName()
{
return "Node::addChild()";
}
//////////////////////////////////////////////////////// ////////////////////////////////////////////////////////
// //
// AddSpriteSheet // AddSpriteSheet
@ -521,8 +589,8 @@ void AddSpriteSheet::update(float dt)
// reset seed // reset seed
//srandom(0); //srandom(0);
// 15 percent // 100 percent
int totalToAdd = currentQuantityOfNodes * 0.15f; int totalToAdd = currentQuantityOfNodes * 1;
if( totalToAdd > 0 ) if( totalToAdd > 0 )
{ {
@ -543,11 +611,11 @@ void AddSpriteSheet::update(float dt)
{ {
batchNode->addChild( sprites[i], zs[i], kTagBase+i); batchNode->addChild( sprites[i], zs[i], kTagBase+i);
} }
CC_PROFILER_STOP(this->profilerName());
batchNode->sortAllChildren(); batchNode->sortAllChildren();
CC_PROFILER_STOP(this->profilerName());
// remove them // remove them
for( int i=0;i < totalToAdd;i++) for( int i=0;i < totalToAdd;i++)
{ {
@ -561,17 +629,17 @@ void AddSpriteSheet::update(float dt)
std::string AddSpriteSheet::title() std::string AddSpriteSheet::title()
{ {
return "F - Add to spritesheet"; return "SpriteBatchNode::addChild()";
} }
std::string AddSpriteSheet::subtitle() std::string AddSpriteSheet::subtitle()
{ {
return "Adds %10 of total sprites with random z. See console"; return "Adds sprites with random z. See console";
} }
const char* AddSpriteSheet::testName() const char* AddSpriteSheet::testName()
{ {
return "add sprites"; return "SpriteBatchNode::addChild()";
} }
//////////////////////////////////////////////////////// ////////////////////////////////////////////////////////
@ -584,8 +652,8 @@ void GetSpriteSheet::update(float dt)
// reset seed // reset seed
//srandom(0); //srandom(0);
// 15 percent // 100% percent
int totalToAdd = currentQuantityOfNodes * 0.15f; int totalToAdd = currentQuantityOfNodes * 1;
if( totalToAdd > 0 ) if( totalToAdd > 0 )
{ {
@ -626,7 +694,7 @@ void GetSpriteSheet::update(float dt)
std::string GetSpriteSheet::title() std::string GetSpriteSheet::title()
{ {
return "G - getChildByTag from spritesheet"; return "getChildByTag from spritesheet";
} }
std::string GetSpriteSheet::subtitle() std::string GetSpriteSheet::subtitle()
@ -636,10 +704,65 @@ std::string GetSpriteSheet::subtitle()
const char* GetSpriteSheet::testName() const char* GetSpriteSheet::testName()
{ {
return "get sprites"; return "SpriteBatchNode::getChildByTag()";
} }
////////////////////////////////////////////////////////
//
// RemoveSprite
//
////////////////////////////////////////////////////////
void RemoveSprite::update(float dt)
{
//srandom(0);
// 100 percent
int totalToAdd = currentQuantityOfNodes * 1;
if( totalToAdd > 0 )
{
Sprite **sprites = new Sprite*[totalToAdd];
// Don't include the sprite creation time as part of the profiling
for(int i=0;i<totalToAdd;i++)
{
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++ )
{
this->addChild( sprites[i], CCRANDOM_MINUS1_1() * 50, kTagBase+i);
}
// remove them
CC_PROFILER_START( this->profilerName() );
for( int i=0;i < totalToAdd;i++)
{
this->removeChild( sprites[i], true);
}
CC_PROFILER_STOP( this->profilerName() );
delete [] sprites;
}
}
std::string RemoveSprite::title()
{
return "Node::removeChild()";
}
std::string RemoveSprite::subtitle()
{
return "Remove sprites. See console";
}
const char* RemoveSprite::testName()
{
return "Node::removeChild()";
}
//////////////////////////////////////////////////////// ////////////////////////////////////////////////////////
// //
// RemoveSpriteSheet // RemoveSpriteSheet
@ -649,8 +772,8 @@ void RemoveSpriteSheet::update(float dt)
{ {
//srandom(0); //srandom(0);
// 15 percent // 100 percent
int totalToAdd = currentQuantityOfNodes * 0.15f; int totalToAdd = currentQuantityOfNodes * 1;
if( totalToAdd > 0 ) if( totalToAdd > 0 )
{ {
@ -682,17 +805,17 @@ void RemoveSpriteSheet::update(float dt)
std::string RemoveSpriteSheet::title() std::string RemoveSpriteSheet::title()
{ {
return "H - Del from spritesheet"; return "SpriteBatchNode::removeChild()";
} }
std::string RemoveSpriteSheet::subtitle() std::string RemoveSpriteSheet::subtitle()
{ {
return "Remove %10 of total sprites placed randomly. See console"; return "Remove sprites. See console";
} }
const char* RemoveSpriteSheet::testName() const char* RemoveSpriteSheet::testName()
{ {
return "remove sprites"; return "SpriteBatchNode::removeChild()";
} }
//////////////////////////////////////////////////////// ////////////////////////////////////////////////////////
@ -704,8 +827,8 @@ void ReorderSpriteSheet::update(float dt)
{ {
//srandom(0); //srandom(0);
// 15 percent // 100 percent
int totalToAdd = currentQuantityOfNodes * 0.15f; int totalToAdd = currentQuantityOfNodes * 1;
if( totalToAdd > 0 ) if( totalToAdd > 0 )
{ {
@ -745,17 +868,17 @@ void ReorderSpriteSheet::update(float dt)
std::string ReorderSpriteSheet::title() std::string ReorderSpriteSheet::title()
{ {
return "I - Reorder from spritesheet"; return "SpriteBatchNode::reorderChild()";
} }
std::string ReorderSpriteSheet::subtitle() std::string ReorderSpriteSheet::subtitle()
{ {
return "Reorder %10 of total sprites placed randomly. See console"; return "Reorder sprites. See console";
} }
const char* ReorderSpriteSheet::testName() const char* ReorderSpriteSheet::testName()
{ {
return "reorder sprites"; return "SpriteBatchNode::reorderChild()";
} }
//////////////////////////////////////////////////////// ////////////////////////////////////////////////////////
@ -767,8 +890,8 @@ void SortAllChildrenSpriteSheet::update(float dt)
{ {
//srandom(0); //srandom(0);
// 15 percent // 100 percent
int totalToAdd = currentQuantityOfNodes * 0.15f; int totalToAdd = currentQuantityOfNodes * 1;
if( totalToAdd > 0 ) if( totalToAdd > 0 )
{ {
@ -810,7 +933,7 @@ void SortAllChildrenSpriteSheet::update(float dt)
std::string SortAllChildrenSpriteSheet::title() std::string SortAllChildrenSpriteSheet::title()
{ {
return "J - Sort All Children from spritesheet"; return "SpriteBatchNode::sortAllChildren()";
} }
std::string SortAllChildrenSpriteSheet::subtitle() std::string SortAllChildrenSpriteSheet::subtitle()
@ -820,7 +943,7 @@ std::string SortAllChildrenSpriteSheet::subtitle()
const char* SortAllChildrenSpriteSheet::testName() const char* SortAllChildrenSpriteSheet::testName()
{ {
return "sort all children"; return "SpriteBatchNode::sortAllChildren()";
} }
@ -872,7 +995,7 @@ void VisitSceneGraph::update(float dt)
std::string VisitSceneGraph::title() std::string VisitSceneGraph::title()
{ {
return "K - Performance of visiting the scene graph"; return "Performance of visiting the scene graph";
} }
std::string VisitSceneGraph::subtitle() std::string VisitSceneGraph::subtitle()
@ -882,7 +1005,7 @@ std::string VisitSceneGraph::subtitle()
const char* VisitSceneGraph::testName() const char* VisitSceneGraph::testName()
{ {
return "visit scene graph"; return "visit()";
} }
///---------------------------------------- ///----------------------------------------

View File

@ -125,6 +125,16 @@ public:
/// ///
class AddSprite : public AddRemoveSpriteSheet
{
public:
virtual void update(float dt);
virtual std::string title();
virtual std::string subtitle();
virtual const char* testName();
};
class AddSpriteSheet : public AddRemoveSpriteSheet class AddSpriteSheet : public AddRemoveSpriteSheet
{ {
public: public:
@ -145,6 +155,16 @@ public:
virtual const char* testName(); virtual const char* testName();
}; };
class RemoveSprite : public AddRemoveSpriteSheet
{
public:
virtual void update(float dt);
virtual std::string title();
virtual std::string subtitle();
virtual const char* testName();
};
class RemoveSpriteSheet : public AddRemoveSpriteSheet class RemoveSpriteSheet : public AddRemoveSpriteSheet
{ {
public: public:

@ -1 +1 @@
Subproject commit c5fc9f2b3d9ae1e092b611e8969e8c2098d40711 Subproject commit 567e5d2612fc564464ccde9ba3da7cfdbc44880f