//========= Copyright Valve Corporation, All rights reserved. ============// // // Purpose: Unit test program for DMX testing // // $NoKeywords: $ //=============================================================================// #include "unitlib/unitlib.h" #include "datamodel/dmelement.h" #include "datamodel/idatamodel.h" #include "tier1/utlbuffer.h" #include "filesystem.h" #include "datamodel/dmehandle.h" #include "tier2/tier2.h" bool AssertEqualElementHierarchies( bool quiet, DmElementHandle_t src1, DmElementHandle_t src2 ); bool AssertUnEqualElementHierarchies( DmElementHandle_t src1, DmElementHandle_t src2 ) { bool equal = AssertEqualElementHierarchies( true, src1, src2 ); if ( equal ) { AssertMsg( 0, "Hierarchies equal, expecting mismatch\n" ); } return !equal; } void CreateTestScene( CUtlVector< DmElementHandle_t >& handles, DmFileId_t fileid ) { DmObjectId_t id; CreateUniqueId( &id ); VMatrix mat, mat2; MatrixBuildRotateZ( mat, 45 ); MatrixBuildRotateZ( mat2, 30 ); int i; unsigned char buf[256]; unsigned char buf2[256]; for ( i = 0; i < 256; ++i ) { buf[i] = i; buf2[i] = 255 - i; } CDmElement *pElement = CreateElement( "root", fileid ); Assert( pElement ); CDmElement *pElement2 = CreateElement( "shared_child", fileid ); Assert( pElement2 ); CDmElement *pElement3 = CreateElement( "unique_child", fileid ); Assert( pElement3 ); CDmElement *pElement4 = CreateElement( "shared_array_element", fileid ); Assert( pElement4 ); CDmElement *pElement5 = CreateElement( "unique_array_element", fileid ); Assert( pElement5 ); CDmElement *pElement6 = CreateElement( "shared_element", fileid ); Assert( pElement6 ); CDmElement *pElement7 = CreateElement( "unique_element", fileid ); Assert( pElement7 ); g_pDataModel->SetFileRoot( fileid, pElement->GetHandle() ); handles.AddToTail( pElement->GetHandle() ); handles.AddToTail( pElement2->GetHandle() ); handles.AddToTail( pElement3->GetHandle() ); handles.AddToTail( pElement4->GetHandle() ); handles.AddToTail( pElement5->GetHandle() ); handles.AddToTail( pElement6->GetHandle() ); handles.AddToTail( pElement7->GetHandle() ); pElement->SetValue( "id_test", id ); pElement->SetValue( "bool_test", true ); pElement->SetValue( "int_test", 2 ); pElement->SetValue( "float_test", 3.0f ); pElement->SetValue( "color_test", Color( 0, 64, 128, 255 ) ); pElement->SetValue( "vector2d_test", Vector2D( 1.0f, -1.0f ) ); pElement->SetValue( "vector3d_test", Vector( 1.0f, -1.0f, 0.0f ) ); pElement->SetValue( "vector4d_test", Vector4D( 1.0f, -1.0f, 0.0f, 2.0f ) ); pElement->SetValue( "qangle_test", QAngle( 0.0f, 90.0f, -90.0f ) ); pElement->SetValue( "quat_test", Quaternion( 1.0f, -1.0f, 0.0f, 2.0f ) ); pElement->SetValue( "vmatrix_test", mat ); pElement->SetValue( "string_test", "test" ); pElement->SetValue( "binary_test", buf, 256 ); // Test DONTSAVE // pElement->SetValue( "dontsave", true ); // CDmAttribute *pAttribute = pElement->GetAttribute( "dontsave" ); // pAttribute->AddFlag( FATTRIB_DONTSAVE ); CDmrArray< bool > boolVec( pElement2, "bool_array_test", true ); boolVec.AddToTail( false ); boolVec.AddToTail( true ); CDmrArray< int > intVec( pElement2, "int_array_test", true ); intVec.AddToTail( 0 ); intVec.AddToTail( 1 ); intVec.AddToTail( 2 ); CDmrArray< float > floatVec( pElement2, "float_array_test", true ); floatVec.AddToTail( -1.0f ); floatVec.AddToTail( 0.0f ); floatVec.AddToTail( 1.0f ); CDmrArray< Color > colorVec( pElement3, "color_array_test", true ); colorVec.AddToTail( Color( 0, 0, 0, 255 ) ); colorVec.AddToTail( Color( 64, 64, 64, 255 ) ); colorVec.AddToTail( Color( 128, 128, 128, 255 ) ); CDmrArray< Vector2D > vector2DVec( pElement3, "vector2d_array_test", true ); vector2DVec.AddToTail( Vector2D( -1.0f, -1.0f ) ); vector2DVec.AddToTail( Vector2D( 1.0f, 1.0f ) ); CDmrArray< Vector > vector3DVec( pElement3, "vector3d_array_test", true ); vector3DVec.AddToTail( Vector( 1.0f, -1.0f, 0.0f ) ); vector3DVec.AddToTail( Vector( 2.0f, -2.0f, 0.0f ) ); CDmrArray< Vector4D > vector4DVec( pElement4, "vector4d_array_test", true ); vector4DVec.AddToTail( Vector4D( 1.0f, -1.0f, 0.0f, 2.0f ) ); vector4DVec.AddToTail( Vector4D( 2.0f, -2.0f, 0.0f, 4.0f ) ); CDmrArray< QAngle > angleVec( pElement4, "qangle_array_test", true ); angleVec.AddToTail( QAngle( 1.0f, -1.0f, 0.0f ) ); angleVec.AddToTail( QAngle( 2.0f, -2.0f, 0.0f ) ); CDmrArray< Quaternion > quatVec( pElement4, "quat_array_test", true ); quatVec.AddToTail( Quaternion( 1.0f, -1.0f, 0.0f, 2.0f ) ); quatVec.AddToTail( Quaternion( 2.0f, -2.0f, 0.0f, 4.0f ) ); CDmrArray< VMatrix > matVec( pElement5, "vmatrix_array_test", true ); matVec.AddToTail( mat ); matVec.AddToTail( mat2 ); CDmrStringArray stringVec( pElement5, "string_array_test", true ); stringVec.AddToTail( "string1" ); stringVec.AddToTail( "string2" ); stringVec.AddToTail( "string3" ); CDmrArray< CUtlBinaryBlock > binaryVec( pElement5, "binary_array_test", true ); CUtlBinaryBlock block( (const void *)buf, 256 ); i = binaryVec.AddToTail( block ); CUtlBinaryBlock block2( (const void *)buf2, 256 ); i = binaryVec.AddToTail( block2); CDmrArray< DmObjectId_t > idVec( pElement6, "elementid_array_test", true ); i = idVec.AddToTail( pElement6->GetId() ); i = idVec.AddToTail( pElement5->GetId() ); i = idVec.AddToTail( pElement4->GetId() ); CDmrElementArray< > elementVec( pElement6, "element_array_test", true ); elementVec.AddToTail( pElement4 ); elementVec.AddToTail( pElement5 ); CDmrElementArray< > elementVec2( pElement7, "element_array_test", true ); elementVec2.AddToTail( pElement2 ); elementVec2.AddToTail( pElement4 ); pElement->SetValue( "element_test", pElement7 ); pElement->SetValue( "shared_element_test", pElement6 ); CDmrElementArray<> children( pElement, "children", true ); children.InsertBefore( 0, pElement2 ); children.InsertBefore( 1, pElement3 ); pElement7->SetValue( "shared_element_test", pElement6 ); CDmrElementArray<> children2( pElement7, "children", true ); children2.InsertBefore( 0, pElement2 ); } DmElementHandle_t CreateTestScene( DmFileId_t fileid ) { CUtlVector< DmElementHandle_t > handles; CreateTestScene( handles, fileid ); return handles[ 0 ]; } DmElementHandle_t CreateKeyValuesTestScene( DmFileId_t fileid ) { CDmElement *pElement = CreateElement( "root", fileid ); Assert( pElement ); CDmElement *pElement2 = CreateElement( "shared_child", fileid ); Assert( pElement2 ); CDmElement *pElement3 = CreateElement( "unique_child", fileid ); Assert( pElement3 ); CDmElement *pElement4 = CreateElement( "shared_array_element", fileid ); Assert( pElement4 ); CDmElement *pElement5 = CreateElement( "unique_array_element", fileid ); Assert( pElement5 ); CDmElement *pElement6 = CreateElement( "shared_element", fileid ); Assert( pElement6 ); CDmElement *pElement7 = CreateElement( "unique_element", fileid ); Assert( pElement7 ); g_pDataModel->SetFileRoot( fileid, pElement->GetHandle() ); pElement->SetValue( "int_test", 2 ); pElement->SetValue( "float_test", 3.0f ); pElement->SetValue( "string_test", "test" ); CDmrElementArray<> eVec( pElement6, "element_array_test", true ); eVec.AddToTail( pElement4 ); eVec.AddToTail( pElement5 ); CDmrElementArray<> eVec2( pElement7, "element_array_test", true ); eVec2.AddToTail( pElement2 ); eVec2.AddToTail( pElement4 ); pElement->SetValue( "element_test", pElement7 ); pElement->SetValue( "shared_element_test", pElement6 ); CDmrElementArray<> children( pElement, "children", true ); children.InsertBefore( 0, pElement2 ); children.InsertBefore( 1, pElement3 ); pElement7->SetValue( "shared_element_test", pElement6 ); CDmrElementArray<> children2( pElement7, "children", true ); children2.InsertBefore( 0, pElement2 ); return pElement->GetHandle(); } template< class T > bool AssertEqualsTest( bool quiet, const T& src1, const T& src2 ) { if ( !( src1 == src2 )) { if ( !quiet ) { AssertMsg( 0, "Results not equal, expecting equal\n" ); } return false; } return true; } template< class T > bool AssertEqualsUtlVector( bool quiet, const CUtlVector &src1, const CUtlVector &src2 ) { bool retval = true; if ( src1.Count() != src2.Count() ) { if ( !quiet ) { AssertEqualsTest( quiet, src1.Count(), src2.Count() ); } retval = false; } for ( int i = 0; i < src1.Count(); ++i ) { if ( !src2.IsValidIndex( i ) ) continue; if ( !( src1[i] == src2[i] ) ) { if ( !quiet ) { AssertEqualsTest( quiet, src1[i], src2[i] ); } retval = false; } } return retval; } template< class T > bool AssertEqualsUtlVector( bool quiet, CDmAttribute *pAttribute1, CDmAttribute *pAttribute2 ) { CDmrArray src1( pAttribute1 ); CDmrArray src2( pAttribute2 ); return AssertEqualsUtlVector( quiet, src1.Get(), src2.Get() ); } bool AssertEqualAttributes( bool quiet, CDmAttribute *pAttribute1, CDmAttribute *pAttribute2 ) { // Always follow ptrs to elements... if ( pAttribute1->GetType() != AT_ELEMENT_ARRAY && pAttribute1->GetType() != AT_ELEMENT ) { // Dirty flag checking here is to avoid infinite recursive loops if ( !pAttribute1->IsFlagSet( FATTRIB_DIRTY ) && !pAttribute2->IsFlagSet( FATTRIB_DIRTY ) ) return true; } if ( !pAttribute1 ) { if ( !quiet ) { AssertMsg( 0, "AssertEqualAttributes: pAttribute1 is NULL\n" ); } return false; } if ( !pAttribute2 ) { if ( !quiet ) { AssertMsg( 0, "AssertEqualAttributes: pAttribute2 is NULL\n" ); } return false; } bool retval = true; pAttribute1->RemoveFlag( FATTRIB_DIRTY ); pAttribute2->RemoveFlag( FATTRIB_DIRTY ); if ( pAttribute1->GetType() != pAttribute2->GetType() ) { if ( !quiet ) { AssertMsg( 0, "pAttribute1->GetType() == pAttribute2->GetType()" ); } retval = false; } switch( pAttribute1->GetType() ) { case AT_INT: return AssertEqualsTest( quiet, pAttribute1->GetValue( ), pAttribute2->GetValue( ) ); case AT_FLOAT: return AssertEqualsTest( quiet, pAttribute1->GetValue( ), pAttribute2->GetValue( ) ); case AT_BOOL: return AssertEqualsTest( quiet, pAttribute1->GetValue( ), pAttribute2->GetValue( ) ); case AT_STRING: return AssertEqualsTest( quiet, pAttribute1->GetValue( ), pAttribute2->GetValue( ) ); case AT_VOID: return AssertEqualsTest( quiet, pAttribute1->GetValue( ), pAttribute2->GetValue( ) ); case AT_OBJECTID: return true; // skip this for now - two elements can't have the same id, and CreateTestScene currently creates random test_id's each time... /* { if ( !g_pDataModel->IsEqual( pAttribute1->GetValue( ), pAttribute2->GetValue( ) ) ) { if ( !quiet ) { Assert( g_pDataModel->IsEqual( pAttribute1->GetValue( ), pAttribute2->GetValue( ) ) ); } return false; } return true; } break; */ case AT_COLOR: return AssertEqualsTest( quiet, pAttribute1->GetValue( ), pAttribute2->GetValue( ) ); case AT_VECTOR2: return AssertEqualsTest( quiet, pAttribute1->GetValue( ), pAttribute2->GetValue( ) ); case AT_VECTOR3: return AssertEqualsTest( quiet, pAttribute1->GetValue( ), pAttribute2->GetValue( ) ); case AT_VECTOR4: return AssertEqualsTest( quiet, pAttribute1->GetValue( ), pAttribute2->GetValue( ) ); case AT_QANGLE: return AssertEqualsTest( quiet, pAttribute1->GetValue( ), pAttribute2->GetValue( ) ); case AT_QUATERNION: return AssertEqualsTest( quiet, pAttribute1->GetValue( ), pAttribute2->GetValue( ) ); case AT_VMATRIX: return AssertEqualsTest( quiet, pAttribute1->GetValue( ), pAttribute2->GetValue( ) ); case AT_ELEMENT: return AssertEqualElementHierarchies( quiet, pAttribute1->GetValue( ), pAttribute2->GetValue( ) ); case AT_ELEMENT_ARRAY: { const CDmrElementArray< CDmElement > src1( pAttribute1 ); const CDmrElementArray< CDmElement > src2( pAttribute2 ); bool differs = !AssertEqualsTest( quiet, src1.Count(), src2.Count() ); bool differs2 = false; for ( int i = 0; i < src1.Count(); ++i ) { differs2 |= !AssertEqualElementHierarchies( quiet, src1[ i ]->GetHandle(), src2[ i ]->GetHandle() ); } return ( !differs && !differs2 ); } break; case AT_INT_ARRAY: return AssertEqualsUtlVector( quiet, pAttribute1, pAttribute2 ); case AT_FLOAT_ARRAY: return AssertEqualsUtlVector( quiet, pAttribute1, pAttribute2 ); case AT_BOOL_ARRAY: return AssertEqualsUtlVector( quiet, pAttribute1, pAttribute2 ); case AT_STRING_ARRAY: return AssertEqualsUtlVector( quiet, pAttribute1, pAttribute2 ); case AT_VOID_ARRAY: return AssertEqualsUtlVector( quiet, pAttribute1, pAttribute2 ); case AT_OBJECTID_ARRAY: { const CDmrArray src1( pAttribute1 ); const CDmrArray src2( pAttribute2 ); bool differs = AssertEqualsTest( quiet, src1.Count(), src2.Count() ); return differs; // skip this for now - CreateTestScene currently creates random ids each time... /* bool differs2 = false; for ( int i = 0; i < src1.Count(); ++i ) { if ( !g_pDataModel->IsEqual( src1[i], src2[i] ) ) { differs2 = true; if ( !quiet ) { Assert( g_pDataModel->IsEqual( src1[i], src2[i] ) ); } } } return ( !differs && !differs2 ); */ } break; case AT_COLOR_ARRAY: return AssertEqualsUtlVector( quiet, pAttribute1, pAttribute2 ); case AT_VECTOR2_ARRAY: return AssertEqualsUtlVector( quiet, pAttribute1, pAttribute2 ); case AT_VECTOR3_ARRAY: return AssertEqualsUtlVector( quiet, pAttribute1, pAttribute2 ); case AT_VECTOR4_ARRAY: return AssertEqualsUtlVector( quiet, pAttribute1, pAttribute2 ); case AT_QANGLE_ARRAY: return AssertEqualsUtlVector( quiet, pAttribute1, pAttribute2 ); case AT_QUATERNION_ARRAY: return AssertEqualsUtlVector( quiet, pAttribute1, pAttribute2 ); case AT_VMATRIX_ARRAY: return AssertEqualsUtlVector( quiet, pAttribute1, pAttribute2 ); } return retval; } bool AssertEqualElementHierarchies( bool quiet, DmElementHandle_t src1, DmElementHandle_t src2 ) { CDmElement *pSrc1 = g_pDataModel->GetElement( src1 ); CDmElement *pSrc2 = g_pDataModel->GetElement( src2 ); if ( !pSrc1 || !pSrc2 ) return false; // Assume equality bool retval = true; if ( pSrc1->GetType() != pSrc2->GetType() ) { if ( !quiet ) { AssertMsg( 0, "pSrc1->GetType() == pSrc2->GetType()" ); } retval = false; } if ( Q_strcmp( pSrc1->GetName(), pSrc2->GetName() ) ) { if ( !quiet ) { AssertMsg2( 0, "Q_strcmp( %s, %s )", pSrc1->GetName(), pSrc2->GetName() ); } retval = false; } if ( pSrc1->AttributeCount() != pSrc2->AttributeCount() ) { if ( !quiet ) { AssertMsg( 0, "pSrc1->NumAttributes() == pSrc2->NumAttributes()" ); } retval = false; } for ( CDmAttribute *pAttribute1 = pSrc1->FirstAttribute(); pAttribute1; pAttribute1 = pAttribute1->NextAttribute() ) { const char *pName = pAttribute1->GetName(); if ( !pSrc2->HasAttribute( pName ) ) { if ( !quiet ) { AssertMsg1( 0, "pSrc2->HasAttribute( %s ) failed\n", pName ); } retval = false; } else { CDmAttribute *pAttribute2 = pSrc2->GetAttribute( pName ); bool differs = !AssertEqualAttributes( quiet, pAttribute1, pAttribute2 ); if ( differs ) { retval = false; } } } return retval; } void TestDeleteOldCR( const char *pSerializationType ) { DmFileId_t testFileID = g_pDataModel->FindOrCreateFileId( "" ); DmElementHandle_t hRoot = CreateTestScene( testFileID ); int nTestElements = g_pDataModel->NumElementsInFile( testFileID ); const char *pFileName = "DeleteOld.dmx"; CDmElement *pRoot = static_cast< CDmElement* >( g_pDataModel->GetElement( hRoot ) ); bool bOk = g_pDataModel->SaveToFile( pFileName, NULL, pSerializationType, "dmx", pRoot ); Shipping_Assert( bOk ); CDmElement *pReadInRoot = NULL; DmFileId_t readFileID = g_pDataModel->RestoreFromFile( pFileName, NULL, NULL, &pReadInRoot, CR_DELETE_OLD ); Shipping_Assert( readFileID != DMFILEID_INVALID ); if ( pReadInRoot ) { Shipping_Assert( pReadInRoot->GetHandle() == hRoot ); Shipping_Assert( g_pDataModel->GetElement( hRoot ) == pReadInRoot ); Shipping_Assert( g_pDataModel->NumElementsInFile( testFileID ) == 0 ); Shipping_Assert( g_pDataModel->NumElementsInFile( readFileID ) == nTestElements ); CDmeHandle< CDmElement > rootHandle( hRoot ); // keeps a reference to root around, even after the file is unloaded g_pDataModel->UnloadFile( readFileID ); Shipping_Assert( g_pDataModel->NumElementsInFile( readFileID ) == 0 ); Shipping_Assert( g_pDataModel->GetElement( hRoot ) == NULL ); DmFileId_t readFileID2 = g_pDataModel->RestoreFromFile( pFileName, NULL, NULL, &pReadInRoot, CR_DELETE_OLD ); Shipping_Assert( readFileID2 == readFileID ); Shipping_Assert( pReadInRoot->GetHandle() == hRoot ); Shipping_Assert( g_pDataModel->GetElement( hRoot ) == pReadInRoot ); Shipping_Assert( g_pDataModel->NumElementsInFile( testFileID ) == 0 ); Shipping_Assert( g_pDataModel->NumElementsInFile( readFileID ) == nTestElements ); g_pDataModel->RemoveFileId( readFileID ); } else { Msg( "Failed to load %s back from disk!!!", pFileName ); } g_pDataModel->RemoveFileId( testFileID ); } void TestDeleteNewCR( const char *pSerializationType ) { DmFileId_t testFileID = g_pDataModel->FindOrCreateFileId( "" ); DmElementHandle_t hRoot = CreateTestScene( testFileID ); int nTestElements = g_pDataModel->NumElementsInFile( testFileID ); const char *pFileName = "DeleteNew.dmx"; CDmElement *pRoot = static_cast< CDmElement* >( g_pDataModel->GetElement( hRoot ) ); bool bOk = g_pDataModel->SaveToFile( pFileName, NULL, pSerializationType, "dmx", pRoot ); Shipping_Assert( bOk ); CDmElement *pReadInRoot = NULL; DmFileId_t readFileID = g_pDataModel->RestoreFromFile( pFileName, NULL, NULL, &pReadInRoot, CR_DELETE_NEW ); Shipping_Assert( readFileID != DMFILEID_INVALID ); Shipping_Assert( g_pDataModel->GetElement( hRoot ) == pRoot ); Shipping_Assert( pRoot->GetHandle() == hRoot ); Shipping_Assert( pReadInRoot == pRoot ); // RestoreFromFile now returns the old element when the new root is deleted Shipping_Assert( g_pDataModel->NumElementsInFile( testFileID ) == nTestElements ); Shipping_Assert( g_pDataModel->NumElementsInFile( readFileID ) == 0 ); g_pDataModel->UnloadFile( readFileID ); Shipping_Assert( g_pDataModel->NumElementsInFile( readFileID ) == 0 ); DmFileId_t readFileID2 = g_pDataModel->RestoreFromFile( pFileName, NULL, NULL, &pReadInRoot, CR_DELETE_NEW ); Shipping_Assert( readFileID2 == readFileID ); Shipping_Assert( g_pDataModel->GetElement( hRoot ) == pRoot ); Shipping_Assert( pRoot->GetHandle() == hRoot ); Shipping_Assert( pReadInRoot == pRoot ); // RestoreFromFile now returns the old element when the new root is deleted Shipping_Assert( g_pDataModel->NumElementsInFile( testFileID ) == nTestElements ); Shipping_Assert( g_pDataModel->NumElementsInFile( readFileID ) == 0 ); g_pDataModel->RemoveFileId( readFileID ); g_pDataModel->RemoveFileId( testFileID ); } void TestCopyNewCR( const char *pSerializationType ) { DmFileId_t testFileID = g_pDataModel->FindOrCreateFileId( "" ); DmElementHandle_t hRoot = CreateTestScene( testFileID ); int nTestElements = g_pDataModel->NumElementsInFile( testFileID ); const char *pFileName = "CopyNew.dmx"; CDmElement *pRoot = g_pDataModel->GetElement( hRoot ); bool bOk = g_pDataModel->SaveToFile( pFileName, NULL, pSerializationType, "dmx", pRoot ); Shipping_Assert( bOk ); CDmElement *pReadInRoot = NULL; DmFileId_t readFileID = g_pDataModel->RestoreFromFile( pFileName, NULL, NULL, &pReadInRoot, CR_COPY_NEW ); Shipping_Assert( readFileID != DMFILEID_INVALID ); if ( pReadInRoot ) { DmElementHandle_t hReadInRoot = pReadInRoot->GetHandle(); Shipping_Assert( g_pDataModel->GetElement( hRoot ) == pRoot ); Shipping_Assert( pRoot->GetHandle() == hRoot ); Shipping_Assert( pReadInRoot->GetHandle() != hRoot ); Shipping_Assert( !IsUniqueIdEqual( pRoot->GetId(), pReadInRoot->GetId() ) ); Shipping_Assert( g_pDataModel->NumElementsInFile( testFileID ) == nTestElements ); Shipping_Assert( g_pDataModel->NumElementsInFile( readFileID ) == nTestElements ); g_pDataModel->UnloadFile( readFileID ); Shipping_Assert( g_pDataModel->NumElementsInFile( readFileID ) == 0 ); Shipping_Assert( g_pDataModel->GetElement( hReadInRoot ) == NULL ); DmFileId_t readFileID2 = g_pDataModel->RestoreFromFile( pFileName, NULL, NULL, &pReadInRoot, CR_COPY_NEW ); Shipping_Assert( readFileID2 == readFileID ); Shipping_Assert( g_pDataModel->GetElement( hRoot ) == pRoot ); Shipping_Assert( pRoot->GetHandle() == hRoot ); Shipping_Assert( pReadInRoot->GetHandle() != hRoot ); Shipping_Assert( !IsUniqueIdEqual( pRoot->GetId(), pReadInRoot->GetId() ) ); Shipping_Assert( g_pDataModel->NumElementsInFile( testFileID ) == nTestElements ); Shipping_Assert( g_pDataModel->NumElementsInFile( readFileID ) == nTestElements ); g_pDataModel->RemoveFileId( readFileID ); } else { Msg( "Failed to load %s back from disk!!!", pFileName ); } g_pDataModel->RemoveFileId( testFileID ); } void TestForceCopyCR( const char *pSerializationType ) { DmFileId_t testFileID = g_pDataModel->FindOrCreateFileId( "" ); DmElementHandle_t hRoot = CreateTestScene( testFileID ); int nTestElements = g_pDataModel->NumElementsInFile( testFileID ); const char *pFileName = "ForceCopy.dmx"; CDmElement *pRoot = static_cast< CDmElement* >( g_pDataModel->GetElement( hRoot ) ); bool bOk = g_pDataModel->SaveToFile( pFileName, NULL, pSerializationType, "dmx", pRoot ); Shipping_Assert( bOk ); CDmElement *pReadInRoot = NULL; DmFileId_t readFileID = g_pDataModel->RestoreFromFile( pFileName, NULL, NULL, &pReadInRoot, CR_FORCE_COPY ); Shipping_Assert( readFileID != DMFILEID_INVALID ); if ( pReadInRoot ) { DmElementHandle_t hReadInRoot = pReadInRoot->GetHandle(); Shipping_Assert( g_pDataModel->GetElement( hRoot ) == pRoot ); Shipping_Assert( pRoot->GetHandle() == hRoot ); Shipping_Assert( pReadInRoot->GetHandle() != hRoot ); Shipping_Assert( !IsUniqueIdEqual( pRoot->GetId(), pReadInRoot->GetId() ) ); Shipping_Assert( g_pDataModel->NumElementsInFile( testFileID ) == nTestElements ); Shipping_Assert( g_pDataModel->NumElementsInFile( readFileID ) == nTestElements ); g_pDataModel->UnloadFile( readFileID ); Shipping_Assert( g_pDataModel->NumElementsInFile( readFileID ) == 0 ); Shipping_Assert( g_pDataModel->GetElement( hReadInRoot ) == NULL ); DmFileId_t readFileID2 = g_pDataModel->RestoreFromFile( pFileName, NULL, NULL, &pReadInRoot, CR_FORCE_COPY ); Shipping_Assert( readFileID2 == readFileID ); Shipping_Assert( g_pDataModel->GetElement( hRoot ) == pRoot ); Shipping_Assert( pRoot->GetHandle() == hRoot ); Shipping_Assert( pReadInRoot->GetHandle() != hRoot ); Shipping_Assert( !IsUniqueIdEqual( pRoot->GetId(), pReadInRoot->GetId() ) ); Shipping_Assert( g_pDataModel->NumElementsInFile( testFileID ) == nTestElements ); Shipping_Assert( g_pDataModel->NumElementsInFile( readFileID ) == nTestElements ); g_pDataModel->RemoveFileId( readFileID ); } else { Msg( "Failed to load %s back from disk!!!", pFileName ); } g_pDataModel->RemoveFileId( testFileID ); } void TestConflictResolution( const char *pSerializationType ) { TestDeleteOldCR( pSerializationType ); TestDeleteNewCR( pSerializationType ); TestCopyNewCR( pSerializationType ); TestForceCopyCR( pSerializationType ); } void TestSerializationMethod( const char *pSerializationType ) { DmFileId_t testFileID = g_pDataModel->FindOrCreateFileId( "" ); DmElementHandle_t hRoot = CreateTestScene( testFileID ); const char *pFileName = "dmxtest.dmx"; CDmElement *pRoot = static_cast(g_pDataModel->GetElement(hRoot)); bool bOk = g_pDataModel->SaveToFile( pFileName, NULL, pSerializationType, "dmx", pRoot ); Shipping_Assert( bOk ); CDmElement *pReadInRoot = NULL; DmFileId_t dmxFileID = g_pDataModel->RestoreFromFile( pFileName, NULL, NULL, &pReadInRoot, CR_FORCE_COPY ); Shipping_Assert( dmxFileID != DMFILEID_INVALID ); if ( pReadInRoot ) { AssertEqualElementHierarchies( false, hRoot, pReadInRoot->GetHandle() ); g_pDataModel->RemoveFileId( dmxFileID ); } else { Msg( "Failed to load dmxtest.dmx back from disk!!!" ); } g_pDataModel->RemoveFileId( testFileID ); TestConflictResolution( pSerializationType ); } DEFINE_TESTCASE_NOSUITE( DmxSerializationTest ) { Msg( "Running dmx serialization tests...\n" ); CDisableUndoScopeGuard sg; TestSerializationMethod( "keyvalues2" ); TestSerializationMethod( "keyvalues2_flat" ); TestSerializationMethod( "xml" ); TestSerializationMethod( "xml_flat" ); TestSerializationMethod( "binary" ); int nEndingCount = g_pDataModel->GetAllocatedElementCount(); AssertEqualsTest( false, 0, nEndingCount ); }