csgo-2018-source/dmserializers/importsfmv3.cpp
2021-07-24 21:11:47 -07:00

229 lines
7.0 KiB
C++

//====== Copyright © 1996-2006, Valve Corporation, All rights reserved. =======
//
// Purpose:
//
//=============================================================================
#include "dmserializers.h"
#include "dmebaseimporter.h"
#include "datamodel/idatamodel.h"
#include "datamodel/dmelement.h"
#include "datamodel/dmattributevar.h"
#include "tier1/KeyValues.h"
#include "tier1/utlbuffer.h"
#include "tier1/utlmap.h"
#include <limits.h>
//-----------------------------------------------------------------------------
// Format converter
//-----------------------------------------------------------------------------
class CImportSFMV3 : public CSFMBaseImporter
{
typedef CSFMBaseImporter BaseClass;
public:
CImportSFMV3( char const *formatName, char const *nextFormatName );
private:
virtual bool DoFixup( CDmElement *pSourceRoot );
void FixupElement( CDmElement *pElement );
// Fixes up all elements
void BuildList( CDmElement *pElement, CUtlRBTree< CDmElement *, int >& list );
};
//-----------------------------------------------------------------------------
// Singleton instance
//-----------------------------------------------------------------------------
static CImportSFMV3 s_ImportSFMV3( "sfm_v3", "sfm_v4" );
void InstallSFMV3Importer( IDataModel *pFactory )
{
pFactory->AddLegacyUpdater( &s_ImportSFMV3 );
}
//-----------------------------------------------------------------------------
// Constructor
//-----------------------------------------------------------------------------
CImportSFMV3::CImportSFMV3( char const *formatName, char const *nextFormatName ) :
BaseClass( formatName, nextFormatName )
{
}
struct LogToCurveInfoTypeMap_t
{
const char *pLogType;
const char *pLogLayerType;
const char *pCurveInfoType;
};
LogToCurveInfoTypeMap_t g_typeMap[] =
{
{ "DmeIntLog", "DmeIntLogLayer", "DmeIntCurveInfo" },
{ "DmeFloatLog", "DmeFloatLogLayer", "DmeFloatCurveInfo" },
{ "DmeBoolLog", "DmeBoolLogLayer", "DmeBoolCurveInfo" },
// string,
// void,
// objectid,
{ "DmeColorLog", "DmeColorLogLayer", "DmeColorCurveInfo" },
{ "DmeVector2Log", "DmeVector2LogLayer", "DmeVector2CurveInfo" },
{ "DmeVector3Log", "DmeVector3LogLayer", "DmeVector3CurveInfo" },
{ "DmeVector4Log", "DmeVector4LogLayer", "DmeVector4CurveInfo" },
{ "DmeQAngleLog", "DmeQAngleLogLayer", "DmeQAngleCurveInfo" },
{ "DmeQuaternionLog", "DmeQuaternionLogLayer","DmeQuaternionCurveInfo" },
{ "DmeVMatrixLog", "DmeVMatrixLogLayer", "DmeVMatrixCurveInfo" },
};
const char *GetCurveInfoTypeFromLogType( const char *pLogType )
{
int c = ARRAYSIZE( g_typeMap );
for ( int i = 0; i < c; ++i )
{
if ( !Q_stricmp( pLogType, g_typeMap[ i ].pLogType ) )
return g_typeMap[ i ].pCurveInfoType;
}
return NULL;
}
bool IsLogLayerType( const char *pLogLayerType )
{
int c = ARRAYSIZE( g_typeMap );
for ( int i = 0; i < c; ++i )
{
if ( !Q_stricmp( pLogLayerType, g_typeMap[ i ].pLogLayerType ) )
return true;
}
return false;
}
void MoveAttribute( CDmElement *pFromElement, const char *pFromAttrName, CDmElement *pToElement = NULL, const char *pToAttrName = NULL, DmAttributeType_t toType = AT_UNKNOWN )
{
if ( !pToAttrName )
{
pToAttrName = pFromAttrName;
}
if ( pToElement )
{
CDmAttribute *pFromAttr = pFromElement->GetAttribute( pFromAttrName );
const void *pValue = pFromAttr->GetValueUntyped();
DmAttributeType_t fromType = pFromAttr->GetType();
if ( toType == AT_UNKNOWN )
{
toType = fromType;
}
CDmAttribute *pToAttr = pToElement->AddAttribute( pToAttrName, toType );
if ( !pToAttr )
{
Warning( "*** Problem in converter encountered!\n" );
Warning( "*** Unable to find or add attribute \"%s\" to element \"%s\"!\n", pToAttrName, pToElement->GetName() );
}
else if ( fromType != toType )
{
Warning( "*** Problem in file encountered!\n" );
Warning( "*** Element \"%s\" has attribute \"%s\" with an unexpected type!\n", pFromElement->GetName(), pFromAttrName );
}
else
{
pToAttr->SetValue( toType, pValue );
}
}
pFromElement->RemoveAttribute( pFromAttrName );
}
// Fixes up all elements
//-----------------------------------------------------------------------------
void CImportSFMV3::FixupElement( CDmElement *pElement )
{
if ( !pElement )
return;
const char *pType = pElement->GetTypeString();
// log layer
if ( IsLogLayerType( pType ) )
{
pElement->RemoveAttribute( "ownerlog" );
return;
}
// log
const char *pCurveInfoType = GetCurveInfoTypeFromLogType( pType );
if ( !pCurveInfoType )
return;
CDmElement *pCurveInfo = NULL;
CDmAttribute *pUseCurveTypeAttr = pElement->GetAttribute( "usecurvetypes" );
if ( pUseCurveTypeAttr && pUseCurveTypeAttr->GetValue<bool>() )
{
DmElementHandle_t hElement = g_pDataModel->CreateElement( "curve info", pCurveInfoType, pElement->GetFileId() );
pCurveInfo = g_pDataModel->GetElement( hElement );
}
pElement->RemoveAttribute( "usecurvetypes" );
MoveAttribute( pElement, "defaultcurvetype", pCurveInfo, "defaultCurveType", AT_INT );
MoveAttribute( pElement, "defaultedgezerovalue",pCurveInfo, "defaultEdgeZeroValue" );
MoveAttribute( pElement, "useedgeinfo", pCurveInfo, "useEdgeInfo", AT_BOOL );
MoveAttribute( pElement, "rightedgetime", pCurveInfo, "rightEdgeTime", AT_INT );
MoveAttribute( pElement, "left_edge_active", pCurveInfo, "leftEdgeActive", AT_BOOL );
MoveAttribute( pElement, "right_edge_active", pCurveInfo, "rightEdgeActive", AT_BOOL );
MoveAttribute( pElement, "left_edge_curvetype", pCurveInfo, "leftEdgeCurveType", AT_INT );
MoveAttribute( pElement, "right_edge_curvetype",pCurveInfo, "rightEdgeCurveType", AT_INT );
MoveAttribute( pElement, "left_edge_value", pCurveInfo, "leftEdgeValue" );
MoveAttribute( pElement, "right_edge_value", pCurveInfo, "rightEdgeValue" );
}
// Fixes up all elements
//-----------------------------------------------------------------------------
void CImportSFMV3::BuildList( CDmElement *pElement, CUtlRBTree< CDmElement *, int >& list )
{
if ( !pElement )
return;
if ( list.Find( pElement ) != list.InvalidIndex() )
return;
list.Insert( pElement );
// Descend to bottom of tree, then do fixup coming back up the tree
for ( CDmAttribute *pAttribute = pElement->FirstAttribute(); pAttribute; pAttribute = pAttribute->NextAttribute() )
{
if ( pAttribute->GetType() == AT_ELEMENT )
{
CDmElement *pElement = pAttribute->GetValueElement<CDmElement>( );
BuildList( pElement, list );
continue;
}
if ( pAttribute->GetType() == AT_ELEMENT_ARRAY )
{
CDmrElementArray<> array( pAttribute );
int nCount = array.Count();
for ( int i = 0; i < nCount; ++i )
{
CDmElement *pChild = array[ i ];
BuildList( pChild, list );
}
continue;
}
}
}
bool CImportSFMV3::DoFixup( CDmElement *pSourceRoot )
{
CUtlRBTree< CDmElement *, int > fixlist( 0, 0, DefLessFunc( CDmElement * ) );
BuildList( pSourceRoot, fixlist );
for ( int i = fixlist.FirstInorder(); i != fixlist.InvalidIndex() ; i = fixlist.NextInorder( i ) )
{
// Search and replace in the entire tree!
FixupElement( fixlist[ i ] );
}
return true;
}