Jasmine
Jasmine

Reputation: 16255

What is the C++ equivalent of this Objective-C Cocos2D and CCNode

I am trying to translate some code from Objective-C to C++

I have a CCNode and I want to recursively traverse all the nodes it has.

I cannot figure out how to write this:

 for(CCNode* child in [self children])
 {

 }

Can anyone translate this for me?

Update: this is the code from another SO answer: CCNode recursive getChildByTag

Upvotes: 3

Views: 866

Answers (3)

schmittsfn
schmittsfn

Reputation: 1442

I am presuming you are using the c++ port of Cocos2d-iPhone? If this is the case then you could use Cocos2d-x's macro for iterating over CCArrays.

Example:

CCObject* pObj = nullptr;
CCARRAY_FOREACH(getChildren(), pObj)
{
    // do something
}

Upvotes: 1

Yakk - Adam Nevraumont
Yakk - Adam Nevraumont

Reputation: 275966

In C++11, we have range-based for loops that have a similar syntax.

To do this, you need an iterator-based wrapper.

The easiest way to do this is to use # include <boost/iterator/iterator_facade.hpp>. Wrapping an index-based container in an iterator_facade at begin/end is pretty easy.

If you have written a struct my_iterator:boost::iterator_facade<my_iterator> {...}; type, then just write my_iterator begin( CCArray& ), the const versions, and the end version.

Having done this, you get:

for( CCObject* obj : *getChildren() ) which is close, but uses CCObject instead of CCNode. You happen to know that the children of this are CCNode, but the Cocos2d interface only tells you the children are CCObjects.

I'd write an CCArrayAs<T> adapter function that returns a wrapped CCArray with a type T information. Ie:

template<typename T>
struct CCArrayAs {
  CCArray* arr;
};

which you'll notice does not use the type T anywhere. We once again write iterators, but for the above struct, where the return type instead of being a CCObject* is a T* using static_cast. We then write begin( CCArrayAs& ), end, and const versions, and what we get out of it is:

for( CCNode* node : CCArrayAs<CCNode>(getChildren()) )

which is pretty close to the Objective-C syntax. If you want a prettier syntax, write CCArrayAs<CCNode> GetChildren( CCNode* self ) { return self->getChildren(); }, giving you:

for( CCNode* node : GetChildren(this) )

The downside to this is that it is a lot of boilerplate, all to get a slightly prettier syntax. It is something you'd hope Cocos2d developers would do, rather than having to do yourself.

If you don't want to do all that work, you can simply loop over the indexes. See @RamyAlZuhouri's answer for that solution. It is much, much easier.

Upvotes: 1

Ramy Al Zuhouri
Ramy Al Zuhouri

Reputation: 22006

Since there isn't fast enumeration in C++, you can iterate it through an iterator, or a counter, stopping when the counter reaches the collection size. Then get every object with objectAtIndex():

for(int i = 0; i < getChildren()->count(); i++)
{
    CCNode *child = getChildren()->objectAtIndex(i);
    < Your code >
}

Upvotes: 3

Related Questions