Team Fortress 2 Source Code as on 22/4/2020
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.

203 lines
5.2 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================
  6. #ifndef MDLLIB_UTILS_H
  7. #define MDLLIB_UTILS_H
  8. #ifdef _WIN32
  9. #pragma once
  10. #endif
  11. #include "utlmap.h"
  12. #include "utlvector.h"
  13. #include "bitvec.h"
  14. //////////////////////////////////////////////////////////////////////////
  15. //
  16. // Helper macros
  17. //
  18. //////////////////////////////////////////////////////////////////////////
  19. // Declare a pointer and automatically do the cast of initial value to the pointer type
  20. #define DECLARE_PTR( type, name, initval ) type *name = ( type * ) ( initval )
  21. // Compute a pointer that is offset given number of bytes from the base pointer
  22. #define BYTE_OFF_PTR( initval, offval ) ( ( ( byte * ) ( initval ) ) + ( offval ) )
  23. // Compute difference in bytes between two pointers
  24. #define BYTE_DIFF_PTR( begin, end ) ( ( ( byte * ) ( end ) ) - ( ( byte * ) ( begin ) ) )
  25. // "for {" to iterate children of a studio container
  26. #define ITERATE_CHILDREN( type, name, parent, accessor, count ) \
  27. for ( int name##_idx = 0; name##_idx < (parent)->count; ++ name##_idx ) { \
  28. type *name = (parent)->accessor( name##_idx );
  29. // "for {" to jointly iterate children of 2 studio containers of same size
  30. #define ITERATE_CHILDREN2( type, type2, name, name2, parent, parent2, accessor, accessor2, count ) \
  31. for ( int name##_idx = 0; name##_idx < (parent)->count; ++ name##_idx ) { \
  32. type *name = (parent)->accessor( name##_idx ); \
  33. type2 *name2 = (parent2)->accessor2( name##_idx );
  34. // "}" to mark the end of iteration block
  35. #define ITERATE_END }
  36. // Get the child of a container by index
  37. #define CHILD_AT( parent, accessor, idx ) ( (parent)->accessor( idx ) )
  38. //
  39. // CLessSimple< T >
  40. // Comparison policy to use "t1 < t2" comparison rule.
  41. //
  42. template < typename T >
  43. class CLessSimple
  44. {
  45. public:
  46. bool Less( const T& src1, const T& src2, void *pCtx )
  47. {
  48. pCtx;
  49. return ( src1 < src2 );
  50. }
  51. };
  52. //
  53. // CInsertionTracker
  54. // Class that is tracking insertions that are scheduled to happen at given points.
  55. // Use policy:
  56. // InsertBytes / InsertElements [*] -- schedule insertions
  57. // Finalize -- finalize insertion information
  58. // ComputePointer / ComputeOffset [*] -- compute new pointers/offsets that will happen after insertions
  59. // MemMove -- perform memory moves to apply insertions
  60. //
  61. class CInsertionTracker
  62. {
  63. public:
  64. CInsertionTracker() : m_map( DefLessFunc( byte * ) ) {}
  65. // Schedules a piece of memory for insertion
  66. public:
  67. void InsertBytes( void *pos, int length );
  68. template< typename T >
  69. void InsertElements( T *ptr, int count = 1 ) { InsertBytes( ( byte * ) ptr, count * sizeof( T ) ); }
  70. int GetNumBytesInserted() const;
  71. // Finalizes the insertion information
  72. public:
  73. void Finalize();
  74. // Computes where the pointer would point after memory insertion occurs
  75. public:
  76. void * ComputePointer( void *ptrNothingInserted ) const;
  77. int ComputeOffset( void *ptrBase, int off ) const;
  78. // Perform memory moves, the buffer should be large enough to accommodate inserted bytes
  79. public:
  80. void MemMove( void *ptrBase, int &length ) const;
  81. protected:
  82. typedef CUtlMap< byte *, int, unsigned int > Map;
  83. Map m_map; // pos -> length
  84. };
  85. //
  86. // CRemoveTracker
  87. // Class that is tracking removals that are scheduled to happen at given points.
  88. // Use policy:
  89. // RemoveBytes / RemoveElements [*] -- schedule removals
  90. // Finalize -- finalize removal information
  91. // ComputePointer / ComputeOffset [*] -- compute new pointers/offsets that will happen after removals
  92. // MemMove -- perform memory moves to apply removals
  93. //
  94. class CRemoveTracker
  95. {
  96. public:
  97. CRemoveTracker() : m_map( DefLessFunc( byte * ) ) {}
  98. // Schedules a piece of memory for removal
  99. public:
  100. void RemoveBytes( void *pos, int length );
  101. template< typename T >
  102. void RemoveElements( T *ptr, int count = 1 ) { RemoveBytes( ( byte * ) ptr, count * sizeof( T ) ); }
  103. int GetNumBytesRemoved() const;
  104. // Finalizes the removal information
  105. public:
  106. void Finalize();
  107. // Computes where the pointer would point after memory removal occurs
  108. public:
  109. void * ComputePointer( void *ptrNothingRemoved ) const;
  110. int ComputeOffset( void *ptrBase, int off ) const;
  111. public:
  112. void MemMove( void *ptrBase, int &length ) const;
  113. protected:
  114. typedef CUtlMap< byte *, int, unsigned int > Map;
  115. Map m_map; // pos -> length
  116. struct Item
  117. {
  118. Map::IndexType_t idx;
  119. byte *ptr;
  120. int len;
  121. };
  122. Item m_hint;
  123. };
  124. //
  125. // CGrowableBitVec
  126. // Serves bit accumulation.
  127. // Provides "GrowSetBit" method to automatically grow to the required size
  128. // and set the given bit.
  129. // Provides safe "IsBitSet" that would return false for missing bits.
  130. //
  131. class CGrowableBitVec : public CVarBitVec
  132. {
  133. public:
  134. void GrowSetBit( int iBit )
  135. {
  136. if ( iBit >= GetNumBits() )
  137. Resize( iBit + 1, false );
  138. Set( iBit );
  139. }
  140. bool IsBitSet( int bitNum ) const
  141. {
  142. return ( bitNum < GetNumBits() ) && CVarBitVec::IsBitSet( bitNum );
  143. }
  144. };
  145. //
  146. // CGrowableVector
  147. // Provides zero-initialization for new elements.
  148. //
  149. template < typename T >
  150. class CGrowableVector : public CUtlVector < T >
  151. {
  152. public:
  153. T & operator[] ( int idx )
  154. {
  155. while ( idx >= Count() )
  156. AddToTail( T() );
  157. return CUtlVector < T >::operator []( idx );
  158. }
  159. };
  160. #endif // #ifndef MDLLIB_UTILS_H