Cocos2d-x C++ Node 使用LocalZOrder$Arrival更高效的排序

文章目录

  • 源码
  • 原理
  • 宏定义
    • CC_LITTLE_ENDIAN
    • CC_64BITS

源码

在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

引用_localZOrder$Arrival的地方只有一处:

template<typename _T> inline
static void sortNodes(cocos2d::Vector<_T*>& nodes)
{
    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) {
        //这里直接使用_localZOrder$Arrival排序,而没有先判断_localZOrder再判断_orderOfArrival
        return (n1->_localZOrder$Arrival < n2->_localZOrder$Arrival);
    });
#else
    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
}

原理

相对于_localZOrder$Arrival变量来说,_localZOrder存储的位置在高位,_orderOfArrival存储的位置在低位,因此当某节点的_localZOrder大于另一节点时,_localZOrder$Arrival的值也必定大于另一节点;当_localZOrder的值相等时,再用低位_orderOfArrival比较。

假设_localZOrder$Arrival占8位,_localZOrder占前4位,_orderOfArrival占后4位:

_localZOrder$Arrival:0000 0000

此时若node1的_localZOrder为0001,_orderOfArrival为1111,则node1的_localZOrder$Arrival值为31,node2的_localZOrder为0010,_orderOfArrival为0000,node2的_localZOrder$Arrival值为32,即_orderOfArrival再大,也无法影响_localZOrder的大小比较。使用_localZOrder$Arrival比较时,比较顺序始终是先比较_localZOrder,相等再比较_orderOfArrival,但此时只需进行一次取数与一次逻辑运算,略微提升了性能。

宏定义

CC_LITTLE_ENDIAN

在不同的操作系统中,数据存储在内存中的高位不一定相同(具体参考大小端模式),通过判断是否为小端(little endian)模式来确保优先按照_localZOrder比较。

CC_64BITS

只在64位系统运行时使用_localZOrder$Arrival比较,原因未知,求解答。

你可能感兴趣的:(cocos2d-x,c++,cocos2dx,Cocos2d-x,C++)