[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
// 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<std::int64_t>(z) << 32) | (_localZOrderAndArrival & 0xffffffff);
_localZOrder = z;
}
void Node::updateOrderOfArrival()
{
_localZOrderAndArrival = (_localZOrderAndArrival & 0xffffffff00000000) | (++s_globalOrderOfArrival);
_orderOfArrival = (++s_globalOrderOfArrival);
}
void Node::setGlobalZOrder(float globalZOrder)

View File

@ -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<Node, _T>::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<Node*> _children; ///< array of children nodes
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
#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
Increments the GL Draws counts by one.