Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

143 lines
3.5 KiB

  1. //========= Copyright � Valve Corporation, All rights reserved. ============//
  2. #ifndef HIERARCHICAL_BIT_VEC_HDR
  3. #define HIERARCHICAL_BIT_VEC_HDR
  4. class CHierarchicalBitVector
  5. {
  6. public:
  7. CHierarchicalBitVector( ){}
  8. CHierarchicalBitVector( int nInitialBitCount )
  9. {
  10. if ( nInitialBitCount > 0 )
  11. {
  12. EnsureBitExists( nInitialBitCount - 1 );
  13. }
  14. }
  15. CHierarchicalBitVector( const CHierarchicalBitVector &other )
  16. {
  17. m_Level0.CopyArray( other.m_Level0.Base( ), other.m_Level0.Count( ) );
  18. m_Level1.CopyArray( other.m_Level1.Base( ), other.m_Level1.Count( ) );
  19. }
  20. void Set( int nBit )
  21. {
  22. m_Level0[ nBit >> 5 ] |= 1 << ( nBit & 31 );
  23. m_Level1[ nBit >> 10 ] |= 1 << ( ( nBit >> 5 ) & 31 );
  24. }
  25. void Reset( int nBit )
  26. {
  27. m_Level0[ nBit >> 5 ] &= ~( 1 << ( nBit & 31 ) );
  28. }
  29. uint32 operator[] ( int nBit ) const
  30. {
  31. uint32 nBitSet = ( m_Level0[ nBit >> 5 ] >> ( nBit & 31 ) ) & 1;
  32. AssertDbg( ( ( m_Level1[ nBit >> 10 ] >> ( ( nBit >> 5 ) & 31 ) ) & 1 ) || !m_Level0[ nBit >> 5 ] );
  33. return nBitSet;
  34. }
  35. const uint32 * Base() const
  36. {
  37. return m_Level0.Base();
  38. }
  39. void Validate()const
  40. {
  41. #ifdef DBGFLAG_ASSERT
  42. for( int i = 0; i < m_Level0.Count(); ++i )
  43. {
  44. uint nLevel0Bits = m_Level0[ i ];
  45. uint nLevel1Bits = m_Level1[ i >> 5 ];
  46. Assert( nLevel1Bits & ( 1 << ( i & 31 ) ) ? nLevel0Bits : !nLevel0Bits );
  47. }
  48. #endif
  49. }
  50. void EnsureBitExists( int nBit ) // reallocate if necessary
  51. {
  52. int nLevel0Size = ( nBit >> 5 ) + 1, nLevel0OldSize = m_Level0.Count();
  53. if( nLevel0OldSize < nLevel0Size )
  54. {
  55. m_Level0.AddMultipleToTail( nLevel0Size - nLevel0OldSize );
  56. for( int i = nLevel0OldSize; i < nLevel0Size; ++i )
  57. {
  58. m_Level0[i] = 0;
  59. }
  60. int nLevel1Size = ( nBit >> 10 ) + 1, nLevel1OldSize = m_Level1.Count();
  61. if( nLevel1OldSize < nLevel1Size )
  62. {
  63. m_Level1.AddMultipleToTail( nLevel1Size - nLevel1OldSize );
  64. for( int i = nLevel1OldSize; i < nLevel1Size; ++i )
  65. {
  66. m_Level1[i] = 0;
  67. }
  68. }
  69. }
  70. }
  71. int Count()
  72. {
  73. return m_Level0.Count() << 5;
  74. }
  75. template < typename Functor >
  76. void ScanBits( Functor functor )
  77. {
  78. for( int nItLevel1 = 0; nItLevel1 < m_Level1.Count(); ++nItLevel1 )
  79. {
  80. uint nLevel1Bits = m_Level1[ nItLevel1 ];
  81. uint nBaseLevel1 = nItLevel1 * 32;
  82. while( nLevel1Bits )
  83. {
  84. #ifdef COMPILER_GCC
  85. uint32 nOffsetLevel1 = __builtin_ctz( nLevel1Bits );
  86. #else
  87. unsigned long nOffsetLevel1;
  88. _BitScanForward( &nOffsetLevel1, nLevel1Bits );
  89. #endif
  90. AssertDbg( nLevel1Bits & ( 1 << nOffsetLevel1 ) );
  91. nLevel1Bits ^= 1 << nOffsetLevel1;
  92. uint nItLevel0 = nBaseLevel1 + nOffsetLevel1;
  93. uint nLevel0Bits = m_Level0[ nItLevel0 ];
  94. if( nLevel0Bits != 0 ) // if the bit is set in level1, it doesn't mean the uint32 in level0 is always non-zero: it may have been reset
  95. {
  96. uint nBaseLevel0 = nItLevel0 * 32;
  97. do
  98. {
  99. #ifdef COMPILER_GCC
  100. uint32 nOffsetLevel0 = __builtin_ctz( nLevel0Bits );
  101. #else
  102. unsigned long nOffsetLevel0;
  103. _BitScanForward( &nOffsetLevel0, nLevel0Bits );
  104. #endif
  105. AssertDbg( nLevel0Bits & ( 1 << nOffsetLevel0 ) );
  106. nLevel0Bits ^= 1 << nOffsetLevel0;
  107. // Perform tree queries for all moving objects
  108. functor( nBaseLevel0 + nOffsetLevel0 );
  109. }
  110. while( nLevel0Bits );
  111. }
  112. }
  113. }
  114. }
  115. void Clear( )
  116. {
  117. m_Level0.FillWithValue( 0 );
  118. m_Level1.FillWithValue( 0 );
  119. }
  120. protected:
  121. CUtlVector< uint32 > m_Level1; // one bit for each 32 bits in m_MoveBufferLevel0
  122. CUtlVector< uint32 > m_Level0; // one bit for each proxy
  123. public:
  124. #ifdef AUTO_SERIALIZE
  125. AUTO_SERIALIZE;
  126. #endif
  127. };
  128. #endif