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.

190 lines
4.1 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: Network dirty field marker for shared objects
  4. //
  5. //=============================================================================
  6. #include "stdafx.h"
  7. // memdbgon must be the last include file in a .cpp file!!!
  8. #include "tier0/memdbgon.h"
  9. namespace GCSDK
  10. {
  11. CSharedObjectDirtyFieldList::CSharedObjectDirtyFieldList( CSharedObject *obj )
  12. : m_obj( obj )
  13. , m_firstFieldBits( 0 )
  14. , m_pExtendedFields( NULL )
  15. {
  16. }
  17. CSharedObjectDirtyFieldList::~CSharedObjectDirtyFieldList()
  18. {
  19. if ( m_pExtendedFields )
  20. {
  21. delete m_pExtendedFields;
  22. }
  23. }
  24. CSharedObject *CSharedObjectDirtyFieldList::Obj() const
  25. {
  26. return m_obj;
  27. }
  28. void CSharedObjectDirtyFieldList::DirtyField( int index )
  29. {
  30. // if the field index fits within our dirty fields struct, set a bit to track it
  31. if ( index < 32 )
  32. {
  33. m_firstFieldBits |= (1 << index);
  34. }
  35. // if the field index is too big, store it in our backup structure; this is less efficient but more
  36. // flexible, especially when dealing with fields that themselves contain flags so would be interpreted
  37. // as huge numbers
  38. else
  39. {
  40. if ( !m_pExtendedFields )
  41. m_pExtendedFields = new CUtlVector<int>;
  42. if ( !m_pExtendedFields->HasElement( index ) )
  43. m_pExtendedFields->AddToTail( index );
  44. }
  45. }
  46. void CSharedObjectDirtyFieldList::GetDirtyFieldSet( CUtlVector<int> &fieldSet ) const
  47. {
  48. fieldSet.Purge();
  49. if( !m_firstFieldBits && !m_pExtendedFields )
  50. {
  51. return;
  52. }
  53. if( m_firstFieldBits )
  54. {
  55. for( int i = 0; i < 32; i++ )
  56. {
  57. // handle dirty bits
  58. if( m_firstFieldBits & ( 1 << i ) )
  59. {
  60. fieldSet.AddToTail( i );
  61. }
  62. }
  63. }
  64. // handle higher order dirty-fields list if present
  65. if ( m_pExtendedFields )
  66. {
  67. fieldSet.AddVectorToTail( *m_pExtendedFields );
  68. }
  69. }
  70. //-----------------------------------------------------------------------------
  71. CSharedObjectDirtyList::CSharedObjectDirtyList()
  72. {
  73. }
  74. CSharedObjectDirtyList::~CSharedObjectDirtyList()
  75. {
  76. }
  77. void CSharedObjectDirtyList::DirtyObjectField( CSharedObject *obj, int field )
  78. {
  79. MEM_ALLOC_CREDIT_CLASS();
  80. Assert( obj != NULL );
  81. if (!obj)
  82. {
  83. return;
  84. }
  85. int index = FindIndexByObj( obj );
  86. if ( index == InvalidIndex() )
  87. {
  88. index = m_sharedObjectDirtyFieldList.AddToTail( CSharedObjectDirtyFieldList( obj ) );
  89. }
  90. m_sharedObjectDirtyFieldList[index].DirtyField( field );
  91. }
  92. int CSharedObjectDirtyList::FindIndexByObj( const CSharedObject *pObj ) const
  93. {
  94. // Slow method for now, we can speed this up with a map later
  95. for ( int i = 0; i < m_sharedObjectDirtyFieldList.Count(); ++i )
  96. {
  97. if( m_sharedObjectDirtyFieldList[i].Obj() == pObj )
  98. {
  99. return i;
  100. }
  101. }
  102. return InvalidIndex();
  103. }
  104. bool CSharedObjectDirtyList::HasElement( const CSharedObject *pObj ) const
  105. {
  106. return FindIndexByObj( pObj ) != InvalidIndex();
  107. }
  108. bool CSharedObjectDirtyList::GetDirtyFieldSetByIndex( int index, CSharedObject **ppObj, CUtlVector<int> &fieldSet ) const
  109. {
  110. VPROF_BUDGET( "CSharedObjectDirtyList::GetDirtyFieldSetByIndex", VPROF_BUDGETGROUP_STEAM );
  111. if( !m_sharedObjectDirtyFieldList.IsValidIndex( index ) )
  112. {
  113. fieldSet.Purge();
  114. if( ppObj )
  115. {
  116. *ppObj = NULL;
  117. }
  118. return false;
  119. }
  120. const CSharedObjectDirtyFieldList &fieldList = m_sharedObjectDirtyFieldList[index];
  121. if( ppObj )
  122. {
  123. *ppObj = fieldList.Obj();
  124. }
  125. fieldList.GetDirtyFieldSet( fieldSet );
  126. return true;
  127. }
  128. bool CSharedObjectDirtyList::GetDirtyFieldSetByObj( CSharedObject *pObj, CUtlVector<int> &fieldSet )
  129. {
  130. int index = FindIndexByObj( pObj );
  131. if ( index == InvalidIndex() )
  132. {
  133. fieldSet.Purge();
  134. return false;
  135. }
  136. CSharedObjectDirtyFieldList &fieldList = m_sharedObjectDirtyFieldList[index];
  137. fieldList.GetDirtyFieldSet( fieldSet );
  138. return true;
  139. }
  140. bool CSharedObjectDirtyList::FindAndRemove( CSharedObject *pObj )
  141. {
  142. int index = FindIndexByObj( pObj );
  143. if ( index == InvalidIndex() )
  144. {
  145. return false;
  146. }
  147. m_sharedObjectDirtyFieldList.Remove( index );
  148. return true;
  149. }
  150. void CSharedObjectDirtyList::RemoveAll()
  151. {
  152. m_sharedObjectDirtyFieldList.RemoveAll();
  153. }
  154. #ifdef DBGFLAG_VALIDATE
  155. void CSharedObjectDirtyList::Validate( CValidator &validator, const char *pchName )
  156. {
  157. VALIDATE_SCOPE();
  158. ValidateObj( m_sharedObjectDirtyFieldList );
  159. }
  160. #endif
  161. } // namespace GCSDK