diff --git a/cocos/2d/CCNode.cpp b/cocos/2d/CCNode.cpp index 07d28e4455..9a62fad725 100644 --- a/cocos/2d/CCNode.cpp +++ b/cocos/2d/CCNode.cpp @@ -29,6 +29,7 @@ THE SOFTWARE. #include "2d/CCNode.h" #include +#include #include "base/CCDirector.h" #include "base/CCScheduler.h" @@ -122,6 +123,8 @@ Node::Node(void) , _cascadeColorEnabled(false) , _cascadeOpacityEnabled(false) , _usingNormalizedPosition(false) +, _name("") +, _hashOfName(0) { // set default scheduler and actionManager Director *director = Director::getInstance(); @@ -624,6 +627,18 @@ void Node::setTag(int tag) _tag = tag ; } +std::string Node::getName() const +{ + return _name; +} + +void Node::setName(const std::string& name) +{ + _name = name; + std::hash h; + _hashOfName = h(name); +} + /// userData setter void Node::setUserData(void *userData) { @@ -750,6 +765,22 @@ Node* Node::getChildByTag(int tag) const return nullptr; } +Node* Node::getChildByName(const std::string& name) const +{ + CCASSERT(name.size() != 0, "Invilide name"); + + std::hash h; + size_t hash = h(name); + + for (auto& child : _children) + { + // Different strings may have the same hash code, but can use it to compare first for speed + if(child->_hashOfName == hash && child->_name.compare(name) == 0) + return child; + } + return nullptr; +} + /* "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 diff --git a/cocos/2d/CCNode.h b/cocos/2d/CCNode.h index 84d0973693..7a6e52ef75 100644 --- a/cocos/2d/CCNode.h +++ b/cocos/2d/CCNode.h @@ -667,6 +667,16 @@ public: * @return a Node object whose tag equals to the input parameter */ virtual Node * getChildByTag(int tag) const; + /** + * Gets a child from the container with its name + * + * @param name An identifier to find the child node. + * + * @return a Node object whose name equals to the input parameter + * + * @since v3.2 + */ + virtual Node* getChildByName(const std::string& name) const; /** * Returns the array of the node's children * @@ -780,6 +790,19 @@ public: * @param tag A integer that identifies the node. */ virtual void setTag(int tag); + + /** Returns a string that is used to identify the node. + * @return A string that identifies the node. + * + * @since v3.2 + */ + virtual std::string getName() const; + /** Changes the name that is used to identify the node easily. + * @param name A string that identifies the node. + * + * @since v3.2 + */ + virtual void setName(const std::string& name); /** @@ -1443,6 +1466,7 @@ protected: int _tag; ///< a tag. Can be any number you assigned just to identify this node std::string _name; ///getChildByTag(tag); } -Widget* ScrollView::getChildByName(const std::string& name)const +Node* ScrollView::getChildByName(const std::string& name)const { return _innerContainer->getChildByName(name); } diff --git a/cocos/ui/UIScrollView.h b/cocos/ui/UIScrollView.h index a0994af4dc..eb7271825b 100644 --- a/cocos/ui/UIScrollView.h +++ b/cocos/ui/UIScrollView.h @@ -264,7 +264,7 @@ public: virtual const Vector& getChildren() const override; virtual ssize_t getChildrenCount() const override; virtual Node * getChildByTag(int tag) const override; - virtual Widget* getChildByName(const std::string& name)const override; + virtual Node* getChildByName(const std::string& name)const override; //handle touch event virtual bool onTouchBegan(Touch *touch, Event *unusedEvent) override; diff --git a/cocos/ui/UIWidget.cpp b/cocos/ui/UIWidget.cpp index 01139a0836..5a18f10f74 100644 --- a/cocos/ui/UIWidget.cpp +++ b/cocos/ui/UIWidget.cpp @@ -144,7 +144,6 @@ _touchMovePosition(Vec2::ZERO), _touchEndPosition(Vec2::ZERO), _touchEventListener(nullptr), _touchEventSelector(nullptr), -_name("default"), _actionTag(0), _size(Size::ZERO), _customSize(Size::ZERO), @@ -249,25 +248,6 @@ void Widget::setEnabled(bool enabled) { _enabled = enabled; } - -Widget* Widget::getChildByName(const std::string& name)const -{ - for (auto& child : _children) - { - if (child) - { - Widget* widgetChild = dynamic_cast(child); - if (widgetChild) - { - if (widgetChild->getName() == name) - { - return widgetChild; - } - } - } - } - return nullptr; -} void Widget::initRenderer() { @@ -964,17 +944,6 @@ const Vec2& Widget::getTouchEndPosition()const return _touchEndPosition; } -void Widget::setName(const std::string& name) -{ - _name = name; -} - -const std::string& Widget::getName() const -{ - return _name; -} - - void Widget::setLayoutParameter(LayoutParameter *parameter) { if (!parameter) diff --git a/cocos/ui/UIWidget.h b/cocos/ui/UIWidget.h index 437068d613..4d201720b0 100644 --- a/cocos/ui/UIWidget.h +++ b/cocos/ui/UIWidget.h @@ -228,15 +228,6 @@ public: CC_DEPRECATED_ATTRIBUTE float getTopInParent(){return this->getTopBoundary();} float getTopBoundary() const; - /** - * Gets a child from the container with its name - * - * @param name An key to find the child widget. - * - * @return a Widget object whose name equals to the input parameter - */ - virtual Widget* getChildByName(const std::string& name) const; - virtual void visit(cocos2d::Renderer *renderer, const Mat4 &parentTransform, uint32_t parentFlags) override; /** @@ -375,22 +366,6 @@ public: CC_DEPRECATED_ATTRIBUTE const Vec2& getTouchEndPos()const{return this->getTouchEndPosition();} const Vec2& getTouchEndPosition()const; - /** - * Changes the name that is used to identify the widget easily. - * - * @param A const std::string that indentifies the widget. - */ - void setName(const std::string& name); - - /** - * Returns a name that is used to identify the widget easily. - * - * You can set tags to widget then identify them easily. - * - * @return A const std::string that identifies the widget. - */ - const std::string& getName() const; - /** * Changes the size that is widget's size * @@ -682,7 +657,6 @@ protected: PositionType _positionType; //use - std::string _name; int _actionTag; Size _size;