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.

188 lines
5.4 KiB

  1. //====== Copyright � 1996-2004, Valve Corporation, All rights reserved. =======
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================
  6. #include "dmxserializationdictionary.h"
  7. #include "dmxloader/dmxelement.h"
  8. #include "dmxloader/dmxattribute.h"
  9. //-----------------------------------------------------------------------------
  10. //
  11. // Element dictionary used in serialization
  12. //
  13. //-----------------------------------------------------------------------------
  14. CDmxSerializationDictionary::CDmxSerializationDictionary( int nElementsHint /* = 0 */ ) :
  15. m_Dict( 0, nElementsHint, CDmxSerializationDictionary::LessFunc )
  16. {
  17. }
  18. //-----------------------------------------------------------------------------
  19. // Used to sort the list of elements
  20. //-----------------------------------------------------------------------------
  21. bool CDmxSerializationDictionary::LessFunc( const DmxElementInfo_t &lhs, const DmxElementInfo_t &rhs )
  22. {
  23. return lhs.m_pElement < rhs.m_pElement;
  24. }
  25. //-----------------------------------------------------------------------------
  26. // Finds the handle of the element
  27. //-----------------------------------------------------------------------------
  28. DmxSerializationHandle_t CDmxSerializationDictionary::Find( CDmxElement *pElement )
  29. {
  30. DmxElementInfo_t find;
  31. find.m_pElement = pElement;
  32. return m_Dict.Find( find );
  33. }
  34. //-----------------------------------------------------------------------------
  35. // Creates the list of all things to serialize
  36. //-----------------------------------------------------------------------------
  37. void CDmxSerializationDictionary::BuildElementList_R( CDmxElement *pElement, bool bFlatMode, bool bIsRoot )
  38. {
  39. if ( !pElement )
  40. return;
  41. // FIXME: Right here we should ask the element if it's an external
  42. // file reference and exit immediately if so.
  43. // This means we've already encountered this guy.
  44. // Therefore, he can never be a root element
  45. DmxSerializationHandle_t h = Find( pElement );
  46. if ( h != m_Dict.InvalidIndex() )
  47. {
  48. m_Dict[h].m_bRoot = true;
  49. return;
  50. }
  51. DmxElementInfo_t info;
  52. info.m_bRoot = bFlatMode || bIsRoot;
  53. info.m_pElement = pElement;
  54. m_Dict.Insert( info );
  55. int nCount = pElement->AttributeCount();
  56. for ( int i = 0; i < nCount; ++i )
  57. {
  58. CDmxAttribute *pAttribute = pElement->GetAttribute(i);
  59. switch( pAttribute->GetType() )
  60. {
  61. case AT_ELEMENT:
  62. {
  63. CDmxElement *pChild = pAttribute->GetValue<CDmxElement*>();
  64. if ( !pChild )
  65. break;
  66. BuildElementList_R( pChild, bFlatMode, false );
  67. }
  68. break;
  69. case AT_ELEMENT_ARRAY:
  70. {
  71. const CUtlVector<CDmxElement*> &array = pAttribute->GetArray<CDmxElement*>( );
  72. int nCount = array.Count();
  73. for ( int i = 0; i < nCount; ++i )
  74. {
  75. CDmxElement *pChild = array[ i ];
  76. if ( !pChild )
  77. break;
  78. BuildElementList_R( pChild, bFlatMode, false );
  79. }
  80. }
  81. break;
  82. }
  83. }
  84. }
  85. void CDmxSerializationDictionary::BuildElementList( CDmxElement *pElement, bool bFlatMode )
  86. {
  87. BuildElementList_R( pElement, bFlatMode, true );
  88. }
  89. //-----------------------------------------------------------------------------
  90. // Should I inline the serialization of this element?
  91. //-----------------------------------------------------------------------------
  92. bool CDmxSerializationDictionary::ShouldInlineElement( CDmxElement *pElement )
  93. {
  94. // This means we've already encountered this guy.
  95. // Therefore, he can never be a root element
  96. DmxSerializationHandle_t h = Find( pElement );
  97. if ( h != m_Dict.InvalidIndex() )
  98. return !m_Dict[h].m_bRoot;
  99. // If we didn't find the element, it means it's a reference to an external
  100. // element (or it's NULL), so don't inline ie.
  101. return false;
  102. }
  103. //-----------------------------------------------------------------------------
  104. // Clears the dictionary
  105. //-----------------------------------------------------------------------------
  106. void CDmxSerializationDictionary::Clear()
  107. {
  108. m_Dict.RemoveAll();
  109. }
  110. //-----------------------------------------------------------------------------
  111. // How many root elements do we have?
  112. //-----------------------------------------------------------------------------
  113. int CDmxSerializationDictionary::RootElementCount() const
  114. {
  115. int nCount = 0;
  116. DmxSerializationHandle_t h = m_Dict.FirstInorder();
  117. while( h != m_Dict.InvalidIndex() )
  118. {
  119. if ( m_Dict[h].m_bRoot )
  120. {
  121. ++nCount;
  122. }
  123. h = m_Dict.NextInorder( h );
  124. }
  125. return nCount;
  126. }
  127. //-----------------------------------------------------------------------------
  128. // Iterates over all root elements to serialize
  129. //-----------------------------------------------------------------------------
  130. DmxSerializationHandle_t CDmxSerializationDictionary::FirstRootElement() const
  131. {
  132. // NOTE: I don't have to use First/NextInorder here because there
  133. // are guaranteed to be no removals from the dictionary.
  134. // Also, using inorder traversal won't get my actual root element to be first in the file
  135. int nCount = m_Dict.Count();
  136. for ( DmxSerializationHandle_t h = 0; h < nCount; ++h )
  137. {
  138. if ( m_Dict[h].m_bRoot )
  139. return h;
  140. }
  141. return DMX_SERIALIZATION_HANDLE_INVALID;
  142. }
  143. DmxSerializationHandle_t CDmxSerializationDictionary::NextRootElement( DmxSerializationHandle_t h ) const
  144. {
  145. ++h;
  146. int nCount = m_Dict.Count();
  147. for ( ; h < nCount; ++h )
  148. {
  149. if ( m_Dict[h].m_bRoot )
  150. return h;
  151. }
  152. return DMX_SERIALIZATION_HANDLE_INVALID;
  153. }
  154. CDmxElement *CDmxSerializationDictionary::GetRootElement( DmxSerializationHandle_t h )
  155. {
  156. Assert( m_Dict[h].m_bRoot );
  157. return m_Dict[h].m_pElement;
  158. }