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.

227 lines
6.9 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================
  6. #include "dmserializers.h"
  7. #include "dmebaseimporter.h"
  8. #include "datamodel/idatamodel.h"
  9. #include "datamodel/dmelement.h"
  10. #include "tier1/KeyValues.h"
  11. #include "tier1/utlbuffer.h"
  12. #include "tier1/utlmap.h"
  13. #include <limits.h>
  14. //-----------------------------------------------------------------------------
  15. // Format converter
  16. //-----------------------------------------------------------------------------
  17. class CImportSFMV3 : public CSFMBaseImporter
  18. {
  19. typedef CSFMBaseImporter BaseClass;
  20. public:
  21. CImportSFMV3( char const *formatName, char const *nextFormatName );
  22. private:
  23. virtual bool DoFixup( CDmElement *pSourceRoot );
  24. void FixupElement( CDmElement *pElement );
  25. // Fixes up all elements
  26. void BuildList( CDmElement *pElement, CUtlRBTree< CDmElement *, int >& list );
  27. };
  28. //-----------------------------------------------------------------------------
  29. // Singleton instance
  30. //-----------------------------------------------------------------------------
  31. static CImportSFMV3 s_ImportSFMV3( "sfm_v3", "sfm_v4" );
  32. void InstallSFMV3Importer( IDataModel *pFactory )
  33. {
  34. pFactory->AddLegacyUpdater( &s_ImportSFMV3 );
  35. }
  36. //-----------------------------------------------------------------------------
  37. // Constructor
  38. //-----------------------------------------------------------------------------
  39. CImportSFMV3::CImportSFMV3( char const *formatName, char const *nextFormatName ) :
  40. BaseClass( formatName, nextFormatName )
  41. {
  42. }
  43. struct LogToCurveInfoTypeMap_t
  44. {
  45. const char *pLogType;
  46. const char *pLogLayerType;
  47. const char *pCurveInfoType;
  48. };
  49. LogToCurveInfoTypeMap_t g_typeMap[] =
  50. {
  51. { "DmeIntLog", "DmeIntLogLayer", "DmeIntCurveInfo" },
  52. { "DmeFloatLog", "DmeFloatLogLayer", "DmeFloatCurveInfo" },
  53. { "DmeBoolLog", "DmeBoolLogLayer", "DmeBoolCurveInfo" },
  54. // string,
  55. // void,
  56. // objectid,
  57. { "DmeColorLog", "DmeColorLogLayer", "DmeColorCurveInfo" },
  58. { "DmeVector2Log", "DmeVector2LogLayer", "DmeVector2CurveInfo" },
  59. { "DmeVector3Log", "DmeVector3LogLayer", "DmeVector3CurveInfo" },
  60. { "DmeVector4Log", "DmeVector4LogLayer", "DmeVector4CurveInfo" },
  61. { "DmeQAngleLog", "DmeQAngleLogLayer", "DmeQAngleCurveInfo" },
  62. { "DmeQuaternionLog", "DmeQuaternionLogLayer","DmeQuaternionCurveInfo" },
  63. { "DmeVMatrixLog", "DmeVMatrixLogLayer", "DmeVMatrixCurveInfo" },
  64. };
  65. const char *GetCurveInfoTypeFromLogType( const char *pLogType )
  66. {
  67. int c = ARRAYSIZE( g_typeMap );
  68. for ( int i = 0; i < c; ++i )
  69. {
  70. if ( !Q_stricmp( pLogType, g_typeMap[ i ].pLogType ) )
  71. return g_typeMap[ i ].pCurveInfoType;
  72. }
  73. return NULL;
  74. }
  75. bool IsLogLayerType( const char *pLogLayerType )
  76. {
  77. int c = ARRAYSIZE( g_typeMap );
  78. for ( int i = 0; i < c; ++i )
  79. {
  80. if ( !Q_stricmp( pLogLayerType, g_typeMap[ i ].pLogLayerType ) )
  81. return true;
  82. }
  83. return false;
  84. }
  85. void MoveAttribute( CDmElement *pFromElement, const char *pFromAttrName, CDmElement *pToElement = NULL, const char *pToAttrName = NULL, DmAttributeType_t toType = AT_UNKNOWN )
  86. {
  87. if ( !pToAttrName )
  88. {
  89. pToAttrName = pFromAttrName;
  90. }
  91. if ( pToElement )
  92. {
  93. CDmAttribute *pFromAttr = pFromElement->GetAttribute( pFromAttrName );
  94. const void *pValue = pFromAttr->GetValueUntyped();
  95. DmAttributeType_t fromType = pFromAttr->GetType();
  96. if ( toType == AT_UNKNOWN )
  97. {
  98. toType = fromType;
  99. }
  100. CDmAttribute *pToAttr = pToElement->AddAttribute( pToAttrName, toType );
  101. if ( !pToAttr )
  102. {
  103. Warning( "*** Problem in converter encountered!\n" );
  104. Warning( "*** Unable to find or add attribute \"%s\" to element \"%s\"!\n", pToAttrName, pToElement->GetName() );
  105. }
  106. else if ( fromType != toType )
  107. {
  108. Warning( "*** Problem in file encountered!\n" );
  109. Warning( "*** Element \"%s\" has attribute \"%s\" with an unexpected type!\n", pFromElement->GetName(), pFromAttrName );
  110. }
  111. else
  112. {
  113. pToAttr->SetValue( toType, pValue );
  114. }
  115. }
  116. pFromElement->RemoveAttribute( pFromAttrName );
  117. }
  118. // Fixes up all elements
  119. //-----------------------------------------------------------------------------
  120. void CImportSFMV3::FixupElement( CDmElement *pElement )
  121. {
  122. if ( !pElement )
  123. return;
  124. const char *pType = pElement->GetTypeString();
  125. // log layer
  126. if ( IsLogLayerType( pType ) )
  127. {
  128. pElement->RemoveAttribute( "ownerlog" );
  129. return;
  130. }
  131. // log
  132. const char *pCurveInfoType = GetCurveInfoTypeFromLogType( pType );
  133. if ( !pCurveInfoType )
  134. return;
  135. CDmElement *pCurveInfo = NULL;
  136. CDmAttribute *pUseCurveTypeAttr = pElement->GetAttribute( "usecurvetypes" );
  137. if ( pUseCurveTypeAttr && pUseCurveTypeAttr->GetValue<bool>() )
  138. {
  139. DmElementHandle_t hElement = g_pDataModel->CreateElement( "curve info", pCurveInfoType, pElement->GetFileId() );
  140. pCurveInfo = g_pDataModel->GetElement( hElement );
  141. }
  142. pElement->RemoveAttribute( "usecurvetypes" );
  143. MoveAttribute( pElement, "defaultcurvetype", pCurveInfo, "defaultCurveType", AT_INT );
  144. MoveAttribute( pElement, "defaultedgezerovalue",pCurveInfo, "defaultEdgeZeroValue" );
  145. MoveAttribute( pElement, "useedgeinfo", pCurveInfo, "useEdgeInfo", AT_BOOL );
  146. MoveAttribute( pElement, "rightedgetime", pCurveInfo, "rightEdgeTime", AT_INT );
  147. MoveAttribute( pElement, "left_edge_active", pCurveInfo, "leftEdgeActive", AT_BOOL );
  148. MoveAttribute( pElement, "right_edge_active", pCurveInfo, "rightEdgeActive", AT_BOOL );
  149. MoveAttribute( pElement, "left_edge_curvetype", pCurveInfo, "leftEdgeCurveType", AT_INT );
  150. MoveAttribute( pElement, "right_edge_curvetype",pCurveInfo, "rightEdgeCurveType", AT_INT );
  151. MoveAttribute( pElement, "left_edge_value", pCurveInfo, "leftEdgeValue" );
  152. MoveAttribute( pElement, "right_edge_value", pCurveInfo, "rightEdgeValue" );
  153. }
  154. // Fixes up all elements
  155. //-----------------------------------------------------------------------------
  156. void CImportSFMV3::BuildList( CDmElement *pElement, CUtlRBTree< CDmElement *, int >& list )
  157. {
  158. if ( !pElement )
  159. return;
  160. if ( list.Find( pElement ) != list.InvalidIndex() )
  161. return;
  162. list.Insert( pElement );
  163. // Descend to bottom of tree, then do fixup coming back up the tree
  164. for ( CDmAttribute *pAttribute = pElement->FirstAttribute(); pAttribute; pAttribute = pAttribute->NextAttribute() )
  165. {
  166. if ( pAttribute->GetType() == AT_ELEMENT )
  167. {
  168. CDmElement *pElementAt = pAttribute->GetValueElement<CDmElement>( );
  169. BuildList( pElementAt, list );
  170. continue;
  171. }
  172. if ( pAttribute->GetType() == AT_ELEMENT_ARRAY )
  173. {
  174. CDmrElementArray<> array( pAttribute );
  175. int nCount = array.Count();
  176. for ( int i = 0; i < nCount; ++i )
  177. {
  178. CDmElement *pChild = array[ i ];
  179. BuildList( pChild, list );
  180. }
  181. continue;
  182. }
  183. }
  184. }
  185. bool CImportSFMV3::DoFixup( CDmElement *pSourceRoot )
  186. {
  187. CUtlRBTree< CDmElement *, int > fixlist( 0, 0, DefLessFunc( CDmElement * ) );
  188. BuildList( pSourceRoot, fixlist );
  189. for ( int i = fixlist.FirstInorder(); i != fixlist.InvalidIndex() ; i = fixlist.NextInorder( i ) )
  190. {
  191. // Search and replace in the entire tree!
  192. FixupElement( fixlist[ i ] );
  193. }
  194. return true;
  195. }