diff --git a/cocos/2d/CCNode.cpp b/cocos/2d/CCNode.cpp index 3943c6096c..b31d4b916f 100644 --- a/cocos/2d/CCNode.cpp +++ b/cocos/2d/CCNode.cpp @@ -57,17 +57,9 @@ NS_CC_BEGIN bool nodeComparisonLess(Node* n1, Node* n2) { -#if defined(_M_X64) || defined(_LP64) || defined(__x86_64) || defined(_WIN64) - return (n1->_localZOrder.value < n2->_localZOrder.value); -#else - return n1->_localZOrder.detail.z < n2->_localZOrder.detail.z || - (n1->_localZOrder.detail.z == n2->_localZOrder.detail.z && n1->_localZOrder.detail.a < n2->_localZOrder.detail.a); -#endif + return( n1->getLocalZOrder() < n2->getLocalZOrder() ); } -// FIXME:: Yes, nodes might have a sort problem once every 30 days if the game runs at 60 FPS and each frame sprites are reordered. -unsigned int Node::s_globalOrderOfArrival = 0; - // MARK: Constructor, Destructor, Init Node::Node() @@ -92,6 +84,7 @@ Node::Node() , _transformUpdated(true) // children (lazy allocs) // lazy alloc +, _localZOrder(0) , _globalZOrder(0) , _parent(nullptr) // "whole screen" objects. like Scenes and Layers, should set _ignoreAnchorPointForPosition to true @@ -122,8 +115,6 @@ Node::Node() , _physicsBody(nullptr) #endif { - _localZOrder.value = 0; - // set default scheduler and actionManager _director = Director::getInstance(); _actionManager = _director->getActionManager(); @@ -263,10 +254,10 @@ void Node::setSkewY(float skewY) void Node::setLocalZOrder(int z) { - if (getLocalZOrder() == z) + if (_localZOrder == z) return; - _setLocalZOrder(z); + _localZOrder = z; if (_parent) { _parent->reorderChild(this, z); @@ -279,12 +270,7 @@ void Node::setLocalZOrder(int z) /// used internally to alter the zOrder variable. DON'T call this method manually void Node::_setLocalZOrder(int z) { - _localZOrder.detail.z = z; -} - -void Node::updateOrderOfArrival() -{ - _localZOrder.detail.a = s_globalOrderOfArrival++; + _localZOrder = z; } void Node::setGlobalZOrder(float globalZOrder) @@ -964,8 +950,6 @@ void Node::addChildHelper(Node* child, int localZOrder, int tag, const std::stri child->setParent(this); child->setCameraMask(getCameraMask()); - child->updateOrderOfArrival(); - if( _running ) { child->onEnter(); @@ -996,7 +980,7 @@ void Node::addChild(Node *child, int zOrder) void Node::addChild(Node *child) { CCASSERT( child != nullptr, "Argument must be non-nil"); - this->addChild(child, child->_localZOrder.detail.z, child->_name); + this->addChild(child, child->_localZOrder, child->_name); } void Node::removeFromParent() @@ -1143,22 +1127,21 @@ void Node::insertChild(Node* child, int z) _transformUpdated = true; _reorderChildDirty = true; _children.pushBack(child); - child->_setLocalZOrder(z); + child->_localZOrder = z; } void Node::reorderChild(Node *child, int zOrder) { CCASSERT( child != nullptr, "Child must be non-nil"); _reorderChildDirty = true; - child->updateOrderOfArrival(); - child->_setLocalZOrder(zOrder); + child->_localZOrder = zOrder; } void Node::sortAllChildren() { if (_reorderChildDirty) { - std::sort(std::begin(_children), std::end(_children), nodeComparisonLess); + std::stable_sort(std::begin(_children), std::end(_children), nodeComparisonLess); _reorderChildDirty = false; } } @@ -1251,7 +1234,7 @@ void Node::visit(Renderer* renderer, const Mat4 &parentTransform, uint32_t paren { auto node = _children.at(i); - if (node && node->_localZOrder.detail.z < 0) + if (node && node->_localZOrder < 0) node->visit(renderer, _modelViewTransform, flags); else break; diff --git a/cocos/2d/CCNode.h b/cocos/2d/CCNode.h index 9ea071b6ba..91d163e1f5 100644 --- a/cocos/2d/CCNode.h +++ b/cocos/2d/CCNode.h @@ -29,7 +29,6 @@ #ifndef __CCNODE_H__ #define __CCNODE_H__ -#include #include "base/ccMacros.h" #include "base/CCVector.h" #include "base/CCProtocols.h" @@ -109,7 +108,6 @@ class EventListener; class CC_DLL Node : public Ref { - friend bool nodeComparisonLess(Node* n1, Node* n2); public: /** Default tag used for all the nodes */ static const int INVALID_TAG = -1; @@ -170,18 +168,6 @@ public: */ CC_DEPRECATED_ATTRIBUTE virtual void _setLocalZOrder(int z); - /** !!! ONLY FOR INTERNAL USE - * Sets the arrival order when this node has a same ZOrder with other children. - * - * A node which called addChild subsequently will take a larger arrival order, - * If two children have the same Z order, the child with larger arrival order will be drawn later. - * - * @warning This method is used internally for localZOrder sorting, don't change this manually - * - * @param orderOfArrival The arrival order. - */ - void updateOrderOfArrival(); - /** * Gets the local Z order of this node. * @@ -189,7 +175,7 @@ public: * * @return The local (relative to its siblings) Z order. */ - virtual int getLocalZOrder() const { return _localZOrder.detail.z; } + virtual int getLocalZOrder() const { return _localZOrder; } CC_DEPRECATED_ATTRIBUTE virtual int getZOrder() const { return getLocalZOrder(); } /** @@ -1895,17 +1881,9 @@ protected: mutable bool _additionalTransformDirty; ///< transform dirty ? bool _transformUpdated; ///< Whether or not the Transform object was updated since the last frame - union { - struct { - std::int32_t z; // The original localZOrder - std::uint32_t a; // Order Of Arrival, for avoid sort problem with unstable_sort algorithm. - } detail; - std::int64_t value; // The value to be used in sort - } _localZOrder; ///< Local order (relative to its siblings) used to sort the node + int _localZOrder; ///< Local order (relative to its siblings) used to sort the node float _globalZOrder; ///< Global order used to sort the node - static unsigned int s_globalOrderOfArrival; - Vector _children; ///< array of children nodes Node *_parent; ///< weak reference to parent node Director* _director; //cached director pointer to improve rendering performance diff --git a/cocos/2d/CCProtectedNode.cpp b/cocos/2d/CCProtectedNode.cpp index 757f92287b..a265ec2456 100644 --- a/cocos/2d/CCProtectedNode.cpp +++ b/cocos/2d/CCProtectedNode.cpp @@ -102,8 +102,6 @@ void ProtectedNode::addProtectedChild(Node *child, int zOrder, int tag) child->setTag(tag); child->setParent(this); - - child->updateOrderOfArrival(); if( _running ) { @@ -254,7 +252,7 @@ void ProtectedNode::insertProtectedChild(cocos2d::Node *child, int z) void ProtectedNode::sortAllProtectedChildren() { if( _reorderProtectedChildDirty ) { - std::sort( std::begin(_protectedChildren), std::end(_protectedChildren), nodeComparisonLess ); + std::stable_sort( std::begin(_protectedChildren), std::end(_protectedChildren), nodeComparisonLess ); _reorderProtectedChildDirty = false; } } @@ -263,7 +261,6 @@ void ProtectedNode::reorderProtectedChild(cocos2d::Node *child, int localZOrder) { CCASSERT( child != nullptr, "Child must be non-nil"); _reorderProtectedChildDirty = true; - child->updateOrderOfArrival(); child->setLocalZOrder(localZOrder); } diff --git a/cocos/editor-support/cocostudio/CCBone.cpp b/cocos/editor-support/cocostudio/CCBone.cpp index d101cd26e8..b971eb4f09 100644 --- a/cocos/editor-support/cocostudio/CCBone.cpp +++ b/cocos/editor-support/cocostudio/CCBone.cpp @@ -143,7 +143,7 @@ void Bone::setBoneData(BoneData *boneData) } _name = _boneData->name; - _setLocalZOrder(_boneData->zOrder); + _localZOrder = _boneData->zOrder; _displayManager->initDisplayList(boneData); } @@ -377,7 +377,7 @@ Tween *Bone::getTween() void Bone::setLocalZOrder(int zOrder) { - if (getLocalZOrder() != zOrder) + if (_localZOrder != zOrder) Node::setLocalZOrder(zOrder); }