Reputation: 16255
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
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
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 CCObject
s.
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
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