add EnumChildNodesByName, walk node tree with callback

This commit is contained in:
heliclei 2014-03-11 13:58:43 +08:00
parent 5e7f2dee8f
commit 8db680b9ee
4 changed files with 106 additions and 5 deletions

View File

@ -715,7 +715,6 @@ Node* Node::getChildByTag(int tag)
Node* Node::getChildByName(const std::string& name)
{
for (auto& child : _children)
{
@ -733,6 +732,25 @@ Node* Node::getChildByName(const std::string& name)
return nullptr;
}
void Node::EnumChildNodesByName(const std::string& name, std::function<void(Node* node, bool* stop)> callback)
{
for (auto& child : _children)
{
if(child->_name == name)
{
bool stop = false;
callback(child, &stop);
if(stop == true)
{
return;
}
}
child->EnumChildNodesByName(name, callback);
}
return;
}
/* "add" logic MUST only be on this method
* If a class want's to extend the 'addChild' behavior it only needs
* to override this method

View File

@ -789,17 +789,25 @@ public:
player = parent->getChildByName("player")
@endcode
*
* @return A C string that identifies the node.
* @return A string that identifies the node.
*/
virtual std::string& getName();
/**
* Changes the string TAG that is used to identify the node easily.
* Changes the name that is used to identify the node easily.
*
* Please refer to getLabel for the sample code.
* Please refer to getName for the sample code.
*
* @param name A string that indentifies the node.
*/
virtual void setName(const std::string& name);
/**
* Search the children to perform processing for nodes which share a name.
* @param name the name to search for
* @param callback, A callback to execute on nodes that match the name parameter. The callback takes the following arguments:
* node: A node that matches the name.
* stop: A pointer to a Boolean variable. Your callback can set this to YES to terminate the enumeration.
*/
virtual void EnumChildNodesByName(const std::string& name, std::function<void(Node* node, bool* stop)> callback);
/**
* Returns a custom user data pointer
*

View File

@ -57,6 +57,7 @@ static std::function<Layer*()> createFunctions[] =
CL(Test4),
CL(Test5),
CL(Test6),
CL(NodeEnumChildByNameTest),
CL(StressTest1),
CL(StressTest2),
CL(NodeToWorld),
@ -108,7 +109,7 @@ TestCocosNodeDemo::~TestCocosNodeDemo(void)
std::string TestCocosNodeDemo::title() const
{
return "No title";
return "Node Test";
}
std::string TestCocosNodeDemo::subtitle() const
@ -352,6 +353,70 @@ std::string Test6::subtitle() const
return "remove/cleanup with children";
}
//------------------------------------------------------------------
//
// NodeEnumChildByNameTest
//
//------------------------------------------------------------------
void NodeEnumChildByNameTest::onEnter()
{
TestCocosNodeDemo::onEnter();
auto sp10 = Sprite::create(s_pathSister1);
auto sp11 = Sprite::create(s_pathSister1);
auto sp12 = Sprite::create(s_pathSister1);
auto sp20 = Sprite::create(s_pathSister2);
auto sp21 = Sprite::create(s_pathSister2);
auto sp22 = Sprite::create(s_pathSister2);
sp10->setPosition(Point(100,60));
sp11->setPosition(Point(100,160));
sp12->setPosition(Point(100,260));
sp20->setPosition(Point(380,60));
sp21->setPosition(Point(380,160));
sp22->setPosition(Point(380,260));
sp10->setName("sister1");
sp11->setName("sister1");
sp12->setName("sister1");
sp20->setName("sister2");
sp21->setName("sister2");
sp22->setName("sister2");
addChild(sp10);
addChild(sp11);
addChild(sp12);
addChild(sp20);
addChild(sp21);
addChild(sp22);
auto fn1 = std::bind(&NodeEnumChildByNameTest::runAction1, this, std::placeholders::_1, std::placeholders::_2);
auto fn2 = std::bind(&NodeEnumChildByNameTest::runAction2, this, std::placeholders::_1, std::placeholders::_2);
EnumChildNodesByName("sister1", fn1);
EnumChildNodesByName("sister2", fn2);
}
void NodeEnumChildByNameTest::runAction1(Node* node, bool* stop)
{
auto rot = RotateBy::create(2, 360);
auto rot_back = rot->reverse();
auto forever1 = RepeatForever::create(Sequence::create(rot, rot_back, NULL));
node->runAction(forever1);
}
void NodeEnumChildByNameTest::runAction2(Node* node, bool* stop)
{
auto actionUp = JumpBy::create(2, Point(0,0), 80, 4);
auto forever2 = RepeatForever::create(Sequence::create(actionUp, NULL));
node->runAction(forever2);
}
std::string NodeEnumChildByNameTest::subtitle() const
{
return "Enum child nodes by name";
}
//------------------------------------------------------------------
//
// StressTest1

View File

@ -263,6 +263,16 @@ protected:
Sprite *_sprite;
};
class NodeEnumChildByNameTest : public TestCocosNodeDemo
{
public:
CREATE_FUNC(NodeEnumChildByNameTest);
virtual void onEnter() override;
virtual std::string subtitle() const override;
void runAction1(Node* node, bool* stop);
void runAction2(Node* node, bool* stop);
};
class CocosNodeTestScene : public TestScene
{
public: