[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
This commit is contained in:
halx99 2017-09-25 09:27:33 +08:00 committed by minggo
parent b633260020
commit e5d19429b8
3 changed files with 53 additions and 18 deletions

View File

@ -56,7 +56,7 @@ THE SOFTWARE.
NS_CC_BEGIN 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. // 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; int Node::__attachedNodeCount = 0;
// MARK: Constructor, Destructor, Init // MARK: Constructor, Destructor, Init
@ -83,8 +83,7 @@ Node::Node()
, _transformUpdated(true) , _transformUpdated(true)
// children (lazy allocs) // children (lazy allocs)
// lazy alloc // lazy alloc
, _localZOrderAndArrival(0) , _localZOrder$Arrival(0LL)
, _localZOrder(0)
, _globalZOrder(0) , _globalZOrder(0)
, _parent(nullptr) , _parent(nullptr)
// "whole screen" objects. like Scenes and Layers, should set _ignoreAnchorPointForPosition to true // "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; _transformUpdated = _transformDirty = _inverseDirty = true;
} }
void Node::setLocalZOrder(int z) void Node::setLocalZOrder(std::int32_t z)
{ {
if (getLocalZOrder() == z) if (getLocalZOrder() == z)
return; return;
@ -275,15 +274,14 @@ void Node::setLocalZOrder(int z)
/// zOrder setter : private method /// zOrder setter : private method
/// used internally to alter the zOrder variable. DON'T call this method manually /// 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<std::int64_t>(z) << 32) | (_localZOrderAndArrival & 0xffffffff);
_localZOrder = z; _localZOrder = z;
} }
void Node::updateOrderOfArrival() void Node::updateOrderOfArrival()
{ {
_localZOrderAndArrival = (_localZOrderAndArrival & 0xffffffff00000000) | (++s_globalOrderOfArrival); _orderOfArrival = (++s_globalOrderOfArrival);
} }
void Node::setGlobalZOrder(float globalZOrder) void Node::setGlobalZOrder(float globalZOrder)

View File

@ -163,15 +163,15 @@ public:
* *
* @param localZOrder The local Z order value. * @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. Helper function used by `setLocalZOrder`. Don't use it unless you know what you are doing.
@js NA @js NA
*/ */
virtual void _setLocalZOrder(int z); virtual void _setLocalZOrder(std::int32_t z);
/** !!! ONLY FOR INTERNAL USE /** !!! ONLY FOR INTERNAL USE
* Sets the arrival order when this node has a same ZOrder with other children. * 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. * @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. Defines the order in which the nodes are renderer.
@ -947,11 +947,11 @@ public:
static_assert(std::is_base_of<Node, _T>::value, "Node::sortNodes: Only accept derived of Node!"); static_assert(std::is_base_of<Node, _T>::value, "Node::sortNodes: Only accept derived of Node!");
#if CC_64BITS #if CC_64BITS
std::sort(std::begin(nodes), std::end(nodes), [](_T* n1, _T* n2) { 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 #else
std::stable_sort(std::begin(nodes), std::end(nodes), [](_T* n1, _T* n2) { std::sort(std::begin(nodes), std::end(nodes), [](_T* n1, _T* n2) {
return n1->_localZOrder < n2->_localZOrder; return (n1->_localZOrder == n2->_localZOrder && n1->_orderOfArrival < n2->_orderOfArrival) || n1->_localZOrder < n2->_localZOrder;
}); });
#endif #endif
} }
@ -1940,12 +1940,27 @@ protected:
mutable bool _additionalTransformDirty; ///< transform dirty ? mutable bool _additionalTransformDirty; ///< transform dirty ?
bool _transformUpdated; ///< Whether or not the Transform object was updated since the last frame bool _transformUpdated; ///< Whether or not the Transform object was updated since the last frame
std::int64_t _localZOrderAndArrival; /// cache, for 64bits compress optimize. #if CC_LITTLE_ENDIAN
int _localZOrder; /// < Local order (relative to its siblings) used to sort the node 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 float _globalZOrder; ///< Global order used to sort the node
static unsigned int s_globalOrderOfArrival; static std::uint32_t s_globalOrderOfArrival;
Vector<Node*> _children; ///< array of children nodes Vector<Node*> _children; ///< array of children nodes
Node *_parent; ///< weak reference to parent node Node *_parent; ///< weak reference to parent node

View File

@ -281,6 +281,28 @@ CC_ASSERT(__gl_error_code == GL_NO_ERROR, "Error"); \
#define CC_64BITS 0 #define CC_64BITS 0
#endif #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 <sys/param.h>
#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 /** @def CC_INCREMENT_GL_DRAWS_BY_ONE
Increments the GL Draws counts by one. Increments the GL Draws counts by one.