From e5d19429b8254795d206591a728dabcfa3942eda Mon Sep 17 00:00:00 2001 From: halx99 Date: Mon, 25 Sep 2017 09:27:33 +0800 Subject: [PATCH] [ci skip]Make the sort behavior is same on 32bit and 64bit (#18301) * Make the sort behavior is same on 32bit and 64bit * Update CCNode.h * Update CCNode.cpp * Update ccMacros.h * Use std::int32_t to for zOrder * Update CCNode.cpp --- cocos/2d/CCNode.cpp | 12 +++++------- cocos/2d/CCNode.h | 37 ++++++++++++++++++++++++++----------- cocos/base/ccMacros.h | 22 ++++++++++++++++++++++ 3 files changed, 53 insertions(+), 18 deletions(-) diff --git a/cocos/2d/CCNode.cpp b/cocos/2d/CCNode.cpp index 26e92e31ff..eb71155e82 100644 --- a/cocos/2d/CCNode.cpp +++ b/cocos/2d/CCNode.cpp @@ -56,7 +56,7 @@ THE SOFTWARE. NS_CC_BEGIN // 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; +std::uint32_t Node::s_globalOrderOfArrival = 0; int Node::__attachedNodeCount = 0; // MARK: Constructor, Destructor, Init @@ -83,8 +83,7 @@ Node::Node() , _transformUpdated(true) // children (lazy allocs) // lazy alloc -, _localZOrderAndArrival(0) -, _localZOrder(0) +, _localZOrder$Arrival(0LL) , _globalZOrder(0) , _parent(nullptr) // "whole screen" objects. like Scenes and Layers, should set _ignoreAnchorPointForPosition to true @@ -259,7 +258,7 @@ void Node::setSkewY(float skewY) _transformUpdated = _transformDirty = _inverseDirty = true; } -void Node::setLocalZOrder(int z) +void Node::setLocalZOrder(std::int32_t z) { if (getLocalZOrder() == z) return; @@ -275,15 +274,14 @@ void Node::setLocalZOrder(int z) /// zOrder setter : private method /// used internally to alter the zOrder variable. DON'T call this method manually -void Node::_setLocalZOrder(int z) +void Node::_setLocalZOrder(std::int32_t z) { - _localZOrderAndArrival = (static_cast(z) << 32) | (_localZOrderAndArrival & 0xffffffff); _localZOrder = z; } void Node::updateOrderOfArrival() { - _localZOrderAndArrival = (_localZOrderAndArrival & 0xffffffff00000000) | (++s_globalOrderOfArrival); + _orderOfArrival = (++s_globalOrderOfArrival); } void Node::setGlobalZOrder(float globalZOrder) diff --git a/cocos/2d/CCNode.h b/cocos/2d/CCNode.h index 9ab2d57425..86b0f6369f 100644 --- a/cocos/2d/CCNode.h +++ b/cocos/2d/CCNode.h @@ -163,15 +163,15 @@ public: * * @param localZOrder The local Z order value. */ - virtual void setLocalZOrder(int localZOrder); + virtual void setLocalZOrder(std::int32_t localZOrder); - CC_DEPRECATED_ATTRIBUTE virtual void setZOrder(int localZOrder) { setLocalZOrder(localZOrder); } + CC_DEPRECATED_ATTRIBUTE virtual void setZOrder(std::int32_t localZOrder) { setLocalZOrder(localZOrder); } /* Helper function used by `setLocalZOrder`. Don't use it unless you know what you are doing. @js NA */ - virtual void _setLocalZOrder(int z); + virtual void _setLocalZOrder(std::int32_t z); /** !!! ONLY FOR INTERNAL USE * Sets the arrival order when this node has a same ZOrder with other children. @@ -193,9 +193,9 @@ public: * @return The local (relative to its siblings) Z order. */ - virtual int getLocalZOrder() const { return _localZOrder; } + virtual std::int32_t getLocalZOrder() const { return _localZOrder; } - CC_DEPRECATED_ATTRIBUTE virtual int getZOrder() const { return getLocalZOrder(); } + CC_DEPRECATED_ATTRIBUTE virtual std::int32_t getZOrder() const { return getLocalZOrder(); } /** Defines the order in which the nodes are renderer. @@ -947,11 +947,11 @@ public: static_assert(std::is_base_of::value, "Node::sortNodes: Only accept derived of Node!"); #if CC_64BITS std::sort(std::begin(nodes), std::end(nodes), [](_T* n1, _T* n2) { - return (n1->_localZOrderAndArrival < n2->_localZOrderAndArrival); + return (n1->_localZOrder$Arrival < n2->_localZOrder$Arrival); }); #else - std::stable_sort(std::begin(nodes), std::end(nodes), [](_T* n1, _T* n2) { - return n1->_localZOrder < n2->_localZOrder; + std::sort(std::begin(nodes), std::end(nodes), [](_T* n1, _T* n2) { + return (n1->_localZOrder == n2->_localZOrder && n1->_orderOfArrival < n2->_orderOfArrival) || n1->_localZOrder < n2->_localZOrder; }); #endif } @@ -1940,12 +1940,27 @@ protected: mutable bool _additionalTransformDirty; ///< transform dirty ? bool _transformUpdated; ///< Whether or not the Transform object was updated since the last frame - std::int64_t _localZOrderAndArrival; /// cache, for 64bits compress optimize. - int _localZOrder; /// < Local order (relative to its siblings) used to sort the node +#if CC_LITTLE_ENDIAN + union { + struct { + std::uint32_t _orderOfArrival; + std::int32_t _localZOrder; + }; + std::int64_t _localZOrder$Arrival; + }; +#else + union { + struct { + std::int32_t _localZOrder; + std::uint32_t _orderOfArrival; + }; + std::int64_t _localZOrder$Arrival; + }; +#endif float _globalZOrder; ///< Global order used to sort the node - static unsigned int s_globalOrderOfArrival; + static std::uint32_t s_globalOrderOfArrival; Vector _children; ///< array of children nodes Node *_parent; ///< weak reference to parent node diff --git a/cocos/base/ccMacros.h b/cocos/base/ccMacros.h index f48f1e15dd..f7b3cbda2a 100644 --- a/cocos/base/ccMacros.h +++ b/cocos/base/ccMacros.h @@ -281,6 +281,28 @@ CC_ASSERT(__gl_error_code == GL_NO_ERROR, "Error"); \ #define CC_64BITS 0 #endif + /******************************************************************************************/ + /** LittleEndian Sense Macro, from google protobuf see: **/ + /** https://github.com/google/protobuf/blob/master/src/google/protobuf/io/coded_stream.h **/ + /******************************************************************************************/ +#ifdef _MSC_VER + #if defined(_M_IX86) + #define CC_LITTLE_ENDIAN 1 + #else + #define CC_LITTLE_ENDIAN 0 + #endif + #if _MSC_VER >= 1300 && !defined(__INTEL_COMPILER) + #pragma runtime_checks("c", off) + #endif +#else + #include + #if defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN + #define CC_LITTLE_ENDIAN 1 + #else + #define CC_LITTLE_ENDIAN 0 + #endif +#endif + /** @def CC_INCREMENT_GL_DRAWS_BY_ONE Increments the GL Draws counts by one.