issue #2790: Node::_children is Vector<Node*> now.

This commit is contained in:
James Chen 2013-11-28 16:02:03 +08:00
parent c152652c5b
commit 90062b656d
26 changed files with 585 additions and 709 deletions

View File

@ -2003,31 +2003,28 @@ Animate::~Animate()
CC_SAFE_DELETE(_splitTimes); CC_SAFE_DELETE(_splitTimes);
} }
bool Animate::initWithAnimation(Animation *pAnimation) bool Animate::initWithAnimation(Animation* animation)
{ {
CCASSERT( pAnimation!=NULL, "Animate: argument Animation must be non-NULL"); CCASSERT( animation!=NULL, "Animate: argument Animation must be non-NULL");
float singleDuration = pAnimation->getDuration(); float singleDuration = animation->getDuration();
if ( ActionInterval::initWithDuration(singleDuration * pAnimation->getLoops() ) ) if ( ActionInterval::initWithDuration(singleDuration * animation->getLoops() ) )
{ {
_nextFrame = 0; _nextFrame = 0;
setAnimation(pAnimation); setAnimation(animation);
_origFrame = NULL; _origFrame = NULL;
_executedLoops = 0; _executedLoops = 0;
_splitTimes->reserve(pAnimation->getFrames()->count()); _splitTimes->reserve(animation->getFrames().count());
float accumUnitsOfTime = 0; float accumUnitsOfTime = 0;
float newUnitOfTimeValue = singleDuration / pAnimation->getTotalDelayUnits(); float newUnitOfTimeValue = singleDuration / animation->getTotalDelayUnits();
Array* pFrames = pAnimation->getFrames(); auto frames = animation->getFrames();
CCARRAY_VERIFY_TYPE(pFrames, AnimationFrame*);
Object* pObj = NULL; for (auto& frame : frames)
CCARRAY_FOREACH(pFrames, pObj)
{ {
AnimationFrame* frame = static_cast<AnimationFrame*>(pObj);
float value = (accumUnitsOfTime * newUnitOfTimeValue) / singleDuration; float value = (accumUnitsOfTime * newUnitOfTimeValue) / singleDuration;
accumUnitsOfTime += frame->getDelayUnits(); accumUnitsOfTime += frame->getDelayUnits();
_splitTimes->push_back(value); _splitTimes->push_back(value);
@ -2099,15 +2096,15 @@ void Animate::update(float t)
t = fmodf(t, 1.0f); t = fmodf(t, 1.0f);
} }
Array* frames = _animation->getFrames(); auto frames = _animation->getFrames();
long numberOfFrames = frames->count(); long numberOfFrames = frames.count();
SpriteFrame *frameToDisplay = NULL; SpriteFrame *frameToDisplay = NULL;
for( int i=_nextFrame; i < numberOfFrames; i++ ) { for( int i=_nextFrame; i < numberOfFrames; i++ ) {
float splitTime = _splitTimes->at(i); float splitTime = _splitTimes->at(i);
if( splitTime <= t ) { if( splitTime <= t ) {
AnimationFrame* frame = static_cast<AnimationFrame*>(frames->getObjectAtIndex(i)); AnimationFrame* frame = frames[i];
frameToDisplay = frame->getSpriteFrame(); frameToDisplay = frame->getSpriteFrame();
static_cast<Sprite*>(_target)->setDisplayFrame(frameToDisplay); static_cast<Sprite*>(_target)->setDisplayFrame(frameToDisplay);
@ -2127,27 +2124,24 @@ void Animate::update(float t)
Animate* Animate::reverse() const Animate* Animate::reverse() const
{ {
Array* pOldArray = _animation->getFrames(); auto oldArray = _animation->getFrames();
Array* pNewArray = Array::createWithCapacity(pOldArray->count()); Vector<AnimationFrame*> newArray(oldArray.count());
CCARRAY_VERIFY_TYPE(pOldArray, AnimationFrame*); if (oldArray.count() > 0)
if (pOldArray->count() > 0)
{ {
Object* pObj = NULL; for (auto iter = oldArray.rcbegin(); iter != oldArray.rcend(); ++iter)
CCARRAY_FOREACH_REVERSE(pOldArray, pObj)
{ {
AnimationFrame* pElement = static_cast<AnimationFrame*>(pObj); AnimationFrame* animFrame = *iter;
if (! pElement) if (!animFrame)
{ {
break; break;
} }
pNewArray->addObject(pElement->clone()); newArray.addObject(animFrame->clone());
} }
} }
Animation *newAnim = Animation::create(pNewArray, _animation->getDelayPerUnit(), _animation->getLoops()); Animation *newAnim = Animation::create(newArray, _animation->getDelayPerUnit(), _animation->getLoops());
newAnim->setRestoreOriginalFrame(_animation->getRestoreOriginalFrame()); newAnim->setRestoreOriginalFrame(_animation->getRestoreOriginalFrame());
return Animate::create(newAnim); return Animate::create(newAnim);
} }

View File

@ -32,6 +32,20 @@ THE SOFTWARE.
NS_CC_BEGIN NS_CC_BEGIN
AnimationFrame* AnimationFrame::create(SpriteFrame* spriteFrame, float delayUnits, Dictionary* userInfo)
{
auto ret = new AnimationFrame();
if (ret && ret->initWithSpriteFrame(spriteFrame, delayUnits, userInfo))
{
ret->autorelease();
}
else
{
CC_SAFE_DELETE(ret);
}
return ret;
}
AnimationFrame::AnimationFrame() AnimationFrame::AnimationFrame()
: _spriteFrame(NULL) : _spriteFrame(NULL)
, _delayUnits(0.0f) , _delayUnits(0.0f)
@ -80,7 +94,7 @@ Animation* Animation::create(void)
return pAnimation; return pAnimation;
} }
Animation* Animation::createWithSpriteFrames(Array *frames, float delay/* = 0.0f*/) Animation* Animation::createWithSpriteFrames(const Vector<SpriteFrame*>& frames, float delay/* = 0.0f*/)
{ {
Animation *pAnimation = new Animation(); Animation *pAnimation = new Animation();
pAnimation->initWithSpriteFrames(frames, delay); pAnimation->initWithSpriteFrames(frames, delay);
@ -89,7 +103,7 @@ Animation* Animation::createWithSpriteFrames(Array *frames, float delay/* = 0.0f
return pAnimation; return pAnimation;
} }
Animation* Animation::create(Array* arrayOfAnimationFrameNames, float delayPerUnit, unsigned int loops /* = 1 */) Animation* Animation::create(const Vector<AnimationFrame*>& arrayOfAnimationFrameNames, float delayPerUnit, unsigned int loops /* = 1 */)
{ {
Animation *pAnimation = new Animation(); Animation *pAnimation = new Animation();
pAnimation->initWithAnimationFrames(arrayOfAnimationFrameNames, delayPerUnit, loops); pAnimation->initWithAnimationFrames(arrayOfAnimationFrameNames, delayPerUnit, loops);
@ -99,49 +113,36 @@ Animation* Animation::create(Array* arrayOfAnimationFrameNames, float delayPerUn
bool Animation::init() bool Animation::init()
{ {
return initWithSpriteFrames(NULL, 0.0f); _loops = 1;
_delayPerUnit = 0.0f;
return true;
} }
bool Animation::initWithSpriteFrames(Array *pFrames, float delay/* = 0.0f*/) bool Animation::initWithSpriteFrames(const Vector<SpriteFrame*>& frames, float delay/* = 0.0f*/)
{ {
CCARRAY_VERIFY_TYPE(pFrames, SpriteFrame*);
_loops = 1; _loops = 1;
_delayPerUnit = delay; _delayPerUnit = delay;
Array* pTmpFrames = Array::create();
setFrames(pTmpFrames);
if (pFrames != NULL) for (auto& spriteFrame : frames)
{ {
Object* pObj = NULL; auto animFrame = AnimationFrame::create(spriteFrame, 1, nullptr);
CCARRAY_FOREACH(pFrames, pObj) _frames.addObject(animFrame);
{ _totalDelayUnits++;
SpriteFrame* frame = static_cast<SpriteFrame*>(pObj);
AnimationFrame *animFrame = new AnimationFrame();
animFrame->initWithSpriteFrame(frame, 1, NULL);
_frames->addObject(animFrame);
animFrame->release();
_totalDelayUnits++;
}
} }
return true; return true;
} }
bool Animation::initWithAnimationFrames(Array* arrayOfAnimationFrames, float delayPerUnit, unsigned int loops) bool Animation::initWithAnimationFrames(const Vector<AnimationFrame*>& arrayOfAnimationFrames, float delayPerUnit, unsigned int loops)
{ {
CCARRAY_VERIFY_TYPE(arrayOfAnimationFrames, AnimationFrame*);
_delayPerUnit = delayPerUnit; _delayPerUnit = delayPerUnit;
_loops = loops; _loops = loops;
setFrames(Array::createWithArray(arrayOfAnimationFrames)); setFrames(arrayOfAnimationFrames);
Object* pObj = NULL; for (auto& animFrame : _frames)
CCARRAY_FOREACH(_frames, pObj)
{ {
AnimationFrame* animFrame = static_cast<AnimationFrame*>(pObj);
_totalDelayUnits += animFrame->getDelayUnits(); _totalDelayUnits += animFrame->getDelayUnits();
} }
return true; return true;
@ -151,7 +152,6 @@ Animation::Animation()
: _totalDelayUnits(0.0f) : _totalDelayUnits(0.0f)
, _delayPerUnit(0.0f) , _delayPerUnit(0.0f)
, _duration(0.0f) , _duration(0.0f)
, _frames(NULL)
, _restoreOriginalFrame(false) , _restoreOriginalFrame(false)
, _loops(0) , _loops(0)
{ {
@ -161,15 +161,12 @@ Animation::Animation()
Animation::~Animation(void) Animation::~Animation(void)
{ {
CCLOGINFO("deallocing Animation: %p", this); CCLOGINFO("deallocing Animation: %p", this);
CC_SAFE_RELEASE(_frames);
} }
void Animation::addSpriteFrame(SpriteFrame *pFrame) void Animation::addSpriteFrame(SpriteFrame* spriteFrame)
{ {
AnimationFrame *animFrame = new AnimationFrame(); AnimationFrame *animFrame = AnimationFrame::create(spriteFrame, 1.0f, nullptr);
animFrame->initWithSpriteFrame(pFrame, 1.0f, NULL); _frames.addObject(animFrame);
_frames->addObject(animFrame);
animFrame->release();
// update duration // update duration
_totalDelayUnits++; _totalDelayUnits++;

View File

@ -32,6 +32,8 @@ THE SOFTWARE.
#include "CCDictionary.h" #include "CCDictionary.h"
#include "CCGeometry.h" #include "CCGeometry.h"
#include "CCSpriteFrame.h" #include "CCSpriteFrame.h"
#include "CCVector.h"
#include <string> #include <string>
NS_CC_BEGIN NS_CC_BEGIN
@ -56,17 +58,10 @@ class CC_DLL AnimationFrame : public Object, public Clonable
{ {
public: public:
/** /**
* @js ctor * Creates the animation frame with a spriteframe, number of delay units and a notification user info
* @since 3.0
*/ */
AnimationFrame(); static AnimationFrame* create(SpriteFrame* spriteFrame, float delayUnits, Dictionary* userInfo);
/**
* @js NA
* @lua NA
*/
virtual ~AnimationFrame();
/** initializes the animation frame with a spriteframe, number of delay units and a notification user info */
bool initWithSpriteFrame(SpriteFrame* spriteFrame, float delayUnits, Dictionary* userInfo);
SpriteFrame* getSpriteFrame() const { return _spriteFrame; }; SpriteFrame* getSpriteFrame() const { return _spriteFrame; };
@ -100,6 +95,20 @@ public:
virtual AnimationFrame *clone() const override; virtual AnimationFrame *clone() const override;
protected: protected:
/**
* @js ctor
*/
AnimationFrame();
/**
* @js NA
* @lua NA
*/
virtual ~AnimationFrame();
/** initializes the animation frame with a spriteframe, number of delay units and a notification user info */
bool initWithSpriteFrame(SpriteFrame* spriteFrame, float delayUnits, Dictionary* userInfo);
/** SpriteFrameName to be used */ /** SpriteFrameName to be used */
SpriteFrame* _spriteFrame; SpriteFrame* _spriteFrame;
@ -108,6 +117,9 @@ protected:
/** A AnimationFrameDisplayedNotification notification will be broadcast when the frame is displayed with this dictionary as UserInfo. If UserInfo is nil, then no notification will be broadcast. */ /** A AnimationFrameDisplayedNotification notification will be broadcast when the frame is displayed with this dictionary as UserInfo. If UserInfo is nil, then no notification will be broadcast. */
Dictionary* _userInfo; Dictionary* _userInfo;
private:
CC_DISALLOW_COPY_AND_ASSIGN(AnimationFrame);
}; };
@ -135,34 +147,13 @@ public:
The frames will be added with one "delay unit". The frames will be added with one "delay unit".
@since v0.99.5 @since v0.99.5
*/ */
static Animation* createWithSpriteFrames(Array* arrayOfSpriteFrameNames, float delay = 0.0f); static Animation* createWithSpriteFrames(const Vector<SpriteFrame*>& arrayOfSpriteFrameNames, float delay = 0.0f);
/* Creates an animation with an array of AnimationFrame, the delay per units in seconds and and how many times it should be executed. /* Creates an animation with an array of AnimationFrame, the delay per units in seconds and and how many times it should be executed.
@since v2.0 @since v2.0
* @js NA * @js NA
*/ */
static Animation* create(Array *arrayOfAnimationFrameNames, float delayPerUnit, unsigned int loops = 1); static Animation* create(const Vector<AnimationFrame*>& arrayOfAnimationFrameNames, float delayPerUnit, unsigned int loops = 1);
/**
* @js ctor
*/
Animation();
/**
* @js NA
* @lua NA
*/
virtual ~Animation(void);
bool init();
/** Initializes a Animation with frames and a delay between frames
@since v0.99.5
*/
bool initWithSpriteFrames(Array *pFrames, float delay = 0.0f);
/** Initializes a Animation with AnimationFrame
@since v2.0
*/
bool initWithAnimationFrames(Array* arrayOfAnimationFrames, float delayPerUnit, unsigned int loops);
/** Adds a SpriteFrame to a Animation. /** Adds a SpriteFrame to a Animation.
The frame will be added with one "delay unit". The frame will be added with one "delay unit".
@ -199,13 +190,11 @@ public:
float getDuration() const; float getDuration() const;
/** Gets the array of AnimationFrames */ /** Gets the array of AnimationFrames */
Array* getFrames() const { return _frames; }; const Vector<AnimationFrame*>& getFrames() const { return _frames; };
/** Sets the array of AnimationFrames */ /** Sets the array of AnimationFrames */
void setFrames(Array* frames) void setFrames(const Vector<AnimationFrame*>& frames)
{ {
CC_SAFE_RETAIN(frames);
CC_SAFE_RELEASE(_frames);
_frames = frames; _frames = frames;
} }
@ -225,6 +214,30 @@ public:
virtual Animation *clone() const override; virtual Animation *clone() const override;
protected: protected:
/**
* @js ctor
*/
Animation();
/**
* @js NA
* @lua NA
*/
virtual ~Animation(void);
/** Initializes a Animation */
bool init();
/** Initializes a Animation with frames and a delay between frames
@since v0.99.5
*/
bool initWithSpriteFrames(const Vector<SpriteFrame*>& arrayOfSpriteFrameNames, float delay = 0.0f);
/** Initializes a Animation with AnimationFrame
@since v2.0
*/
bool initWithAnimationFrames(const Vector<AnimationFrame*>& arrayOfAnimationFrameNames, float delayPerUnit, unsigned int loops);
/** total Delay units of the Animation. */ /** total Delay units of the Animation. */
float _totalDelayUnits; float _totalDelayUnits;
@ -235,13 +248,16 @@ protected:
float _duration; float _duration;
/** array of AnimationFrames */ /** array of AnimationFrames */
Array* _frames; Vector<AnimationFrame*> _frames;
/** whether or not it shall restore the original frame when the animation finishes */ /** whether or not it shall restore the original frame when the animation finishes */
bool _restoreOriginalFrame; bool _restoreOriginalFrame;
/** how many times the animation is going to loop. 0 means animation is not animated. 1, animation is executed one time, ... */ /** how many times the animation is going to loop. 0 means animation is not animated. 1, animation is executed one time, ... */
unsigned int _loops; unsigned int _loops;
private:
CC_DISALLOW_COPY_AND_ASSIGN(Animation);
}; };
// end of sprite_nodes group // end of sprite_nodes group

View File

@ -107,8 +107,7 @@ void AnimationCache::parseVersion1(Dictionary* animations)
continue; continue;
} }
Array* frames = Array::createWithCapacity(frameNames->count()); Vector<AnimationFrame*> frames(frameNames->count());
frames->retain();
Object* pObj = NULL; Object* pObj = NULL;
CCARRAY_FOREACH(frameNames, pObj) CCARRAY_FOREACH(frameNames, pObj)
@ -122,24 +121,21 @@ void AnimationCache::parseVersion1(Dictionary* animations)
continue; continue;
} }
AnimationFrame* animFrame = new AnimationFrame(); AnimationFrame* animFrame = AnimationFrame::create(spriteFrame, 1, nullptr);
animFrame->initWithSpriteFrame(spriteFrame, 1, NULL); frames.addObject(animFrame);
frames->addObject(animFrame);
animFrame->release();
} }
if ( frames->count() == 0 ) { if ( frames.count() == 0 ) {
CCLOG("cocos2d: AnimationCache: None of the frames for animation '%s' were found in the SpriteFrameCache. Animation is not being added to the Animation Cache.", element->getStrKey()); CCLOG("cocos2d: AnimationCache: None of the frames for animation '%s' were found in the SpriteFrameCache. Animation is not being added to the Animation Cache.", element->getStrKey());
continue; continue;
} else if ( frames->count() != frameNames->count() ) { } else if ( frames.count() != frameNames->count() ) {
CCLOG("cocos2d: AnimationCache: An animation in your dictionary refers to a frame which is not in the SpriteFrameCache. Some or all of the frames for the animation '%s' may be missing.", element->getStrKey()); CCLOG("cocos2d: AnimationCache: An animation in your dictionary refers to a frame which is not in the SpriteFrameCache. Some or all of the frames for the animation '%s' may be missing.", element->getStrKey());
} }
animation = Animation::create(frames, delay, 1); animation = Animation::create(frames, delay, 1);
AnimationCache::getInstance()->addAnimation(animation, element->getStrKey()); AnimationCache::getInstance()->addAnimation(animation, element->getStrKey());
frames->release(); }
}
} }
void AnimationCache::parseVersion2(Dictionary* animations) void AnimationCache::parseVersion2(Dictionary* animations)
@ -163,8 +159,7 @@ void AnimationCache::parseVersion2(Dictionary* animations)
} }
// Array of AnimationFrames // Array of AnimationFrames
Array* array = Array::createWithCapacity(frameArray->count()); Vector<AnimationFrame*> array(frameArray->count());
array->retain();
Object* pObj = NULL; Object* pObj = NULL;
CCARRAY_FOREACH(frameArray, pObj) CCARRAY_FOREACH(frameArray, pObj)
@ -183,22 +178,17 @@ void AnimationCache::parseVersion2(Dictionary* animations)
float delayUnits = entry->valueForKey("delayUnits")->floatValue(); float delayUnits = entry->valueForKey("delayUnits")->floatValue();
Dictionary* userInfo = (Dictionary*)entry->objectForKey("notification"); Dictionary* userInfo = (Dictionary*)entry->objectForKey("notification");
AnimationFrame *animFrame = new AnimationFrame(); AnimationFrame *animFrame = AnimationFrame::create(spriteFrame, delayUnits, userInfo);
animFrame->initWithSpriteFrame(spriteFrame, delayUnits, userInfo);
array->addObject(animFrame); array.addObject(animFrame);
animFrame->release();
} }
float delayPerUnit = animationDict->valueForKey("delayPerUnit")->floatValue(); float delayPerUnit = animationDict->valueForKey("delayPerUnit")->floatValue();
Animation *animation = new Animation(); Animation *animation = Animation::create(array, delayPerUnit, 0 != loops->length() ? loops->intValue() : 1);
animation->initWithAnimationFrames(array, delayPerUnit, 0 != loops->length() ? loops->intValue() : 1);
array->release();
animation->setRestoreOriginalFrame(restoreOriginalFrame); animation->setRestoreOriginalFrame(restoreOriginalFrame);
AnimationCache::getInstance()->addAnimation(animation, name); AnimationCache::getInstance()->addAnimation(animation, name);
animation->release();
} }
} }

View File

@ -39,13 +39,10 @@ static GLint g_sStencilBits = -1;
static void setProgram(Node *n, GLProgram *p) static void setProgram(Node *n, GLProgram *p)
{ {
n->setShaderProgram(p); n->setShaderProgram(p);
if (!n->getChildren()) return;
Object* pObj = NULL; n->getChildren().makeObjectsPerformCallback([p](Node* child){
CCARRAY_FOREACH(n->getChildren(), pObj) setProgram(child, p);
{ });
setProgram(static_cast<Node*>(pObj), p);
}
} }
ClippingNode::ClippingNode() ClippingNode::ClippingNode()

View File

@ -189,18 +189,17 @@ EventDispatcher::~EventDispatcher()
void EventDispatcher::visitTarget(Node* node) void EventDispatcher::visitTarget(Node* node)
{ {
int i = 0; long i = 0;
Array* children = node->getChildren(); auto children = node->getChildren();
int childrenCount = children ? children->count() : 0; long childrenCount = children.count();
if(childrenCount > 0) if(childrenCount > 0)
{ {
Node* child = nullptr; Node* child = nullptr;
// visit children zOrder < 0 // visit children zOrder < 0
for( ; i < childrenCount; i++ ) for( ; i < childrenCount; i++ )
{ {
child = static_cast<Node*>( children->getObjectAtIndex(i) ); child = children[i];
if ( child && child->getZOrder() < 0 ) if ( child && child->getZOrder() < 0 )
visitTarget(child); visitTarget(child);
@ -212,7 +211,7 @@ void EventDispatcher::visitTarget(Node* node)
for( ; i < childrenCount; i++ ) for( ; i < childrenCount; i++ )
{ {
child = static_cast<Node*>( children->getObjectAtIndex(i) ); child = children[i];
if (child) if (child)
visitTarget(child); visitTarget(child);
} }

View File

@ -248,20 +248,17 @@ void Label::alignText()
LabelTextFormatter::alignText(this); LabelTextFormatter::alignText(this);
int strLen = cc_wcslen(_currentUTF16String); int strLen = cc_wcslen(_currentUTF16String);
if (_children && _children->count() != 0)
{ _children.makeObjectsPerformCallback([this, &strLen](Node* child){
for (auto child: *_children) if (child)
{ {
Node* pNode = static_cast<Node*>( child ); int tag = child->getTag();
if (pNode) if(tag < 0 || tag >= strLen)
{ SpriteBatchNode::removeChild(child, true);
int tag = pNode->getTag();
if(tag < 0 || tag >= strLen)
SpriteBatchNode::removeChild(pNode, true);
}
} }
} });
_reusedLetter->setBatchNode(nullptr); _reusedLetter->setBatchNode(nullptr);
int vaildIndex = 0; int vaildIndex = 0;
@ -594,21 +591,18 @@ bool Label::isOpacityModifyRGB() const
void Label::setOpacityModifyRGB(bool isOpacityModifyRGB) void Label::setOpacityModifyRGB(bool isOpacityModifyRGB)
{ {
_isOpacityModifyRGB = isOpacityModifyRGB; _isOpacityModifyRGB = isOpacityModifyRGB;
if (_children && _children->count() != 0)
{ _children.makeObjectsPerformCallback([this](Node* child){
for (auto child: *_children) if (child)
{ {
Node* pNode = static_cast<Node*>( child ); RGBAProtocol *pRGBAProtocol = dynamic_cast<RGBAProtocol*>(child);
if (pNode) if (pRGBAProtocol)
{ {
RGBAProtocol *pRGBAProtocol = dynamic_cast<RGBAProtocol*>(pNode); pRGBAProtocol->setOpacityModifyRGB(_isOpacityModifyRGB);
if (pRGBAProtocol)
{
pRGBAProtocol->setOpacityModifyRGB(_isOpacityModifyRGB);
}
} }
} }
} });
_reusedLetter->setOpacityModifyRGB(true); _reusedLetter->setOpacityModifyRGB(true);
} }
@ -640,13 +634,13 @@ void Label::updateDisplayedOpacity(GLubyte parentOpacity)
{ {
_displayedOpacity = _realOpacity * parentOpacity/255.0; _displayedOpacity = _realOpacity * parentOpacity/255.0;
for (auto child: *_children) _children.makeObjectsPerformCallback([this](Node* child){
{
Sprite *item = static_cast<Sprite*>( child ); Sprite *item = static_cast<Sprite*>( child );
item->updateDisplayedOpacity(_displayedOpacity); item->updateDisplayedOpacity(_displayedOpacity);
} });
V3F_C4B_T2F_Quad *quads = _textureAtlas->getQuads(); V3F_C4B_T2F_Quad *quads = _textureAtlas->getQuads();
int count = _textureAtlas->getTotalQuads(); long count = _textureAtlas->getTotalQuads();
Color4B color4( _displayedColor.r, _displayedColor.g, _displayedColor.b, _displayedOpacity ); Color4B color4( _displayedColor.r, _displayedColor.g, _displayedColor.b, _displayedOpacity );
if (_isOpacityModifyRGB) if (_isOpacityModifyRGB)
{ {
@ -706,14 +700,13 @@ void Label::updateDisplayedColor(const Color3B& parentColor)
_displayedColor.g = _realColor.g * parentColor.g/255.0; _displayedColor.g = _realColor.g * parentColor.g/255.0;
_displayedColor.b = _realColor.b * parentColor.b/255.0; _displayedColor.b = _realColor.b * parentColor.b/255.0;
for (auto child: *_children) _children.makeObjectsPerformCallback([this](Node* child){
{
Sprite *item = static_cast<Sprite*>( child ); Sprite *item = static_cast<Sprite*>( child );
item->updateDisplayedColor(_displayedColor); item->updateDisplayedColor(_displayedColor);
} });
V3F_C4B_T2F_Quad *quads = _textureAtlas->getQuads(); V3F_C4B_T2F_Quad *quads = _textureAtlas->getQuads();
int count = _textureAtlas->getTotalQuads(); long count = _textureAtlas->getTotalQuads();
Color4B color4( _displayedColor.r, _displayedColor.g, _displayedColor.b, _displayedOpacity ); Color4B color4( _displayedColor.r, _displayedColor.g, _displayedColor.b, _displayedOpacity );
// special opacity for premultiplied textures // special opacity for premultiplied textures

View File

@ -746,18 +746,10 @@ void LabelBMFont::setString(unsigned short *newString, bool needUpdateLabel)
CC_SAFE_DELETE_ARRAY(tmp); CC_SAFE_DELETE_ARRAY(tmp);
} }
if (_children && _children->count() != 0) _children.makeObjectsPerformCallback([](Node* child){
{ child->setVisible(false);
Object* child; });
CCARRAY_FOREACH(_children, child)
{
Node* pNode = static_cast<Node*>( child );
if (pNode)
{
pNode->setVisible(false);
}
}
}
this->createFontChars(); this->createFontChars();
if (needUpdateLabel) { if (needUpdateLabel) {
@ -830,22 +822,16 @@ void LabelBMFont::setOpacity(GLubyte opacity)
void LabelBMFont::setOpacityModifyRGB(bool var) void LabelBMFont::setOpacityModifyRGB(bool var)
{ {
_isOpacityModifyRGB = var; _isOpacityModifyRGB = var;
if (_children && _children->count() != 0) _children.makeObjectsPerformCallback([this](Node* child){
{ if (child)
Object* child;
CCARRAY_FOREACH(_children, child)
{ {
Node* pNode = static_cast<Node*>( child ); RGBAProtocol *pRGBAProtocol = dynamic_cast<RGBAProtocol*>(child);
if (pNode) if (pRGBAProtocol)
{ {
RGBAProtocol *pRGBAProtocol = dynamic_cast<RGBAProtocol*>(pNode); pRGBAProtocol->setOpacityModifyRGB(_isOpacityModifyRGB);
if (pRGBAProtocol)
{
pRGBAProtocol->setOpacityModifyRGB(_isOpacityModifyRGB);
}
} }
} }
} });
} }
bool LabelBMFont::isOpacityModifyRGB() const bool LabelBMFont::isOpacityModifyRGB() const
{ {
@ -854,28 +840,24 @@ bool LabelBMFont::isOpacityModifyRGB() const
void LabelBMFont::updateDisplayedOpacity(GLubyte parentOpacity) void LabelBMFont::updateDisplayedOpacity(GLubyte parentOpacity)
{ {
_displayedOpacity = _realOpacity * parentOpacity/255.0; _displayedOpacity = _realOpacity * parentOpacity/255.0f;
Object* pObj; _children.makeObjectsPerformCallback([this](Node* child){
CCARRAY_FOREACH(_children, pObj) Sprite *item = static_cast<Sprite*>( child );
{
Sprite *item = static_cast<Sprite*>( pObj );
item->updateDisplayedOpacity(_displayedOpacity); item->updateDisplayedOpacity(_displayedOpacity);
} });
} }
void LabelBMFont::updateDisplayedColor(const Color3B& parentColor) void LabelBMFont::updateDisplayedColor(const Color3B& parentColor)
{ {
_displayedColor.r = _realColor.r * parentColor.r/255.0; _displayedColor.r = _realColor.r * parentColor.r/255.0f;
_displayedColor.g = _realColor.g * parentColor.g/255.0; _displayedColor.g = _realColor.g * parentColor.g/255.0f;
_displayedColor.b = _realColor.b * parentColor.b/255.0; _displayedColor.b = _realColor.b * parentColor.b/255.0f;
Object* pObj; _children.makeObjectsPerformCallback([this](Node* child){
CCARRAY_FOREACH(_children, pObj) Sprite *item = static_cast<Sprite*>( child );
{
Sprite *item = static_cast<Sprite*>( pObj );
item->updateDisplayedColor(_displayedColor); item->updateDisplayedColor(_displayedColor);
} });
} }
bool LabelBMFont::isCascadeColorEnabled() const bool LabelBMFont::isCascadeColorEnabled() const
@ -917,7 +899,7 @@ void LabelBMFont::updateLabel()
{ {
// Step 1: Make multiline // Step 1: Make multiline
vector<unsigned short> str_whole = cc_utf16_vec_from_utf16_str(_string); vector<unsigned short> str_whole = cc_utf16_vec_from_utf16_str(_string);
unsigned int stringLength = str_whole.size(); size_t stringLength = str_whole.size();
vector<unsigned short> multiline_string; vector<unsigned short> multiline_string;
multiline_string.reserve( stringLength ); multiline_string.reserve( stringLength );
vector<unsigned short> last_word; vector<unsigned short> last_word;
@ -928,8 +910,8 @@ void LabelBMFont::updateLabel()
float startOfLine = -1, startOfWord = -1; float startOfLine = -1, startOfWord = -1;
int skip = 0; int skip = 0;
Array* children = getChildren(); auto children = getChildren();
for (int j = 0; j < children->count(); j++) for (int j = 0; j < children.count(); j++)
{ {
Sprite* characterSprite; Sprite* characterSprite;
unsigned int justSkipped = 0; unsigned int justSkipped = 0;
@ -1068,7 +1050,7 @@ void LabelBMFont::updateLabel()
multiline_string.insert(multiline_string.end(), last_word.begin(), last_word.end()); multiline_string.insert(multiline_string.end(), last_word.begin(), last_word.end());
int size = multiline_string.size(); size_t size = multiline_string.size();
unsigned short* str_new = new unsigned short[size + 1]; unsigned short* str_new = new unsigned short[size + 1];
for (int j = 0; j < size; ++j) for (int j = 0; j < size; ++j)
@ -1096,7 +1078,7 @@ void LabelBMFont::updateLabel()
if (_string[ctr] == '\n' || _string[ctr] == 0) if (_string[ctr] == '\n' || _string[ctr] == 0)
{ {
float lineWidth = 0.0f; float lineWidth = 0.0f;
unsigned int line_length = last_line.size(); size_t line_length = last_line.size();
// if last line is empty we must just increase lineNumber and work with next line // if last line is empty we must just increase lineNumber and work with next line
if (line_length == 0) if (line_length == 0)
{ {

View File

@ -499,15 +499,13 @@ void LayerRGBA::updateDisplayedOpacity(GLubyte parentOpacity)
if (_cascadeOpacityEnabled) if (_cascadeOpacityEnabled)
{ {
Object *obj = NULL; _children.makeObjectsPerformCallback([this](Node* obj){
CCARRAY_FOREACH(_children, obj)
{
RGBAProtocol *item = dynamic_cast<RGBAProtocol*>(obj); RGBAProtocol *item = dynamic_cast<RGBAProtocol*>(obj);
if (item) if (item)
{ {
item->updateDisplayedOpacity(_displayedOpacity); item->updateDisplayedOpacity(_displayedOpacity);
} }
} });
} }
} }
@ -519,15 +517,13 @@ void LayerRGBA::updateDisplayedColor(const Color3B& parentColor)
if (_cascadeColorEnabled) if (_cascadeColorEnabled)
{ {
Object *obj = NULL; _children.makeObjectsPerformCallback([this](Node* obj){
CCARRAY_FOREACH(_children, obj)
{
RGBAProtocol *item = dynamic_cast<RGBAProtocol*>(obj); RGBAProtocol *item = dynamic_cast<RGBAProtocol*>(obj);
if (item) if (item)
{ {
item->updateDisplayedColor(_displayedColor); item->updateDisplayedColor(_displayedColor);
} }
} });
} }
} }

View File

@ -81,36 +81,36 @@ Menu * Menu::create(MenuItem* item, ...)
return pRet; return pRet;
} }
Menu* Menu::createWithArray(Array* pArrayOfItems) Menu* Menu::createWithArray(const Vector<MenuItem*>& arrayOfItems)
{ {
Menu *pRet = new Menu(); auto ret = new Menu();
if (pRet && pRet->initWithArray(pArrayOfItems)) if (ret && ret->initWithArray(arrayOfItems))
{ {
pRet->autorelease(); ret->autorelease();
} }
else else
{ {
CC_SAFE_DELETE(pRet); CC_SAFE_DELETE(ret);
} }
return pRet; return ret;
} }
Menu* Menu::createWithItems(MenuItem* item, va_list args) Menu* Menu::createWithItems(MenuItem* item, va_list args)
{ {
Array* pArray = NULL; Vector<MenuItem*> items;
if( item ) if( item )
{ {
pArray = Array::create(item, NULL); items.addObject(item);
MenuItem *i = va_arg(args, MenuItem*); MenuItem *i = va_arg(args, MenuItem*);
while(i) while(i)
{ {
pArray->addObject(i); items.addObject(i);
i = va_arg(args, MenuItem*); i = va_arg(args, MenuItem*);
} }
} }
return Menu::createWithArray(pArray); return Menu::createWithArray(items);
} }
Menu* Menu::createWithItem(MenuItem* item) Menu* Menu::createWithItem(MenuItem* item)
@ -120,10 +120,10 @@ Menu* Menu::createWithItem(MenuItem* item)
bool Menu::init() bool Menu::init()
{ {
return initWithArray(NULL); return initWithArray(Vector<MenuItem*>());
} }
bool Menu::initWithArray(Array* pArrayOfItems) bool Menu::initWithArray(const Vector<MenuItem*>& arrayOfItems)
{ {
if (Layer::init()) if (Layer::init())
{ {
@ -137,16 +137,12 @@ bool Menu::initWithArray(Array* pArrayOfItems)
setPosition(Point(s.width/2, s.height/2)); setPosition(Point(s.width/2, s.height/2));
if (pArrayOfItems != NULL) int z=0;
for (auto& item : arrayOfItems)
{ {
int z=0; this->addChild(item, z);
Object* pObj = NULL; z++;
CCARRAY_FOREACH(pArrayOfItems, pObj)
{
MenuItem* item = static_cast<MenuItem*>(pObj);
this->addChild(item, z);
z++;
}
} }
_selectedItem = NULL; _selectedItem = NULL;
@ -306,33 +302,23 @@ void Menu::alignItemsVertically()
void Menu::alignItemsVerticallyWithPadding(float padding) void Menu::alignItemsVerticallyWithPadding(float padding)
{ {
float height = -padding; float height = -padding;
if (_children && _children->count() > 0)
{ _children.makeObjectsPerformCallback([&](Node* child){
Object* pObject = NULL; if (child)
CCARRAY_FOREACH(_children, pObject)
{ {
Node* child = dynamic_cast<Node*>(pObject); height += child->getContentSize().height * child->getScaleY() + padding;
if (child)
{
height += child->getContentSize().height * child->getScaleY() + padding;
}
} }
} });
float y = height / 2.0f; float y = height / 2.0f;
if (_children && _children->count() > 0)
{ _children.makeObjectsPerformCallback([&](Node* child){
Object* pObject = NULL; if (child)
CCARRAY_FOREACH(_children, pObject)
{ {
Node* child = dynamic_cast<Node*>(pObject); child->setPosition(Point(0, y - child->getContentSize().height * child->getScaleY() / 2.0f));
if (child) y -= child->getContentSize().height * child->getScaleY() + padding;
{
child->setPosition(Point(0, y - child->getContentSize().height * child->getScaleY() / 2.0f));
y -= child->getContentSize().height * child->getScaleY() + padding;
}
} }
} });
} }
void Menu::alignItemsHorizontally(void) void Menu::alignItemsHorizontally(void)
@ -342,35 +328,23 @@ void Menu::alignItemsHorizontally(void)
void Menu::alignItemsHorizontallyWithPadding(float padding) void Menu::alignItemsHorizontallyWithPadding(float padding)
{ {
float width = -padding; float width = -padding;
if (_children && _children->count() > 0) _children.makeObjectsPerformCallback([&](Node* child){
{ if (child)
Object* pObject = NULL;
CCARRAY_FOREACH(_children, pObject)
{ {
Node* child = dynamic_cast<Node*>(pObject); width += child->getContentSize().width * child->getScaleX() + padding;
if (child)
{
width += child->getContentSize().width * child->getScaleX() + padding;
}
} }
} });
float x = -width / 2.0f; float x = -width / 2.0f;
if (_children && _children->count() > 0)
{ _children.makeObjectsPerformCallback([&](Node* child){
Object* pObject = NULL; if (child)
CCARRAY_FOREACH(_children, pObject)
{ {
Node* child = dynamic_cast<Node*>(pObject); child->setPosition(Point(x + child->getContentSize().width * child->getScaleX() / 2.0f, 0));
if (child) x += child->getContentSize().width * child->getScaleX() + padding;
{
child->setPosition(Point(x + child->getContentSize().width * child->getScaleX() / 2.0f, 0));
x += child->getContentSize().width * child->getScaleX() + padding;
}
} }
} });
} }
void Menu::alignItemsInColumns(int columns, ...) void Menu::alignItemsInColumns(int columns, ...)
@ -405,35 +379,29 @@ void Menu::alignItemsInColumnsWithArray(Array* rowsArray)
unsigned int columnsOccupied = 0; unsigned int columnsOccupied = 0;
unsigned int rowColumns; unsigned int rowColumns;
if (_children && _children->count() > 0) _children.makeObjectsPerformCallback([&](Node* child){
{ if (child)
Object* pObject = NULL;
CCARRAY_FOREACH(_children, pObject)
{ {
Node* child = dynamic_cast<Node*>(pObject); CCASSERT(row < rows.size(), "");
if (child)
rowColumns = rows[row];
// can not have zero columns on a row
CCASSERT(rowColumns, "");
float tmp = child->getContentSize().height;
rowHeight = (unsigned int)((rowHeight >= tmp || isnan(tmp)) ? rowHeight : tmp);
++columnsOccupied;
if (columnsOccupied >= rowColumns)
{ {
CCASSERT(row < rows.size(), ""); height += rowHeight + 5;
rowColumns = rows[row]; columnsOccupied = 0;
// can not have zero columns on a row rowHeight = 0;
CCASSERT(rowColumns, ""); ++row;
float tmp = child->getContentSize().height;
rowHeight = (unsigned int)((rowHeight >= tmp || isnan(tmp)) ? rowHeight : tmp);
++columnsOccupied;
if (columnsOccupied >= rowColumns)
{
height += rowHeight + 5;
columnsOccupied = 0;
rowHeight = 0;
++row;
}
} }
} }
} });
// check if too many rows/columns for available menu items // check if too many rows/columns for available menu items
CCASSERT(! columnsOccupied, ""); CCASSERT(! columnsOccupied, "");
@ -447,12 +415,9 @@ void Menu::alignItemsInColumnsWithArray(Array* rowsArray)
float x = 0.0; float x = 0.0;
float y = (float)(height / 2); float y = (float)(height / 2);
if (_children && _children->count() > 0) _children.makeObjectsPerformCallback([&](Node* child){
{ if (child)
Object* pObject = NULL;
CCARRAY_FOREACH(_children, pObject)
{ {
Node* child = dynamic_cast<Node*>(pObject);
if (child) if (child)
{ {
if (rowColumns == 0) if (rowColumns == 0)
@ -482,7 +447,7 @@ void Menu::alignItemsInColumnsWithArray(Array* rowsArray)
} }
} }
} }
} });
} }
void Menu::alignItemsInRows(int rows, ...) void Menu::alignItemsInRows(int rows, ...)
@ -520,42 +485,36 @@ void Menu::alignItemsInRowsWithArray(Array* columnArray)
unsigned int rowsOccupied = 0; unsigned int rowsOccupied = 0;
unsigned int columnRows; unsigned int columnRows;
if (_children && _children->count() > 0) _children.makeObjectsPerformCallback([&](Node* child){
{ if (child)
Object* pObject = NULL;
CCARRAY_FOREACH(_children, pObject)
{ {
Node* child = dynamic_cast<Node*>(pObject); // check if too many menu items for the amount of rows/columns
if (child) CCASSERT(column < columns.size(), "");
columnRows = columns[column];
// can't have zero rows on a column
CCASSERT(columnRows, "");
// columnWidth = fmaxf(columnWidth, [item contentSize].width);
float tmp = child->getContentSize().width;
columnWidth = (unsigned int)((columnWidth >= tmp || isnan(tmp)) ? columnWidth : tmp);
columnHeight += (int)(child->getContentSize().height + 5);
++rowsOccupied;
if (rowsOccupied >= columnRows)
{ {
// check if too many menu items for the amount of rows/columns columnWidths.push_back(columnWidth);
CCASSERT(column < columns.size(), ""); columnHeights.push_back(columnHeight);
width += columnWidth + 10;
columnRows = columns[column]; rowsOccupied = 0;
// can't have zero rows on a column columnWidth = 0;
CCASSERT(columnRows, ""); columnHeight = -5;
++column;
// columnWidth = fmaxf(columnWidth, [item contentSize].width);
float tmp = child->getContentSize().width;
columnWidth = (unsigned int)((columnWidth >= tmp || isnan(tmp)) ? columnWidth : tmp);
columnHeight += (int)(child->getContentSize().height + 5);
++rowsOccupied;
if (rowsOccupied >= columnRows)
{
columnWidths.push_back(columnWidth);
columnHeights.push_back(columnHeight);
width += columnWidth + 10;
rowsOccupied = 0;
columnWidth = 0;
columnHeight = -5;
++column;
}
} }
} }
} });
// check if too many rows/columns for available menu items. // check if too many rows/columns for available menu items.
CCASSERT(! rowsOccupied, ""); CCASSERT(! rowsOccupied, "");
@ -568,59 +527,52 @@ void Menu::alignItemsInRowsWithArray(Array* columnArray)
float x = (float)(-width / 2); float x = (float)(-width / 2);
float y = 0.0; float y = 0.0;
if (_children && _children->count() > 0) _children.makeObjectsPerformCallback([&](Node* child){
{ if (child)
Object* pObject = NULL;
CCARRAY_FOREACH(_children, pObject)
{ {
Node* child = dynamic_cast<Node*>(pObject); if (columnRows == 0)
if (child)
{ {
if (columnRows == 0) columnRows = columns[column];
{ y = (float) columnHeights[column];
columnRows = columns[column]; }
y = (float) columnHeights[column];
}
// columnWidth = fmaxf(columnWidth, [item contentSize].width); // columnWidth = fmaxf(columnWidth, [item contentSize].width);
float tmp = child->getContentSize().width; float tmp = child->getContentSize().width;
columnWidth = (unsigned int)((columnWidth >= tmp || isnan(tmp)) ? columnWidth : tmp); columnWidth = (unsigned int)((columnWidth >= tmp || isnan(tmp)) ? columnWidth : tmp);
child->setPosition(Point(x + columnWidths[column] / 2, child->setPosition(Point(x + columnWidths[column] / 2,
y - winSize.height / 2)); y - winSize.height / 2));
y -= child->getContentSize().height + 10; y -= child->getContentSize().height + 10;
++rowsOccupied; ++rowsOccupied;
if (rowsOccupied >= columnRows) if (rowsOccupied >= columnRows)
{ {
x += columnWidth + 5; x += columnWidth + 5;
rowsOccupied = 0; rowsOccupied = 0;
columnRows = 0; columnRows = 0;
columnWidth = 0; columnWidth = 0;
++column; ++column;
}
} }
} }
} });
} }
MenuItem* Menu::itemForTouch(Touch *touch) MenuItem* Menu::itemForTouch(Touch *touch)
{ {
Point touchLocation = touch->getLocation(); Point touchLocation = touch->getLocation();
if (_children && _children->count() > 0) if (_children.count() > 0)
{ {
Object* pObject = NULL; for (auto iter = _children.rcbegin(); iter != _children.rcend(); ++iter)
CCARRAY_FOREACH_REVERSE(_children, pObject)
{ {
MenuItem* child = dynamic_cast<MenuItem*>(pObject); MenuItem* child = dynamic_cast<MenuItem*>(*iter);
if (child && child->isVisible() && child->isEnabled()) if (child && child->isVisible() && child->isEnabled())
{ {
Point local = child->convertToNodeSpace(touchLocation); Point local = child->convertToNodeSpace(touchLocation);
Rect r = child->rect(); Rect r = child->rect();
r.origin = Point::ZERO; r.origin = Point::ZERO;
if (r.containsPoint(local)) if (r.containsPoint(local))
{ {
return child; return child;

View File

@ -27,7 +27,7 @@ THE SOFTWARE.
#include "CCMenuItem.h" #include "CCMenuItem.h"
#include "CCLayer.h" #include "CCLayer.h"
#include "CCVector.h"
#include "CCEventTouch.h" #include "CCEventTouch.h"
NS_CC_BEGIN NS_CC_BEGIN
@ -63,7 +63,7 @@ public:
static Menu* create(MenuItem* item, ...) CC_REQUIRES_NULL_TERMINATION; static Menu* create(MenuItem* item, ...) CC_REQUIRES_NULL_TERMINATION;
/** creates a Menu with a Array of MenuItem objects */ /** creates a Menu with a Array of MenuItem objects */
static Menu* createWithArray(Array* pArrayOfItems); static Menu* createWithArray(const Vector<MenuItem*>& arrayOfItems);
/** creates a Menu with it's item, then use addChild() to add /** creates a Menu with it's item, then use addChild() to add
* other items. It is used for script, it can't init with undetermined * other items. It is used for script, it can't init with undetermined
@ -129,7 +129,7 @@ protected:
bool init(); bool init();
/** initializes a Menu with a NSArray of MenuItem objects */ /** initializes a Menu with a NSArray of MenuItem objects */
bool initWithArray(Array* pArrayOfItems); bool initWithArray(const Vector<MenuItem*>& arrayOfItems);
/** whether or not the menu will receive events */ /** whether or not the menu will receive events */
bool _enabled; bool _enabled;

View File

@ -114,7 +114,6 @@ Node::Node(void)
// lazy alloc // lazy alloc
, _grid(NULL) , _grid(NULL)
, _ZOrder(0) , _ZOrder(0)
, _children(NULL)
, _parent(NULL) , _parent(NULL)
// "whole screen" objects. like Scenes and Layers, should set _ignoreAnchorPointForPosition to true // "whole screen" objects. like Scenes and Layers, should set _ignoreAnchorPointForPosition to true
, _tag(Node::INVALID_TAG) , _tag(Node::INVALID_TAG)
@ -169,22 +168,14 @@ Node::~Node()
CC_SAFE_RELEASE(_shaderProgram); CC_SAFE_RELEASE(_shaderProgram);
CC_SAFE_RELEASE(_userObject); CC_SAFE_RELEASE(_userObject);
if(_children && _children->count() > 0) for (auto& child : _children)
{ {
Object* child; if (child)
CCARRAY_FOREACH(_children, child)
{ {
Node* node = static_cast<Node*>(child); child->_parent = NULL;
if (node)
{
node->_parent = NULL;
}
} }
} }
// children
CC_SAFE_RELEASE(_children);
removeAllComponents(); removeAllComponents();
CC_SAFE_DELETE(_componentContainer); CC_SAFE_DELETE(_componentContainer);
@ -406,7 +397,7 @@ void Node::setPositionY(float y)
long Node::getChildrenCount() const long Node::getChildrenCount() const
{ {
return _children ? _children->count() : 0; return _children.count();
} }
/// camera getter: lazy alloc /// camera getter: lazy alloc
@ -584,7 +575,9 @@ void Node::cleanup()
} }
// timers // timers
arrayMakeObjectsPerformSelector(_children, cleanup, Node*); _children.makeObjectsPerformCallback([](Node* child){
child->cleanup();
});
} }
@ -593,28 +586,16 @@ const char* Node::description() const
return String::createWithFormat("<Node | Tag = %d>", _tag)->getCString(); return String::createWithFormat("<Node | Tag = %d>", _tag)->getCString();
} }
// lazy allocs
void Node::childrenAlloc(void)
{
_children = Array::createWithCapacity(4);
_children->retain();
}
Node* Node::getChildByTag(int aTag) Node* Node::getChildByTag(int aTag)
{ {
CCASSERT( aTag != Node::INVALID_TAG, "Invalid tag"); CCASSERT( aTag != Node::INVALID_TAG, "Invalid tag");
if(_children && _children->count() > 0) for (auto& child : _children)
{ {
Object* child; if(child && child->_tag == aTag)
CCARRAY_FOREACH(_children, child) return child;
{
Node* pNode = static_cast<Node*>(child);
if(pNode && pNode->_tag == aTag)
return pNode;
}
} }
return NULL; return nullptr;
} }
/* "add" logic MUST only be on this method /* "add" logic MUST only be on this method
@ -626,11 +607,6 @@ void Node::addChild(Node *child, int zOrder, int tag)
CCASSERT( child != NULL, "Argument must be non-nil"); CCASSERT( child != NULL, "Argument must be non-nil");
CCASSERT( child->_parent == NULL, "child already added. It can't be added again"); CCASSERT( child->_parent == NULL, "child already added. It can't be added again");
if( ! _children )
{
this->childrenAlloc();
}
this->insertChild(child, zOrder); this->insertChild(child, zOrder);
#ifdef CC_USE_PHYSICS #ifdef CC_USE_PHYSICS
@ -691,12 +667,12 @@ void Node::removeFromParentAndCleanup(bool cleanup)
void Node::removeChild(Node* child, bool cleanup /* = true */) void Node::removeChild(Node* child, bool cleanup /* = true */)
{ {
// explicit nil handling // explicit nil handling
if (_children == NULL) if (_children.count() == 0)
{ {
return; return;
} }
long index = _children->getIndexOfObject(child); long index = _children.getIndexOfObject(child);
if( index != CC_INVALID_INDEX ) if( index != CC_INVALID_INDEX )
this->detachChild( child, index, cleanup ); this->detachChild( child, index, cleanup );
} }
@ -725,33 +701,31 @@ void Node::removeAllChildren()
void Node::removeAllChildrenWithCleanup(bool cleanup) void Node::removeAllChildrenWithCleanup(bool cleanup)
{ {
// not using detachChild improves speed here // not using detachChild improves speed here
if ( _children && _children->count() > 0 ) if ( _children.count() > 0 )
{ {
Object* child; for (auto& child : _children)
CCARRAY_FOREACH(_children, child)
{ {
Node* pNode = static_cast<Node*>(child); if (child)
if (pNode)
{ {
// IMPORTANT: // IMPORTANT:
// -1st do onExit // -1st do onExit
// -2nd cleanup // -2nd cleanup
if(_running) if(_running)
{ {
pNode->onExitTransitionDidStart(); child->onExitTransitionDidStart();
pNode->onExit(); child->onExit();
} }
if (cleanup) if (cleanup)
{ {
pNode->cleanup(); child->cleanup();
} }
// set parent nil at the end // set parent nil at the end
pNode->setParent(NULL); child->setParent(nullptr);
} }
} }
_children->removeAllObjects(); _children.removeAllObjects();
} }
} }
@ -783,9 +757,9 @@ void Node::detachChild(Node *child, long childIndex, bool doCleanup)
} }
// set parent nil at the end // set parent nil at the end
child->setParent(NULL); child->setParent(nullptr);
_children->removeObjectAtIndex(childIndex); _children.removeObjectAtIndex(childIndex);
} }
@ -793,7 +767,7 @@ void Node::detachChild(Node *child, long childIndex, bool doCleanup)
void Node::insertChild(Node* child, int z) void Node::insertChild(Node* child, int z)
{ {
_reorderChildDirty = true; _reorderChildDirty = true;
_children->addObject(child); _children.addObject(child);
child->_setZOrder(z); child->_setZOrder(z);
} }
@ -810,24 +784,24 @@ void Node::sortAllChildren()
#if 0 #if 0
if (_reorderChildDirty) if (_reorderChildDirty)
{ {
int i,j,length = _children->count(); int i,j,length = _children.count();
// insertion sort // insertion sort
for(i=1; i<length; i++) for(i=1; i<length; i++)
{ {
j = i-1; j = i-1;
auto tempI = static_cast<Node*>( _children->getObjectAtIndex(i) ); auto tempI = static_cast<Node*>( _children.getObjectAtIndex(i) );
auto tempJ = static_cast<Node*>( _children->getObjectAtIndex(j) ); auto tempJ = static_cast<Node*>( _children.getObjectAtIndex(j) );
//continue moving element downwards while zOrder is smaller or when zOrder is the same but mutatedIndex is smaller //continue moving element downwards while zOrder is smaller or when zOrder is the same but mutatedIndex is smaller
while(j>=0 && ( tempI->_ZOrder < tempJ->_ZOrder || ( tempI->_ZOrder == tempJ->_ZOrder && tempI->_orderOfArrival < tempJ->_orderOfArrival ) ) ) while(j>=0 && ( tempI->_ZOrder < tempJ->_ZOrder || ( tempI->_ZOrder == tempJ->_ZOrder && tempI->_orderOfArrival < tempJ->_orderOfArrival ) ) )
{ {
_children->fastSetObject( tempJ, j+1 ); _children.fastSetObject( tempJ, j+1 );
j = j-1; j = j-1;
if(j>=0) if(j>=0)
tempJ = static_cast<Node*>( _children->getObjectAtIndex(j) ); tempJ = static_cast<Node*>( _children.getObjectAtIndex(j) );
} }
_children->fastSetObject(tempI, j+1); _children.fastSetObject(tempI, j+1);
} }
//don't need to check children recursively, that's done in visit of each child //don't need to check children recursively, that's done in visit of each child
@ -836,7 +810,7 @@ void Node::sortAllChildren()
} }
#else #else
if( _reorderChildDirty ) { if( _reorderChildDirty ) {
std::sort( std::begin(*_children), std::end(*_children), nodeComparisonLess ); std::sort( std::begin(_children), std::end(_children), nodeComparisonLess );
_reorderChildDirty = false; _reorderChildDirty = false;
} }
#endif #endif
@ -869,13 +843,13 @@ void Node::visit()
this->transform(); this->transform();
int i = 0; int i = 0;
if(_children && _children->count() > 0) if(_children.count() > 0)
{ {
sortAllChildren(); sortAllChildren();
// draw children zOrder < 0 // draw children zOrder < 0
for( ; i < _children->count(); i++ ) for( ; i < _children.count(); i++ )
{ {
auto node = static_cast<Node*>( _children->getObjectAtIndex(i) ); auto node = _children[i];
if ( node && node->_ZOrder < 0 ) if ( node && node->_ZOrder < 0 )
node->visit(); node->visit();
@ -885,9 +859,9 @@ void Node::visit()
// self draw // self draw
this->draw(); this->draw();
for( ; i < _children->count(); i++ ) for( ; i < _children.count(); i++ )
{ {
auto node = static_cast<Node*>( _children->getObjectAtIndex(i) ); auto node = _children[i];
if (node) if (node)
node->visit(); node->visit();
} }
@ -955,7 +929,9 @@ void Node::onEnter()
{ {
_isTransitionFinished = false; _isTransitionFinished = false;
arrayMakeObjectsPerformSelector(_children, onEnter, Node*); _children.makeObjectsPerformCallback([](Node* child){
child->onEnter();
});
this->resume(); this->resume();
@ -974,8 +950,10 @@ void Node::onEnterTransitionDidFinish()
{ {
_isTransitionFinished = true; _isTransitionFinished = true;
arrayMakeObjectsPerformSelector(_children, onEnterTransitionDidFinish, Node*); _children.makeObjectsPerformCallback([](Node* child){
child->onEnterTransitionDidFinish();
});
if (_scriptType != kScriptTypeNone) if (_scriptType != kScriptTypeNone)
{ {
int action = kNodeOnEnterTransitionDidFinish; int action = kNodeOnEnterTransitionDidFinish;
@ -987,7 +965,10 @@ void Node::onEnterTransitionDidFinish()
void Node::onExitTransitionDidStart() void Node::onExitTransitionDidStart()
{ {
arrayMakeObjectsPerformSelector(_children, onExitTransitionDidStart, Node*); _children.makeObjectsPerformCallback([](Node* child){
child->onExitTransitionDidStart();
});
if (_scriptType != kScriptTypeNone) if (_scriptType != kScriptTypeNone)
{ {
int action = kNodeOnExitTransitionDidStart; int action = kNodeOnExitTransitionDidStart;
@ -1010,7 +991,9 @@ void Node::onExit()
ScriptEngineManager::getInstance()->getScriptEngine()->sendEvent(&scriptEvent); ScriptEngineManager::getInstance()->getScriptEngine()->sendEvent(&scriptEvent);
} }
arrayMakeObjectsPerformSelector(_children, onExit, Node*); _children.makeObjectsPerformCallback([](Node* child){
child->onExit();
});
} }
void Node::setEventDispatcher(EventDispatcher* dispatcher) void Node::setEventDispatcher(EventDispatcher* dispatcher)
@ -1063,7 +1046,7 @@ Action * Node::getActionByTag(int tag)
return _actionManager->getActionByTag(tag, this); return _actionManager->getActionByTag(tag, this);
} }
unsigned int Node::getNumberOfRunningActions() const long Node::getNumberOfRunningActions() const
{ {
return _actionManager->getNumberOfRunningActionsInTarget(this); return _actionManager->getNumberOfRunningActionsInTarget(this);
} }
@ -1358,7 +1341,9 @@ bool Node::updatePhysicsTransform()
void Node::updateTransform() void Node::updateTransform()
{ {
// Recursively iterate over children // Recursively iterate over children
arrayMakeObjectsPerformSelector(_children, updateTransform, Node*); _children.makeObjectsPerformCallback([](Node* child){
child->updateTransform();
});
} }
Component* Node::getComponent(const char *pName) Component* Node::getComponent(const char *pName)
@ -1467,15 +1452,13 @@ void NodeRGBA::updateDisplayedOpacity(GLubyte parentOpacity)
if (_cascadeOpacityEnabled) if (_cascadeOpacityEnabled)
{ {
Object* pObj; _children.makeObjectsPerformCallback([this](Node* child){
CCARRAY_FOREACH(_children, pObj) RGBAProtocol* item = dynamic_cast<RGBAProtocol*>(child);
{
RGBAProtocol* item = dynamic_cast<RGBAProtocol*>(pObj);
if (item) if (item)
{ {
item->updateDisplayedOpacity(_displayedOpacity); item->updateDisplayedOpacity(_displayedOpacity);
} }
} });
} }
} }
@ -1524,15 +1507,13 @@ void NodeRGBA::updateDisplayedColor(const Color3B& parentColor)
if (_cascadeColorEnabled) if (_cascadeColorEnabled)
{ {
Object *obj = NULL; _children.makeObjectsPerformCallback([this](Node* child){
CCARRAY_FOREACH(_children, obj) RGBAProtocol *item = dynamic_cast<RGBAProtocol*>(child);
{
RGBAProtocol *item = dynamic_cast<RGBAProtocol*>(obj);
if (item) if (item)
{ {
item->updateDisplayedColor(_displayedColor); item->updateDisplayedColor(_displayedColor);
} }
} });
} }
} }

View File

@ -38,8 +38,7 @@
#include "CCScriptSupport.h" #include "CCScriptSupport.h"
#include "CCProtocols.h" #include "CCProtocols.h"
#include "CCEventDispatcher.h" #include "CCEventDispatcher.h"
#include "CCVector.h"
#include <vector>
NS_CC_BEGIN NS_CC_BEGIN
@ -614,10 +613,10 @@ public:
* *
* @return An array of children * @return An array of children
*/ */
virtual Array* getChildren() { return _children; } virtual Vector<Node*>& getChildren() { return _children; }
virtual const Array *getChildren() const { return _children; } virtual const Vector<Node*>& getChildren() const { return _children; }
/** /**
* Get the amount of children. * Get the amount of children.
* *
* @return The amount of children. * @return The amount of children.
@ -1043,7 +1042,7 @@ public:
* *
* @return The number of actions that are running plus the ones that are schedule to run * @return The number of actions that are running plus the ones that are schedule to run
*/ */
unsigned int getNumberOfRunningActions() const; long getNumberOfRunningActions() const;
/** @deprecated Use getNumberOfRunningActions() instead */ /** @deprecated Use getNumberOfRunningActions() instead */
CC_DEPRECATED_ATTRIBUTE unsigned int numberOfRunningActions() const { return getNumberOfRunningActions(); }; CC_DEPRECATED_ATTRIBUTE unsigned int numberOfRunningActions() const { return getNumberOfRunningActions(); };
@ -1395,10 +1394,7 @@ protected:
Node(); Node();
virtual ~Node(); virtual ~Node();
virtual bool init(); virtual bool init();
/// lazy allocs
void childrenAlloc(void);
/// helper that reorder a child /// helper that reorder a child
void insertChild(Node* child, int z); void insertChild(Node* child, int z);
@ -1440,8 +1436,8 @@ protected:
GridBase *_grid; ///< a grid GridBase *_grid; ///< a grid
int _ZOrder; ///< z-order value that affects the draw order int _ZOrder; ///< z-order value that affects the draw order
Array *_children; ///< array of children nodes Vector<Node*> _children; ///< array of children nodes
Node *_parent; ///< weak reference to parent node Node *_parent; ///< weak reference to parent node
int _tag; ///< a tag. Can be any number you assigned just to identify this node int _tag; ///< a tag. Can be any number you assigned just to identify this node

View File

@ -96,9 +96,11 @@ bool ParticleBatchNode::initWithTexture(Texture2D *tex, int capacity)
_textureAtlas->initWithTexture(tex, capacity); _textureAtlas->initWithTexture(tex, capacity);
// no lazy alloc in this node // no lazy alloc in this node
_children = new Array(); if (_children.count() == 0)
_children->initWithCapacity(capacity); {
_children.init(capacity);
}
_blendFunc = BlendFunc::ALPHA_PREMULTIPLIED; _blendFunc = BlendFunc::ALPHA_PREMULTIPLIED;
setShaderProgram(ShaderCache::getInstance()->getProgram(GLProgram::SHADER_NAME_POSITION_TEXTURE_COLOR)); setShaderProgram(ShaderCache::getInstance()->getProgram(GLProgram::SHADER_NAME_POSITION_TEXTURE_COLOR));
@ -171,7 +173,7 @@ void ParticleBatchNode::addChild(Node * aChild, int zOrder, int tag)
ParticleSystem* child = static_cast<ParticleSystem*>(aChild); ParticleSystem* child = static_cast<ParticleSystem*>(aChild);
CCASSERT( child->getTexture()->getName() == _textureAtlas->getTexture()->getName(), "CCParticleSystem is not using the same texture id"); CCASSERT( child->getTexture()->getName() == _textureAtlas->getTexture()->getName(), "CCParticleSystem is not using the same texture id");
// If this is the 1st children, then copy blending function // If this is the 1st children, then copy blending function
if( _children->count() == 0 ) if( _children.count() == 0 )
{ {
setBlendFunc(child->getBlendFunc()); setBlendFunc(child->getBlendFunc());
} }
@ -186,9 +188,8 @@ void ParticleBatchNode::addChild(Node * aChild, int zOrder, int tag)
if (pos != 0) if (pos != 0)
{ {
ParticleSystem* p = (ParticleSystem*)_children->getObjectAtIndex(pos-1); ParticleSystem* p = static_cast<ParticleSystem*>(_children[pos-1]);
atlasIndex = p->getAtlasIndex() + p->getTotalParticles(); atlasIndex = p->getAtlasIndex() + p->getTotalParticles();
} }
else else
{ {
@ -205,21 +206,20 @@ void ParticleBatchNode::addChild(Node * aChild, int zOrder, int tag)
// XXX research whether lazy sorting + freeing current quads and calloc a new block with size of capacity would be faster // XXX research whether lazy sorting + freeing current quads and calloc a new block with size of capacity would be faster
// XXX or possibly using vertexZ for reordering, that would be fastest // XXX or possibly using vertexZ for reordering, that would be fastest
// this helper is almost equivalent to Node's addChild, but doesn't make use of the lazy sorting // this helper is almost equivalent to Node's addChild, but doesn't make use of the lazy sorting
unsigned int ParticleBatchNode::addChildHelper(ParticleSystem* child, int z, int aTag) long ParticleBatchNode::addChildHelper(ParticleSystem* child, int z, int aTag)
{ {
CCASSERT( child != NULL, "Argument must be non-nil"); CCASSERT( child != NULL, "Argument must be non-nil");
CCASSERT( child->getParent() == NULL, "child already added. It can't be added again"); CCASSERT( child->getParent() == NULL, "child already added. It can't be added again");
if( ! _children ) if (_children.count() == 0 )
{ {
_children = new Array(); _children.init(4);
_children->initWithCapacity(4);
} }
//don't use a lazy insert //don't use a lazy insert
unsigned int pos = searchNewPositionInChildrenForZ(z); long pos = searchNewPositionInChildrenForZ(z);
_children->insertObject(child, pos); _children.insertObject(child, pos);
child->setTag(aTag); child->setTag(aTag);
child->_setZOrder(z); child->_setZOrder(z);
@ -239,7 +239,7 @@ void ParticleBatchNode::reorderChild(Node * aChild, int zOrder)
{ {
CCASSERT( aChild != NULL, "Child must be non-NULL"); CCASSERT( aChild != NULL, "Child must be non-NULL");
CCASSERT( dynamic_cast<ParticleSystem*>(aChild) != NULL, "CCParticleBatchNode only supports QuadParticleSystems as children"); CCASSERT( dynamic_cast<ParticleSystem*>(aChild) != NULL, "CCParticleBatchNode only supports QuadParticleSystems as children");
CCASSERT( _children->containsObject(aChild), "Child doesn't belong to batch" ); CCASSERT( _children.containsObject(aChild), "Child doesn't belong to batch" );
ParticleSystem* child = static_cast<ParticleSystem*>(aChild); ParticleSystem* child = static_cast<ParticleSystem*>(aChild);
@ -249,9 +249,9 @@ void ParticleBatchNode::reorderChild(Node * aChild, int zOrder)
} }
// no reordering if only 1 child // no reordering if only 1 child
if( _children->count() > 1) if( _children.count() > 1)
{ {
unsigned int newIndex = 0, oldIndex = 0; long newIndex = 0, oldIndex = 0;
getCurrentIndex(&oldIndex, &newIndex, child, zOrder); getCurrentIndex(&oldIndex, &newIndex, child, zOrder);
@ -260,8 +260,8 @@ void ParticleBatchNode::reorderChild(Node * aChild, int zOrder)
// reorder _children->array // reorder _children->array
child->retain(); child->retain();
_children->removeObjectAtIndex(oldIndex); _children.removeObjectAtIndex(oldIndex);
_children->insertObject(child, newIndex); _children.insertObject(child, newIndex);
child->release(); child->release();
// save old altasIndex // save old altasIndex
@ -272,10 +272,10 @@ void ParticleBatchNode::reorderChild(Node * aChild, int zOrder)
// Find new AtlasIndex // Find new AtlasIndex
int newAtlasIndex = 0; int newAtlasIndex = 0;
for( int i=0;i < _children->count();i++) for( int i=0;i < _children.count();i++)
{ {
ParticleSystem* pNode = (ParticleSystem*)_children->getObjectAtIndex(i); ParticleSystem* node = static_cast<ParticleSystem*>(_children[i]);
if( pNode == child ) if( node == child )
{ {
newAtlasIndex = child->getAtlasIndex(); newAtlasIndex = child->getAtlasIndex();
break; break;
@ -292,17 +292,17 @@ void ParticleBatchNode::reorderChild(Node * aChild, int zOrder)
child->_setZOrder(zOrder); child->_setZOrder(zOrder);
} }
void ParticleBatchNode::getCurrentIndex(unsigned int* oldIndex, unsigned int* newIndex, Node* child, int z) void ParticleBatchNode::getCurrentIndex(long* oldIndex, long* newIndex, Node* child, int z)
{ {
bool foundCurrentIdx = false; bool foundCurrentIdx = false;
bool foundNewIdx = false; bool foundNewIdx = false;
int minusOne = 0; int minusOne = 0;
unsigned int count = _children->count(); long count = _children.count();
for( unsigned int i=0; i < count; i++ ) for( long i=0; i < count; i++ )
{ {
Node* pNode = (Node *)_children->getObjectAtIndex(i); Node* pNode = _children[i];
// new index // new index
if( pNode->getZOrder() > z && ! foundNewIdx ) if( pNode->getZOrder() > z && ! foundNewIdx )
@ -343,13 +343,13 @@ void ParticleBatchNode::getCurrentIndex(unsigned int* oldIndex, unsigned int* ne
*newIndex += minusOne; *newIndex += minusOne;
} }
unsigned int ParticleBatchNode::searchNewPositionInChildrenForZ(int z) long ParticleBatchNode::searchNewPositionInChildrenForZ(int z)
{ {
unsigned int count = _children->count(); long count = _children.count();
for( unsigned int i=0; i < count; i++ ) for( long i=0; i < count; i++ )
{ {
Node *child = (Node *)_children->getObjectAtIndex(i); Node *child = _children[i];
if (child->getZOrder() > z) if (child->getZOrder() > z)
{ {
return i; return i;
@ -366,7 +366,7 @@ void ParticleBatchNode::removeChild(Node* aChild, bool cleanup)
return; return;
CCASSERT( dynamic_cast<ParticleSystem*>(aChild) != NULL, "CCParticleBatchNode only supports QuadParticleSystems as children"); CCASSERT( dynamic_cast<ParticleSystem*>(aChild) != NULL, "CCParticleBatchNode only supports QuadParticleSystems as children");
CCASSERT(_children->containsObject(aChild), "CCParticleBatchNode doesn't contain the sprite. Can't remove it"); CCASSERT(_children.containsObject(aChild), "CCParticleBatchNode doesn't contain the sprite. Can't remove it");
ParticleSystem* child = static_cast<ParticleSystem*>(aChild); ParticleSystem* child = static_cast<ParticleSystem*>(aChild);
Node::removeChild(child, cleanup); Node::removeChild(child, cleanup);
@ -385,12 +385,14 @@ void ParticleBatchNode::removeChild(Node* aChild, bool cleanup)
void ParticleBatchNode::removeChildAtIndex(unsigned int index, bool doCleanup) void ParticleBatchNode::removeChildAtIndex(unsigned int index, bool doCleanup)
{ {
removeChild((ParticleSystem *)_children->getObjectAtIndex(index),doCleanup); removeChild(_children[index],doCleanup);
} }
void ParticleBatchNode::removeAllChildrenWithCleanup(bool doCleanup) void ParticleBatchNode::removeAllChildrenWithCleanup(bool doCleanup)
{ {
arrayMakeObjectsPerformSelectorWithObject(_children, setBatchNode, NULL, ParticleSystem*); _children.makeObjectsPerformCallback([](Node* child){
static_cast<ParticleSystem*>(child)->setBatchNode(nullptr);
});
Node::removeAllChildrenWithCleanup(doCleanup); Node::removeAllChildrenWithCleanup(doCleanup);
@ -417,7 +419,7 @@ void ParticleBatchNode::draw(void)
void ParticleBatchNode::increaseAtlasCapacityTo(unsigned int quantity) void ParticleBatchNode::increaseAtlasCapacityTo(long quantity)
{ {
CCLOG("cocos2d: ParticleBatchNode: resizing TextureAtlas capacity from [%lu] to [%lu].", CCLOG("cocos2d: ParticleBatchNode: resizing TextureAtlas capacity from [%lu] to [%lu].",
(long)_textureAtlas->getCapacity(), (long)_textureAtlas->getCapacity(),
@ -467,15 +469,13 @@ void ParticleBatchNode::insertChild(ParticleSystem* system, int index)
//rebuild atlas indexes //rebuild atlas indexes
void ParticleBatchNode::updateAllAtlasIndexes() void ParticleBatchNode::updateAllAtlasIndexes()
{ {
Object *pObj = NULL;
unsigned int index = 0; unsigned int index = 0;
CCARRAY_FOREACH(_children,pObj) _children.makeObjectsPerformCallback([&index](Node* child){
{ ParticleSystem* partiSys = static_cast<ParticleSystem*>(child);
ParticleSystem* child = static_cast<ParticleSystem*>(pObj); partiSys->setAtlasIndex(index);
child->setAtlasIndex(index); index += partiSys->getTotalParticles();
index += child->getTotalParticles(); });
}
} }
// ParticleBatchNode - CocosNodeTexture protocol // ParticleBatchNode - CocosNodeTexture protocol

View File

@ -129,10 +129,10 @@ public:
private: private:
void updateAllAtlasIndexes(); void updateAllAtlasIndexes();
void increaseAtlasCapacityTo(unsigned int quantity); void increaseAtlasCapacityTo(long quantity);
unsigned int searchNewPositionInChildrenForZ(int z); long searchNewPositionInChildrenForZ(int z);
void getCurrentIndex(unsigned int* oldIndex, unsigned int* newIndex, Node* child, int z); void getCurrentIndex(long* oldIndex, long* newIndex, Node* child, int z);
unsigned int addChildHelper(ParticleSystem* child, int z, int aTag); long addChildHelper(ParticleSystem* child, int z, int aTag);
void updateBlendFunc(void); void updateBlendFunc(void);
/** the texture atlas used for drawing the quads */ /** the texture atlas used for drawing the quads */
TextureAtlas* _textureAtlas; TextureAtlas* _textureAtlas;

View File

@ -528,16 +528,12 @@ void RenderTexture::draw()
//! make sure all children are drawn //! make sure all children are drawn
sortAllChildren(); sortAllChildren();
Object *pElement; _children.makeObjectsPerformCallback([this](Node* child){
CCARRAY_FOREACH(_children, pElement)
{
Node *child = static_cast<Node*>(pElement);
if (child != _sprite) if (child != _sprite)
{ {
child->visit(); child->visit();
} }
} });
end(); end();
} }

View File

@ -132,25 +132,17 @@ void Scene::addChildToPhysicsWorld(Node* child)
{ {
if (_physicsWorld) if (_physicsWorld)
{ {
std::function<void(Object*)> addToPhysicsWorldFunc = nullptr; std::function<void(Node*)> addToPhysicsWorldFunc = nullptr;
addToPhysicsWorldFunc = [this, &addToPhysicsWorldFunc](Object* obj) -> void addToPhysicsWorldFunc = [this, &addToPhysicsWorldFunc](Node* node) -> void
{ {
if (node->getPhysicsBody())
if (dynamic_cast<Node*>(obj) != nullptr)
{ {
Node* node = dynamic_cast<Node*>(obj); _physicsWorld->addBody(node->getPhysicsBody());
if (node->getPhysicsBody())
{
_physicsWorld->addBody(node->getPhysicsBody());
}
Object* subChild = nullptr;
CCARRAY_FOREACH(node->getChildren(), subChild)
{
addToPhysicsWorldFunc(subChild);
}
} }
node->getChildren().makeObjectsPerformCallback([addToPhysicsWorldFunc](Node* n){
addToPhysicsWorldFunc(n);
});
}; };
addToPhysicsWorldFunc(child); addToPhysicsWorldFunc(child);

View File

@ -696,7 +696,7 @@ void Sprite::addChild(Node *child, int zOrder, int tag)
void Sprite::reorderChild(Node *child, int zOrder) void Sprite::reorderChild(Node *child, int zOrder)
{ {
CCASSERT(child != NULL, ""); CCASSERT(child != NULL, "");
CCASSERT(_children->containsObject(child), ""); CCASSERT(_children.containsObject(child), "");
if (zOrder == child->getZOrder()) if (zOrder == child->getZOrder())
{ {
@ -726,15 +726,13 @@ void Sprite::removeAllChildrenWithCleanup(bool cleanup)
{ {
if (_batchNode) if (_batchNode)
{ {
Object* object = NULL; _children.makeObjectsPerformCallback([this](Node* child){
CCARRAY_FOREACH(_children, object) Sprite* sprite = dynamic_cast<Sprite*>(child);
{ if (sprite)
Sprite* child = dynamic_cast<Sprite*>(object);
if (child)
{ {
_batchNode->removeSpriteFromAtlas(child); _batchNode->removeSpriteFromAtlas(sprite);
} }
} });
} }
Node::removeAllChildrenWithCleanup(cleanup); Node::removeAllChildrenWithCleanup(cleanup);
@ -769,12 +767,14 @@ void Sprite::sortAllChildren()
_children->fastSetObject(tempI, j+1); _children->fastSetObject(tempI, j+1);
} }
#else #else
std::sort(std::begin(*_children), std::end(*_children), nodeComparisonLess); std::sort(std::begin(_children), std::end(_children), nodeComparisonLess);
#endif #endif
if ( _batchNode) if ( _batchNode)
{ {
arrayMakeObjectsPerformSelector(_children, sortAllChildren, Sprite*); _children.makeObjectsPerformCallback([](Node* child){
child->sortAllChildren();
});
} }
_reorderChildDirty = false; _reorderChildDirty = false;
@ -809,15 +809,13 @@ void Sprite::setDirtyRecursively(bool bValue)
// recursively set dirty // recursively set dirty
if (_hasChildren) if (_hasChildren)
{ {
Object* object = NULL; _children.makeObjectsPerformCallback([](Node* child){
CCARRAY_FOREACH(_children, object) Sprite* sp = dynamic_cast<Sprite*>(child);
{ if (sp)
Sprite* child = dynamic_cast<Sprite*>(object);
if (child)
{ {
child->setDirtyRecursively(true); sp->setDirtyRecursively(true);
} }
} });
} }
} }
@ -1062,7 +1060,7 @@ void Sprite::setDisplayFrameWithAnimationName(const std::string& animationName,
CCASSERT(a, "CCSprite#setDisplayFrameWithAnimationName: Frame not found"); CCASSERT(a, "CCSprite#setDisplayFrameWithAnimationName: Frame not found");
AnimationFrame* frame = static_cast<AnimationFrame*>( a->getFrames()->getObjectAtIndex(frameIndex) ); AnimationFrame* frame = a->getFrames()[frameIndex];
CCASSERT(frame, "CCSprite#setDisplayFrame. Invalid frame"); CCASSERT(frame, "CCSprite#setDisplayFrame. Invalid frame");

View File

@ -93,9 +93,10 @@ bool SpriteBatchNode::initWithTexture(Texture2D *tex, long capacity)
updateBlendFunc(); updateBlendFunc();
// no lazy alloc in this node // no lazy alloc in this node
_children = new Array(); if (_children.count() == 0)
_children->initWithCapacity(capacity); {
_children.init(capacity);
}
_descendants.reserve(capacity); _descendants.reserve(capacity);
setShaderProgram(ShaderCache::getInstance()->getProgram(GLProgram::SHADER_NAME_POSITION_TEXTURE_COLOR)); setShaderProgram(ShaderCache::getInstance()->getProgram(GLProgram::SHADER_NAME_POSITION_TEXTURE_COLOR));
@ -187,7 +188,7 @@ void SpriteBatchNode::addChild(Node *child, int zOrder, int tag)
void SpriteBatchNode::reorderChild(Node *child, int zOrder) void SpriteBatchNode::reorderChild(Node *child, int zOrder)
{ {
CCASSERT(child != NULL, "the child should not be null"); CCASSERT(child != NULL, "the child should not be null");
CCASSERT(_children->containsObject(child), "Child doesn't belong to Sprite"); CCASSERT(_children.containsObject(child), "Child doesn't belong to Sprite");
if (zOrder == child->getZOrder()) if (zOrder == child->getZOrder())
{ {
@ -209,7 +210,7 @@ void SpriteBatchNode::removeChild(Node *child, bool cleanup)
return; return;
} }
CCASSERT(_children->containsObject(sprite), "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(sprite); removeSpriteFromAtlas(sprite);
@ -219,8 +220,8 @@ void SpriteBatchNode::removeChild(Node *child, bool cleanup)
void SpriteBatchNode::removeChildAtIndex(int index, bool doCleanup) void SpriteBatchNode::removeChildAtIndex(int index, bool doCleanup)
{ {
CCASSERT(index>=0 && index < _children->count(), "Invalid index"); CCASSERT(index>=0 && index < _children.count(), "Invalid index");
removeChild( static_cast<Sprite*>(_children->getObjectAtIndex(index)), doCleanup); removeChild(_children[index], doCleanup);
} }
void SpriteBatchNode::removeAllChildrenWithCleanup(bool doCleanup) void SpriteBatchNode::removeAllChildrenWithCleanup(bool doCleanup)
@ -265,25 +266,25 @@ void SpriteBatchNode::sortAllChildren()
_children->fastSetObject(tempI, j+1); _children->fastSetObject(tempI, j+1);
} }
#else #else
std::sort(std::begin(*_children), std::end(*_children), nodeComparisonLess); std::sort(std::begin(_children), std::end(_children), nodeComparisonLess);
#endif #endif
//sorted now check all children //sorted now check all children
if (_children->count() > 0) if (_children.count() > 0)
{ {
//first sort all children recursively based on zOrder //first sort all children recursively based on zOrder
arrayMakeObjectsPerformSelector(_children, sortAllChildren, Sprite*); _children.makeObjectsPerformCallback([](Node* child){
child->sortAllChildren();
});
int index=0; int index=0;
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, obj) _children.makeObjectsPerformCallback([this, &index](Node* child){
{ Sprite* sp = static_cast<Sprite*>(child);
Sprite* child = static_cast<Sprite*>(obj); updateAtlasIndex(sp, &index);
updateAtlasIndex(child, &index); });
}
} }
_reorderChildDirty=false; _reorderChildDirty=false;
@ -292,12 +293,8 @@ void SpriteBatchNode::sortAllChildren()
void SpriteBatchNode::updateAtlasIndex(Sprite* sprite, int* curIndex) void SpriteBatchNode::updateAtlasIndex(Sprite* sprite, int* curIndex)
{ {
int count = 0; auto array = sprite->getChildren();
Array* array = sprite->getChildren(); long count = array.count();
if (array != NULL)
{
count = array->count();
}
int oldIndex = 0; int oldIndex = 0;
@ -315,7 +312,7 @@ void SpriteBatchNode::updateAtlasIndex(Sprite* sprite, int* curIndex)
{ {
bool needNewIndex=true; bool needNewIndex=true;
if (static_cast<Sprite*>(array->getObjectAtIndex(0) )->getZOrder() >= 0) if (array[0]->getZOrder() >= 0)
{ {
//all children are in front of the parent //all children are in front of the parent
oldIndex = sprite->getAtlasIndex(); oldIndex = sprite->getAtlasIndex();
@ -330,11 +327,9 @@ void SpriteBatchNode::updateAtlasIndex(Sprite* sprite, int* curIndex)
needNewIndex = false; needNewIndex = false;
} }
Object* obj = NULL; array.makeObjectsPerformCallback([&](Node* child){
CCARRAY_FOREACH(array,obj) Sprite* sp = static_cast<Sprite*>(child);
{ if (needNewIndex && sp->getZOrder() >= 0)
Sprite* child = static_cast<Sprite*>(obj);
if (needNewIndex && child->getZOrder() >= 0)
{ {
oldIndex = sprite->getAtlasIndex(); oldIndex = sprite->getAtlasIndex();
sprite->setAtlasIndex(*curIndex); sprite->setAtlasIndex(*curIndex);
@ -344,11 +339,10 @@ void SpriteBatchNode::updateAtlasIndex(Sprite* sprite, int* curIndex)
} }
(*curIndex)++; (*curIndex)++;
needNewIndex = false; needNewIndex = false;
} }
updateAtlasIndex(child, curIndex); updateAtlasIndex(sp, curIndex);
} });
if (needNewIndex) if (needNewIndex)
{//all children have a zOrder < 0) {//all children have a zOrder < 0)
@ -399,7 +393,9 @@ void SpriteBatchNode::draw(void)
CC_NODE_DRAW_SETUP(); CC_NODE_DRAW_SETUP();
arrayMakeObjectsPerformSelector(_children, updateTransform, Sprite*); _children.makeObjectsPerformCallback([](Node* child){
child->updateTransform();
});
GL::blendFunc( _blendFunc.src, _blendFunc.dst ); GL::blendFunc( _blendFunc.src, _blendFunc.dst );
@ -413,11 +409,11 @@ 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
int quantity = (_textureAtlas->getCapacity() + 1) * 4 / 3; long 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(), _textureAtlas->getCapacity(),
(long)quantity); quantity);
if (! _textureAtlas->resizeCapacity(quantity)) if (! _textureAtlas->resizeCapacity(quantity))
{ {
@ -429,22 +425,17 @@ void SpriteBatchNode::increaseAtlasCapacity(void)
int SpriteBatchNode::rebuildIndexInOrder(Sprite *parent, int index) int SpriteBatchNode::rebuildIndexInOrder(Sprite *parent, int index)
{ {
CCASSERT(index>=0 && index < _children->count(), "Invalid index"); CCASSERT(index>=0 && index < _children.count(), "Invalid index");
Array *children = parent->getChildren(); auto children = parent->getChildren();
if (children && children->count() > 0) children.makeObjectsPerformCallback([this, &index](Node* child){
{ Sprite* sp = static_cast<Sprite*>(child);
Object* object = NULL; if (sp && (sp->getZOrder() < 0))
CCARRAY_FOREACH(children, object)
{ {
Sprite* child = static_cast<Sprite*>(object); index = rebuildIndexInOrder(sp, index);
if (child && (child->getZOrder() < 0))
{
index = rebuildIndexInOrder(child, index);
}
} }
} });
// ignore self (batch node) // ignore self (batch node)
if (! parent->isEqual(this)) if (! parent->isEqual(this))
@ -453,61 +444,56 @@ int SpriteBatchNode::rebuildIndexInOrder(Sprite *parent, int index)
index++; index++;
} }
if (children && children->count() > 0) children.makeObjectsPerformCallback([this, &index](Node* child){
{ Sprite* sp = static_cast<Sprite*>(child);
Object* object = NULL; if (sp && (sp->getZOrder() >= 0))
CCARRAY_FOREACH(children, object)
{ {
Sprite* child = static_cast<Sprite*>(object); index = rebuildIndexInOrder(sp, index);
if (child && (child->getZOrder() >= 0))
{
index = rebuildIndexInOrder(child, index);
}
} }
} });
return index; return index;
} }
int SpriteBatchNode::highestAtlasIndexInChild(Sprite *sprite) int SpriteBatchNode::highestAtlasIndexInChild(Sprite *sprite)
{ {
Array *children = sprite->getChildren(); auto children = sprite->getChildren();
if (! children || children->count() == 0) if (children.count() == 0)
{ {
return sprite->getAtlasIndex(); return sprite->getAtlasIndex();
} }
else else
{ {
return highestAtlasIndexInChild( static_cast<Sprite*>(children->getLastObject())); return highestAtlasIndexInChild( static_cast<Sprite*>(children.getLastObject()));
} }
} }
int SpriteBatchNode::lowestAtlasIndexInChild(Sprite *sprite) int SpriteBatchNode::lowestAtlasIndexInChild(Sprite *sprite)
{ {
Array *children = sprite->getChildren(); auto children = sprite->getChildren();
if (! children || children->count() == 0) if (children.count() == 0)
{ {
return sprite->getAtlasIndex(); return sprite->getAtlasIndex();
} }
else else
{ {
return lowestAtlasIndexInChild(static_cast<Sprite*>(children->getObjectAtIndex(0))); return lowestAtlasIndexInChild(static_cast<Sprite*>(children[0]));
} }
} }
int SpriteBatchNode::atlasIndexForChild(Sprite *sprite, int nZ) int SpriteBatchNode::atlasIndexForChild(Sprite *sprite, int nZ)
{ {
Array *siblings = sprite->getParent()->getChildren(); auto siblings = sprite->getParent()->getChildren();
int childIndex = siblings->getIndexOfObject(sprite); long childIndex = siblings.getIndexOfObject(sprite);
// ignore parent Z if parent is spriteSheet // ignore parent Z if parent is spriteSheet
bool ignoreParent = (SpriteBatchNode*)(sprite->getParent()) == this; bool ignoreParent = (SpriteBatchNode*)(sprite->getParent()) == this;
Sprite *prev = NULL; Sprite *prev = NULL;
if (childIndex > 0 && childIndex != -1) if (childIndex > 0 && childIndex != -1)
{ {
prev = static_cast<Sprite*>(siblings->getObjectAtIndex(childIndex - 1)); prev = static_cast<Sprite*>(siblings[childIndex - 1]);
} }
// first child of the sprite sheet // first child of the sprite sheet
@ -568,7 +554,7 @@ void SpriteBatchNode::appendChild(Sprite* sprite)
} }
_descendants.push_back(sprite); _descendants.push_back(sprite);
int index = _descendants.size()-1; long index = _descendants.size()-1;
sprite->setAtlasIndex(index); sprite->setAtlasIndex(index);
@ -576,13 +562,9 @@ void SpriteBatchNode::appendChild(Sprite* sprite)
_textureAtlas->insertQuad(&quad, index); _textureAtlas->insertQuad(&quad, index);
// add children recursively // add children recursively
sprite->getChildren().makeObjectsPerformCallback([this](Node* child){
Object* obj = nullptr; appendChild(static_cast<Sprite*>(child));
CCARRAY_FOREACH(sprite->getChildren(), obj) });
{
Sprite* child = static_cast<Sprite*>(obj);
appendChild(child);
}
} }
void SpriteBatchNode::removeSpriteFromAtlas(Sprite *sprite) void SpriteBatchNode::removeSpriteFromAtlas(Sprite *sprite)
@ -606,19 +588,14 @@ void SpriteBatchNode::removeSpriteFromAtlas(Sprite *sprite)
} }
// remove children recursively // remove children recursively
Array *children = sprite->getChildren(); auto children = sprite->getChildren();
if (children && children->count() > 0) children.makeObjectsPerformCallback([this](Node* obj){
{ Sprite* child = static_cast<Sprite*>(obj);
Object* object = NULL; if (child)
CCARRAY_FOREACH(children, object)
{ {
Sprite* child = static_cast<Sprite*>(object); removeSpriteFromAtlas(child);
if (child)
{
removeSpriteFromAtlas(child);
}
} }
} });
} }
void SpriteBatchNode::updateBlendFunc(void) void SpriteBatchNode::updateBlendFunc(void)

View File

@ -390,22 +390,19 @@ Sprite * TMXLayer::insertTileForGID(unsigned int gid, const Point& pos)
ccCArrayInsertValueAtIndex(_atlasIndexArray, (void*)z, indexForZ); ccCArrayInsertValueAtIndex(_atlasIndexArray, (void*)z, indexForZ);
// update possible children // update possible children
if (_children && _children->count()>0)
{ _children.makeObjectsPerformCallback([&indexForZ](Node* child){
Object* pObject = nullptr; Sprite* sp = static_cast<Sprite*>(child);
CCARRAY_FOREACH(_children, pObject) if (child)
{ {
Sprite* child = static_cast<Sprite*>(pObject); unsigned int ai = sp->getAtlasIndex();
if (child) if ( ai >= indexForZ )
{ {
unsigned int ai = child->getAtlasIndex(); sp->setAtlasIndex(ai+1);
if ( ai >= indexForZ )
{
child->setAtlasIndex(ai+1);
}
} }
} }
} });
_tiles[z] = gid; _tiles[z] = gid;
return tile; return tile;
} }
@ -558,7 +555,7 @@ void TMXLayer::removeChild(Node* node, bool cleanup)
return; return;
} }
CCASSERT(_children->containsObject(sprite), "Tile does not belong to TMXLayer"); CCASSERT(_children.containsObject(sprite), "Tile does not belong to TMXLayer");
unsigned int atlasIndex = sprite->getAtlasIndex(); unsigned int atlasIndex = sprite->getAtlasIndex();
unsigned int zz = (size_t)_atlasIndexArray->arr[atlasIndex]; unsigned int zz = (size_t)_atlasIndexArray->arr[atlasIndex];
@ -596,22 +593,17 @@ void TMXLayer::removeTileAt(const Point& pos)
_textureAtlas->removeQuadAtIndex(atlasIndex); _textureAtlas->removeQuadAtIndex(atlasIndex);
// update possible children // update possible children
if (_children && _children->count()>0) _children.makeObjectsPerformCallback([&atlasIndex](Node* obj){
{ Sprite* child = static_cast<Sprite*>(obj);
Object* pObject = nullptr; if (child)
CCARRAY_FOREACH(_children, pObject)
{ {
Sprite* child = static_cast<Sprite*>(pObject); unsigned int ai = child->getAtlasIndex();
if (child) if ( ai >= atlasIndex )
{ {
unsigned int ai = child->getAtlasIndex(); child->setAtlasIndex(ai-1);
if ( ai >= atlasIndex )
{
child->setAtlasIndex(ai-1);
}
} }
} }
} });
} }
} }
} }

View File

@ -210,10 +210,10 @@ void TMXTiledMap::buildWithMapInfo(TMXMapInfo* mapInfo)
TMXLayer * TMXTiledMap::getLayer(const std::string& layerName) const TMXLayer * TMXTiledMap::getLayer(const std::string& layerName) const
{ {
CCASSERT(layerName.size() > 0, "Invalid layer name!"); CCASSERT(layerName.size() > 0, "Invalid layer name!");
Object* pObj = NULL;
CCARRAY_FOREACH(_children, pObj) for (auto& child : _children)
{ {
TMXLayer* layer = dynamic_cast<TMXLayer*>(pObj); TMXLayer* layer = dynamic_cast<TMXLayer*>(child);
if(layer) if(layer)
{ {
if(layerName.compare( layer->getLayerName()) == 0) if(layerName.compare( layer->getLayerName()) == 0)
@ -224,7 +224,7 @@ TMXLayer * TMXTiledMap::getLayer(const std::string& layerName) const
} }
// layer not found // layer not found
return NULL; return nullptr;
} }
TMXObjectGroup * TMXTiledMap::getObjectGroup(const std::string& groupName) const TMXObjectGroup * TMXTiledMap::getObjectGroup(const std::string& groupName) const

View File

@ -35,11 +35,14 @@ template<class T>
class CC_DLL Vector class CC_DLL Vector
{ {
public: public:
static const long DEFAULT_CAPACTIY = 7;
/** creates an emptry Vector */ /** creates an emptry Vector */
Vector<T>(long capacity=7) explicit Vector<T>(long capacity=DEFAULT_CAPACTIY)
: _data() : _data()
{ {
CCLOG("In the constructor of Vector."); CCLOG("In the default constructor of Vector.");
init(capacity); init(capacity);
} }
@ -54,13 +57,27 @@ public:
copy(other); copy(other);
} }
const Vector<T>& operator=(const Vector<T>& other) /** Move constructor */
Vector<T>(Vector<T>&& other)
{ {
CCLOG("In the assignment operator!"); CCLOG("In the move constructor of Vector!");
_data = std::move(other._data);
}
Vector<T>& operator=(const Vector<T>& other)
{
CCLOG("In the copy assignment operator!");
copy(other); copy(other);
return *this; return *this;
} }
Vector<T>& operator=(Vector<T>&& other)
{
CCLOG("In the move assignment operator!");
_data = std::move(other._data);
return *this;
}
T operator[](long index) const T operator[](long index) const
{ {
return getObjectAtIndex(index); return getObjectAtIndex(index);
@ -171,7 +188,8 @@ public:
/** Insert a certain object at a certain index */ /** Insert a certain object at a certain index */
void insertObject(T object, long index) void insertObject(T object, long index)
{ {
_data.insert( std::next( std::begin(_data, index), object ) ); CCASSERT(index >= 0 && index < count(), "Invalid index!");
_data.insert((std::begin(_data) + index), object);
object->retain(); object->retain();
} }
@ -220,6 +238,7 @@ public:
(*it)->release(); (*it)->release();
} }
_data.clear(); _data.clear();
_data.reserve(DEFAULT_CAPACTIY);
} }
/** Fast way to remove a certain object */ /** Fast way to remove a certain object */
@ -275,6 +294,16 @@ public:
{ {
_data.shrink_to_fit(); _data.shrink_to_fit();
} }
void makeObjectsPerformCallback(std::function<void(T)> callback)
{
if (count() <= 0)
return;
std::for_each(_data.begin(), _data.end(), [&callback](T obj){
callback(obj);
});
}
// ------------------------------------------ // ------------------------------------------
// Iterators // Iterators
@ -282,18 +311,26 @@ public:
typedef typename std::vector<T>::iterator iterator; typedef typename std::vector<T>::iterator iterator;
typedef typename std::vector<T>::const_iterator const_iterator; typedef typename std::vector<T>::const_iterator const_iterator;
typedef typename std::vector<T>::reverse_iterator reverse_iterator;
typedef typename std::vector<T>::const_reverse_iterator const_reverse_iterator;
iterator begin() { return _data.begin(); } iterator begin() { return _data.begin(); }
const_iterator begin() const { return _data.begin(); } const_iterator begin() const { return _data.begin(); }
iterator end() { return _data.end(); } iterator end() { return _data.end(); }
const_iterator end() const { return _data.end(); } const_iterator end() const { return _data.end(); }
iterator cbegin() { return _data.cbegin(); }
const_iterator cbegin() const { return _data.cbegin(); } const_iterator cbegin() const { return _data.cbegin(); }
iterator cend() { return _data.cend(); }
const_iterator cend() const { return _data.cend(); } const_iterator cend() const { return _data.cend(); }
reverse_iterator rbegin() { return _data.rbegin(); }
const_reverse_iterator rbegin() const { return _data.rbegin(); }
reverse_iterator rend() { return _data.rend(); }
const_reverse_iterator rend() const { return _data.rend(); }
const_reverse_iterator rcbegin() const { return _data.crbegin(); }
const_reverse_iterator rcend() const { return _data.crend(); }
protected: protected:
std::vector<T> _data; std::vector<T> _data;

View File

@ -324,15 +324,13 @@ Scene* CCBReader::createSceneWithNodeGraphFromFile(const char *pCCBFileName, Obj
return pScene; return pScene;
} }
void CCBReader::cleanUpNodeGraph(Node *pNode) void CCBReader::cleanUpNodeGraph(Node *node)
{ {
pNode->setUserObject(NULL); node->setUserObject(nullptr);
Object *pChild = NULL; node->getChildren().makeObjectsPerformCallback([this](Node* obj){
CCARRAY_FOREACH(pNode->getChildren(), pChild) cleanUpNodeGraph(obj);
{ });
cleanUpNodeGraph(static_cast<Node*>(pChild));
}
} }
Node* CCBReader::readFileWithCleanUp(bool bCleanUp, Dictionary* am) Node* CCBReader::readFileWithCleanUp(bool bCleanUp, Dictionary* am)

View File

@ -312,7 +312,7 @@ void Armature::changeBoneParent(Bone *bone, const char *parentName)
if(bone->getParentBone()) if(bone->getParentBone())
{ {
bone->getParentBone()->getChildren()->removeObject(bone); bone->getParentBone()->getChildren().removeObject(bone);
bone->setParentBone(nullptr); bone->setParentBone(nullptr);
} }
@ -467,7 +467,7 @@ void Armature::draw()
GL::blendFunc(_blendFunc.src, _blendFunc.dst); GL::blendFunc(_blendFunc.src, _blendFunc.dst);
} }
for (auto object : *_children) for (auto object : _children)
{ {
if (Bone *bone = dynamic_cast<Bone *>(object)) if (Bone *bone = dynamic_cast<Bone *>(object))
{ {
@ -640,7 +640,7 @@ Rect Armature::getBoundingBox() const
Rect boundingBox = Rect(0, 0, 0, 0); Rect boundingBox = Rect(0, 0, 0, 0);
for(auto object : *_children) for(auto object : _children)
{ {
if (Bone *bone = dynamic_cast<Bone *>(object)) if (Bone *bone = dynamic_cast<Bone *>(object))
{ {
@ -672,12 +672,12 @@ Rect Armature::getBoundingBox() const
Bone *Armature::getBoneAtPoint(float x, float y) const Bone *Armature::getBoneAtPoint(float x, float y) const
{ {
int length = _children->count(); long length = _children.count();
Bone *bs; Bone *bs;
for(int i = length - 1; i >= 0; i--) for(long i = length - 1; i >= 0; i--)
{ {
bs = static_cast<Bone*>( _children->getObjectAtIndex(i) ); bs = static_cast<Bone*>( _children[i] );
if(bs->getDisplayManager()->containPoint(x, y)) if(bs->getDisplayManager()->containPoint(x, y))
{ {
return bs; return bs;
@ -797,7 +797,7 @@ void Armature::setBody(cpBody *body)
_body = body; _body = body;
_body->data = this; _body->data = this;
for(auto object: *_children) for(auto object: _children)
{ {
if (Bone *bone = dynamic_cast<Bone *>(object)) if (Bone *bone = dynamic_cast<Bone *>(object))
{ {

View File

@ -163,14 +163,14 @@ void BatchNode::visit()
void BatchNode::draw() void BatchNode::draw()
{ {
if (_children == nullptr) if (_children.count() == 0)
{ {
return; return;
} }
CC_NODE_DRAW_SETUP(); CC_NODE_DRAW_SETUP();
for(auto object : *_children) for(auto object : _children)
{ {
Armature *armature = dynamic_cast<Armature *>(object); Armature *armature = dynamic_cast<Armature *>(object);
if (armature) if (armature)

View File

@ -69,7 +69,6 @@ Bone::Bone()
_boneData = nullptr; _boneData = nullptr;
_tween = nullptr; _tween = nullptr;
_tween = nullptr; _tween = nullptr;
_children = nullptr;
_displayManager = nullptr; _displayManager = nullptr;
_ignoreMovementBoneData = false; _ignoreMovementBoneData = false;
_worldTransform = AffineTransformMake(1, 0, 0, 1, 0, 0); _worldTransform = AffineTransformMake(1, 0, 0, 1, 0, 0);
@ -85,7 +84,6 @@ Bone::Bone()
Bone::~Bone(void) Bone::~Bone(void)
{ {
CC_SAFE_DELETE(_tweenData); CC_SAFE_DELETE(_tweenData);
CC_SAFE_DELETE(_children);
CC_SAFE_DELETE(_tween); CC_SAFE_DELETE(_tween);
CC_SAFE_DELETE(_displayManager); CC_SAFE_DELETE(_displayManager);
CC_SAFE_DELETE(_worldInfo); CC_SAFE_DELETE(_worldInfo);
@ -229,14 +227,10 @@ void Bone::update(float delta)
DisplayFactory::updateDisplay(this, delta, _boneTransformDirty || _armature->getArmatureTransformDirty()); DisplayFactory::updateDisplay(this, delta, _boneTransformDirty || _armature->getArmatureTransformDirty());
if (_children) _children.makeObjectsPerformCallback([&delta](Node* obj){
{ Bone *childBone = static_cast<Bone*>(obj);
for(auto object : *_children) childBone->update(delta);
{ });
Bone *childBone = (Bone *)object;
childBone->update(delta);
}
}
_boneTransformDirty = false; _boneTransformDirty = false;
} }
@ -309,30 +303,29 @@ void Bone::addChildBone(Bone *child)
CCASSERT( nullptr != child, "Argument must be non-nil"); CCASSERT( nullptr != child, "Argument must be non-nil");
CCASSERT( nullptr == child->_parentBone, "child already added. It can't be added again"); CCASSERT( nullptr == child->_parentBone, "child already added. It can't be added again");
if(!_children) if(_children.count() == 0)
{ {
_children = Array::createWithCapacity(4); _children.init(4);
_children->retain();
} }
if (_children->getIndexOfObject(child) == CC_INVALID_INDEX) if (_children.getIndexOfObject(child) == CC_INVALID_INDEX)
{ {
_children->addObject(child); _children.addObject(child);
child->setParentBone(this); child->setParentBone(this);
} }
} }
void Bone::removeChildBone(Bone *bone, bool recursion) void Bone::removeChildBone(Bone *bone, bool recursion)
{ {
if (_children && _children->getIndexOfObject(bone) != CC_INVALID_INDEX ) if (_children.count() > 0 && _children.getIndexOfObject(bone) != CC_INVALID_INDEX )
{ {
if(recursion) if(recursion)
{ {
Array *ccbones = bone->_children; auto ccbones = bone->_children;
for(auto object : *ccbones) for(auto& object : ccbones)
{ {
Bone *ccBone = (Bone *)object; Bone *ccBone = static_cast<Bone*>(object);
bone->removeChildBone(ccBone, recursion); bone->removeChildBone(ccBone, recursion);
} }
} }
@ -341,7 +334,7 @@ void Bone::removeChildBone(Bone *bone, bool recursion)
bone->getDisplayManager()->setCurrentDecorativeDisplay(nullptr); bone->getDisplayManager()->setCurrentDecorativeDisplay(nullptr);
_children->removeObject(bone); _children.removeObject(bone);
} }
} }