removeFromParent 和 addChild 和引用计数的关系

来源:互联网 发布:java高并发技术 编辑:程序博客网 时间:2024/06/05 01:07

//removeFromParent

void Node::removeFromParent()

{

    this->removeFromParentAndCleanup(true);

}


void Node::removeFromParentAndCleanup(bool cleanup)

{

    if (_parent !=nullptr)

    {

        _parent->removeChild(this,cleanup);

    } 

}


/* "remove" logic MUST only be on this method

* If a class want's to extend the 'removeChild' behavior it only needs

* to override this method

*/

void Node::removeChild(Node* child,bool cleanup /* = true */)

{

    // explicit nil handling

    if (_children.empty())

    {

        return;

    }


    ssize_t index =_children.getIndex(child);

    if( index !=CC_INVALID_INDEX )

        this->detachChild( child, index, cleanup );

}


void Node::detachChild(Node *child,ssize_t childIndex, bool doCleanup)

{

    // IMPORTANT:

    //  -1st do onExit

    //  -2nd cleanup

    if (_running)

    {

        child->onExitTransitionDidStart();

        child->onExit();

    }

    

#if CC_USE_PHYSICS

    child->removeFromPhysicsWorld();

#endif


    // If you don't do cleanup, the child's actions will not get removed and the

    // its scheduledSelectors_ dict will not get released!

    if (doCleanup)

    {

        child->cleanup();

    }


    // set parent nil at the end

    child->setParent(nullptr);


    _children.erase(childIndex);

}


iterator erase(ssize_t index)

{

    CCASSERT(!_data.empty() && index >=0 && index <size(), "Invalid index!");

    auto it =std::next( begin(), index );

    (*it)->release();  //引用计数-1

    return_data.erase(it);

}


//addChild

void Node::addChild(Node *child)

{

    CCASSERT( child !=nullptr, "Argument must be non-nil");

    this->addChild(child, child->_localZOrder, child->_name);

}


void Node::addChild(Node* child,int localZOrder, const std::string &name)

{

    CCASSERT(child !=nullptr, "Argument must be non-nil");

    CCASSERT(child->_parent ==nullptr, "child already added. It can't be added again");

    

    addChildHelper(child, localZOrder,INVALID_TAG, name, false);

}


void Node::addChildHelper(Node* child,int localZOrder, int tag, conststd::string &name,bool setTag)

{

    if (_children.empty())

    {

        this->childrenAlloc();

    }

    

    this->insertChild(child, localZOrder);

    

    if (setTag)

        child->setTag(tag);

    else

        child->setName(name);

    

    child->setParent(this);

    child->setOrderOfArrival(s_globalOrderOfArrival++);

    

#if CC_USE_PHYSICS

    _physicsBodyAssociatedWith += child->_physicsBodyAssociatedWith;

    auto parentNode =this;

    while (parentNode->_parent)

    {

        parentNode = parentNode->_parent;

        parentNode->_physicsBodyAssociatedWith += child->_physicsBodyAssociatedWith;

    }


    auto scene =dynamic_cast<Scene*>(parentNode);


    // Recursive add children with which have physics body.

    if (scene && scene->getPhysicsWorld())

    {

        scene->addChildToPhysicsWorld(child);

    }

#endif

    

    if( _running )

    {

        child->onEnter();

        // prevent onEnterTransitionDidFinish to be called twice when a node is added in onEnter

        if (_isTransitionFinished)

        {

            child->onEnterTransitionDidFinish();

        }

    }

    

    if (_cascadeColorEnabled)

    {

        updateCascadeColor();

    }

    

    if (_cascadeOpacityEnabled)

    {

        updateCascadeOpacity();

    }

}


void Node::insertChild(Node* child,int z)

{

    _transformUpdated =true;

    _reorderChildDirty =true;

    _children.pushBack(child);

    child->_localZOrder = z;

}


void pushBack(T object)

{

     CCASSERT(object !=nullptr, "The object should not be nullptr");

     _data.push_back( object );

     object->retain(); //引用计数+1

}




















0 0
原创粉丝点击