//========= 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 "movieobjects/movieobjects.h" #include "tier1/utlbuffer.h" #include "filesystem.h" // From dmxtestserialization.cpp bool AssertEqualElementHierarchies( bool quiet, DmElementHandle_t src1, DmElementHandle_t src2 ); bool AssertUnEqualElementHierarchies( DmElementHandle_t src1, DmElementHandle_t src2 ); void CreateTestScene( CUtlVector< DmElementHandle_t >& handles, DmFileId_t fileid ); bool AssertEqualElementHierarchies( bool quiet, CDmElement *src1, CDmElement *src2 ) { DmElementHandle_t h1 = src1->GetHandle(); DmElementHandle_t h2 = src2->GetHandle(); return AssertEqualElementHierarchies( quiet, h1, h2 ); } bool AssertUnEqualElementHierarchies( CDmElement *src1, CDmElement *src2 ) { return AssertUnEqualElementHierarchies( src1->GetHandle(), src2->GetHandle() ); } //----------------------------------------------------------------------------- // Purpose: // Input : - //----------------------------------------------------------------------------- void DescribeUndo() { CUtlVector< UndoInfo_t > list; g_pDataModel->GetUndoInfo( list ); for ( int i = list.Count() - 1; i >= 0; --i ) { UndoInfo_t& entry = list[ i ]; if ( entry.terminator ) { Msg( "[ '%s' ] -- %i operations\n", entry.undo, entry.numoperations ); } Msg( " +[ '%s' ]\n", entry.desc ); } } template< class T > void RunSingleSetAttributeUndoTest( CDmElement *pTest, CDmElement *pOriginal, CDmElement *pElement, const char *attribute, const T& newVal ) { { CUndoScopeGuard guard( attribute, attribute ); pElement->SetValue( attribute, newVal ); } g_pDataModel->Undo(); AssertEqualElementHierarchies( false, pTest, pOriginal ); g_pDataModel->Redo(); g_pDataModel->Undo(); AssertEqualElementHierarchies( false, pTest, pOriginal ); } void RunSingleSetAttributeUndoTestBinary( CDmElement *pTest, CDmElement *pOriginal, CDmElement *pElement, const char *attribute, const void *data, size_t size ) { { CUndoScopeGuard guard( attribute, attribute ); pElement->SetValue( attribute, data, size ); } AssertUnEqualElementHierarchies( pTest, pOriginal ); g_pDataModel->Undo(); AssertEqualElementHierarchies( false, pTest, pOriginal ); g_pDataModel->Redo(); AssertUnEqualElementHierarchies( pTest, pOriginal ); g_pDataModel->Undo(); AssertEqualElementHierarchies( false, pTest, pOriginal ); } template< class T > void RunSingleSetAttributeUndoTestArray( CDmElement *pTest, CDmElement *pOriginal, CDmElement *pElement, const char *attribute, int slot, const T& newVal ) { { CUndoScopeGuard guard( attribute, attribute ); CDmrArray< T > array( pElement, attribute ); array.Set( slot, newVal ); } AssertUnEqualElementHierarchies( pTest, pOriginal ); g_pDataModel->Undo(); AssertEqualElementHierarchies( false, pTest, pOriginal ); g_pDataModel->Redo(); AssertUnEqualElementHierarchies( pTest, pOriginal ); g_pDataModel->Undo(); AssertEqualElementHierarchies( false, pTest, pOriginal ); } template<> void RunSingleSetAttributeUndoTestArray( CDmElement *pTest, CDmElement *pOriginal, CDmElement *pElement, const char *attribute, int slot, const DmElementHandle_t& newVal ) { { CUndoScopeGuard guard( attribute, attribute ); CDmrElementArray<> array( pElement, attribute ); array.SetHandle( slot, newVal ); } AssertUnEqualElementHierarchies( pTest, pOriginal ); g_pDataModel->Undo(); AssertEqualElementHierarchies( false, pTest, pOriginal ); g_pDataModel->Redo(); AssertUnEqualElementHierarchies( pTest, pOriginal ); g_pDataModel->Undo(); AssertEqualElementHierarchies( false, pTest, pOriginal ); } template< class T > void RunSingleAttributeUndoTestArrayAddToHead( CDmElement *pTest, CDmElement *pOriginal, CDmElement *pElement, const char *attribute, const T& newVal ) { { CUndoScopeGuard guard( attribute, attribute ); CDmrArray< T > array( pElement, attribute ); array.InsertBefore( 0, newVal ); } AssertUnEqualElementHierarchies( pTest, pOriginal ); g_pDataModel->Undo(); AssertEqualElementHierarchies( false, pTest, pOriginal ); g_pDataModel->Redo(); AssertUnEqualElementHierarchies( pTest, pOriginal ); g_pDataModel->Undo(); AssertEqualElementHierarchies( false, pTest, pOriginal ); } template< class T > void RunSingleAttributeUndoTestArrayAddToTail( CDmElement *pTest, CDmElement *pOriginal, CDmElement *pElement, const char *attribute, const T& newVal ) { { CUndoScopeGuard guard( attribute, attribute ); CDmrArray< T > array( pElement, attribute ); array.AddToTail( newVal ); } AssertUnEqualElementHierarchies( pTest, pOriginal ); g_pDataModel->Undo(); AssertEqualElementHierarchies( false, pTest, pOriginal ); g_pDataModel->Redo(); AssertUnEqualElementHierarchies( pTest, pOriginal ); g_pDataModel->Undo(); AssertEqualElementHierarchies( false, pTest, pOriginal ); } template< class T > void RunSingleAttributeUndoTestArrayInsertBefore( CDmElement *pTest, CDmElement *pOriginal, CDmElement *pElement, const char *attribute, int slot, const T& newVal ) { { CUndoScopeGuard guard( attribute, attribute ); CDmrArray< T > array( pElement, attribute ); array.InsertBefore( slot, newVal ); } AssertUnEqualElementHierarchies( pTest, pOriginal ); g_pDataModel->Undo(); AssertEqualElementHierarchies( false, pTest, pOriginal ); g_pDataModel->Redo(); AssertUnEqualElementHierarchies( pTest, pOriginal ); g_pDataModel->Undo(); AssertEqualElementHierarchies( false, pTest, pOriginal ); } template< class T > void RunSingleAttributeUndoTestArrayFastRemove( CDmElement *pTest, CDmElement *pOriginal, CDmElement *pElement, const char *attribute, int slot, T typeDeducer ) { { CUndoScopeGuard guard( attribute, attribute ); CDmrArray< T > array( pElement, attribute ); array.FastRemove( slot ); } AssertUnEqualElementHierarchies( pTest, pOriginal ); g_pDataModel->Undo(); AssertEqualElementHierarchies( false, pTest, pOriginal ); g_pDataModel->Redo(); AssertUnEqualElementHierarchies( pTest, pOriginal ); g_pDataModel->Undo(); AssertEqualElementHierarchies( false, pTest, pOriginal ); } void RunSingleAttributeUndoTestElementArrayRemove( CDmElement *pTest, CDmElement *pOriginal, CDmElement *pElement, const char *attribute, int slot ) { { CUndoScopeGuard guard( attribute, attribute ); CDmrElementArray<> array( pElement, attribute ); array.Remove( slot ); } DescribeUndo(); AssertUnEqualElementHierarchies( pTest, pOriginal ); g_pDataModel->Undo(); AssertEqualElementHierarchies( false, pTest, pOriginal ); g_pDataModel->Redo(); AssertUnEqualElementHierarchies( pTest, pOriginal ); g_pDataModel->Undo(); AssertEqualElementHierarchies( false, pTest, pOriginal ); } template< class T > void RunSingleAttributeUndoTestArrayRemove( CDmElement *pTest, CDmElement *pOriginal, CDmElement *pElement, const char *attribute, int slot, T typeDeducer ) { { CUndoScopeGuard guard( attribute, attribute ); CDmrArray array( pElement, attribute ); array.Remove( slot ); } AssertUnEqualElementHierarchies( pTest, pOriginal ); g_pDataModel->Undo(); AssertEqualElementHierarchies( false, pTest, pOriginal ); g_pDataModel->Redo(); AssertUnEqualElementHierarchies( pTest, pOriginal ); g_pDataModel->Undo(); AssertEqualElementHierarchies( false, pTest, pOriginal ); } template< class T > void RunSingleAttributeUndoTestArrayRemoveMultiple( CDmElement *pTest, CDmElement *pOriginal, CDmElement *pElement, const char *attribute, int slot, int count, T typeDeducer ) { { CUndoScopeGuard guard( attribute, attribute ); CDmrArray< T > array( pElement, attribute ); array.RemoveMultiple( slot, count ); } AssertUnEqualElementHierarchies( pTest, pOriginal ); g_pDataModel->Undo(); AssertEqualElementHierarchies( false, pTest, pOriginal ); g_pDataModel->Redo(); AssertUnEqualElementHierarchies( pTest, pOriginal ); g_pDataModel->Undo(); AssertEqualElementHierarchies( false, pTest, pOriginal ); } template< class T > void RunSingleAttributeUndoTestArrayRemoveAll( CDmElement *pTest, CDmElement *pOriginal, CDmElement *pElement, const char *attribute, bool purge ) { { CUndoScopeGuard guard( attribute, attribute ); CDmrArray< T > array( pElement, attribute ); if( purge ) { array.Purge(); } else { array.RemoveAll(); } } AssertUnEqualElementHierarchies( pTest, pOriginal ); g_pDataModel->Undo(); AssertEqualElementHierarchies( false, pTest, pOriginal ); g_pDataModel->Redo(); AssertUnEqualElementHierarchies( pTest, pOriginal ); g_pDataModel->Undo(); AssertEqualElementHierarchies( false, pTest, pOriginal ); } template< class T > void RunSingleAttributeUndoTestArrayCopyFrom( CDmElement *pTest, CDmElement *pOriginal, CDmElement *pElement, const char *attribute, const CUtlVector& list ) { { CUndoScopeGuard guard( attribute, attribute ); CDmrArray array( pElement, attribute ); array.CopyArray( list.Base(), list.Count() ); } AssertUnEqualElementHierarchies( pTest, pOriginal ); g_pDataModel->Undo(); AssertEqualElementHierarchies( false, pTest, pOriginal ); g_pDataModel->Redo(); AssertUnEqualElementHierarchies( pTest, pOriginal ); g_pDataModel->Undo(); AssertEqualElementHierarchies( false, pTest, pOriginal ); } void RunSingleSetAttributeUndoTestArrayBinary( CDmElement *pTest, CDmElement *pOriginal, CDmElement *pElement, const char *attribute, int slot, const void *data, size_t size ) { { CUndoScopeGuard guard( attribute, attribute ); CUtlBinaryBlock block( (const void *)data, size ); CDmrArray< CUtlBinaryBlock > array( pElement, attribute ); array.Set( slot, block ); } AssertUnEqualElementHierarchies( pTest, pOriginal ); g_pDataModel->Undo(); AssertEqualElementHierarchies( false, pTest, pOriginal ); g_pDataModel->Redo(); AssertUnEqualElementHierarchies( pTest, pOriginal ); g_pDataModel->Undo(); AssertEqualElementHierarchies( false, pTest, pOriginal ); } template< class T > void RunSingleSetAttributeUndoTestArrayWhole( CDmElement *pTest, CDmElement *pOriginal, CDmElement *pElement, const char *attribute, CUtlVector< T >& newVal ) { { CUndoScopeGuard guard( attribute, attribute ); IDmAttributeArray< T > *pArray = static_cast< IDmAttributeArray< T > * >( pElement->GetAttribute( "attribute" ) ); pArray->SetValue( newVal ); } AssertUnEqualElementHierarchies( pTest, pOriginal ); g_pDataModel->Undo(); AssertEqualElementHierarchies( false, pTest, pOriginal ); g_pDataModel->Redo(); AssertUnEqualElementHierarchies( pTest, pOriginal ); g_pDataModel->Undo(); AssertEqualElementHierarchies( false, pTest, pOriginal ); } template< class T > void RunSingleAddAttributeUndoTest( CDmElement *pTest, CDmElement *pOriginal, CDmElement *pElement, const char *attribute, const T& newVal ) { { CUndoScopeGuard guard( attribute, attribute ); pElement->SetValue( attribute, newVal ); } AssertUnEqualElementHierarchies( pTest, pOriginal ); g_pDataModel->Undo(); AssertEqualElementHierarchies( false, pTest, pOriginal ); g_pDataModel->Redo(); AssertUnEqualElementHierarchies( pTest, pOriginal ); g_pDataModel->Undo(); AssertEqualElementHierarchies( false, pTest, pOriginal ); } void RunSingleRemoveAttributeUndoTest( CDmElement *pTest, CDmElement *pOriginal, CDmElement *pElement, const char *attribute ) { AssertEqualElementHierarchies( false, pTest, pOriginal ); { CUndoScopeGuard guard( attribute, attribute ); pElement->RemoveAttribute( attribute ); } AssertUnEqualElementHierarchies( pTest, pOriginal ); g_pDataModel->Undo(); AssertEqualElementHierarchies( false, pTest, pOriginal ); g_pDataModel->Redo(); AssertUnEqualElementHierarchies( pTest, pOriginal ); g_pDataModel->Undo(); AssertEqualElementHierarchies( false, pTest, pOriginal ); } void RunUndoTestsArray( CUtlVector< DmElementHandle_t >& handles, CDmElement *pTest, CDmElement *pOriginal ) { DmObjectId_t id; CreateUniqueId( &id ); VMatrix mat, mat2; MatrixBuildRotateZ( mat, 55 ); MatrixBuildRotateZ( mat2, -55 ); int i; unsigned char buf[256]; unsigned char buf2[256]; for ( i = 0; i < 256; ++i ) { buf[i] = i+55500; buf2[i] = 55000 + 255 - i; } Assert( handles.Count() == 7 ); //CDmElement *pElement = pTest; CDmElement *pElement2 = GetElement< CDmElement >( handles[ 1 ] ); CDmElement *pElement3 = GetElement< CDmElement >( handles[ 2 ] ); CDmElement *pElement4 = GetElement< CDmElement >( handles[ 3 ] ); CDmElement *pElement5 = GetElement< CDmElement >( handles[ 4 ] ); CDmElement *pElement6 = GetElement< CDmElement >( handles[ 5 ] ); CDmElement *pElement7 = GetElement< CDmElement >( handles[ 6 ] ); RunSingleSetAttributeUndoTestArray( pTest, pOriginal, pElement2, "int_array_test", 0, 55 ); RunSingleSetAttributeUndoTestArray( pTest, pOriginal, pElement2, "float_array_test", 0, 55.0f ); RunSingleSetAttributeUndoTestArray( pTest, pOriginal, pElement2, "bool_array_test", 0, true ); RunSingleSetAttributeUndoTestArray( pTest, pOriginal, pElement3, "color_array_test", 0, Color( 55, 55, 55, 55 ) ); RunSingleSetAttributeUndoTestArray( pTest, pOriginal, pElement3, "vector2d_array_test", 0, Vector2D( 55.0f, -55.0f ) ); RunSingleSetAttributeUndoTestArray( pTest, pOriginal, pElement3, "vector3d_array_test", 0, Vector( 55.0f, -55.0f, 55.0f ) ); RunSingleSetAttributeUndoTestArray( pTest, pOriginal, pElement4, "vector4d_array_test", 0, Vector4D( 55.0f, -55.0f, 55.0f, 55.0f ) ); RunSingleSetAttributeUndoTestArray( pTest, pOriginal, pElement4, "qangle_array_test", 0, QAngle( 55.0f, 55.0f, -55.0f ) ); RunSingleSetAttributeUndoTestArray( pTest, pOriginal, pElement4, "quat_array_test", 0, Quaternion( 1.0f, -1.0f, 0.0f, 55.0f ) ); RunSingleSetAttributeUndoTestArray( pTest, pOriginal, pElement5, "vmatrix_array_test", 0, mat ); CUtlString newString( "55test" ); RunSingleSetAttributeUndoTestArray( pTest, pOriginal, pElement5, "string_array_test", 0, newString ); RunSingleSetAttributeUndoTestArrayBinary( pTest, pOriginal, pElement5, "binary_array_test", 0, buf, 256 ); // RunSingleSetAttributeUndoTestArray( pTest, pOriginal, pElement6, "elementid_array_test", 0, id ); RunSingleSetAttributeUndoTestArray( pTest, pOriginal, pElement6, "element_array_test", 0, pElement2->GetHandle() ); RunSingleSetAttributeUndoTestArray( pTest, pOriginal, pElement7, "element_array_test", 0, pElement5->GetHandle() ); { RunSingleSetAttributeUndoTestArray( pTest, pOriginal, pElement2, "int_array_test", 0, 55 ); RunSingleSetAttributeUndoTestArray( pTest, pOriginal, pElement2, "float_array_test", 0, 55.0f ); RunSingleSetAttributeUndoTestArray( pTest, pOriginal, pElement2, "bool_array_test", 0, true ); RunSingleSetAttributeUndoTestArray( pTest, pOriginal, pElement3, "color_array_test", 0, Color( 55, 55, 55, 55 ) ); RunSingleSetAttributeUndoTestArray( pTest, pOriginal, pElement3, "vector2d_array_test", 0, Vector2D( 55.0f, -55.0f ) ); RunSingleSetAttributeUndoTestArray( pTest, pOriginal, pElement3, "vector3d_array_test", 0, Vector( 55.0f, -55.0f, 55.0f ) ); RunSingleSetAttributeUndoTestArray( pTest, pOriginal, pElement4, "vector4d_array_test", 0, Vector4D( 55.0f, -55.0f, 55.0f, 55.0f ) ); RunSingleSetAttributeUndoTestArray( pTest, pOriginal, pElement4, "qangle_array_test", 0, QAngle( 55.0f, 55.0f, -55.0f ) ); RunSingleSetAttributeUndoTestArray( pTest, pOriginal, pElement4, "quat_array_test", 0, Quaternion( 1.0f, -1.0f, 0.0f, 55.0f ) ); RunSingleSetAttributeUndoTestArray( pTest, pOriginal, pElement5, "vmatrix_array_test", 0, mat ); CUtlString newString( "55test" ); RunSingleSetAttributeUndoTestArray( pTest, pOriginal, pElement5, "string_array_test", 0, newString ); RunSingleSetAttributeUndoTestArrayBinary( pTest, pOriginal, pElement5, "binary_array_test", 0, buf, 256 ); // RunSingleSetAttributeUndoTestArray( pTest, pOriginal, pElement6, "elementid_array_test", 0, id ); RunSingleSetAttributeUndoTestArray( pTest, pOriginal, pElement6, "element_array_test", 0, pElement2->GetHandle() ); RunSingleSetAttributeUndoTestArray( pTest, pOriginal, pElement7, "element_array_test", 0, pElement5->GetHandle() ); } RunSingleAttributeUndoTestArrayAddToHead( pTest, pOriginal, pElement2, "int_array_test", 55 ); RunSingleAttributeUndoTestArrayAddToTail( pTest, pOriginal, pElement2, "int_array_test", 55 ); RunSingleAttributeUndoTestArrayInsertBefore( pTest, pOriginal, pElement2, "int_array_test", 0, 55 ); RunSingleAttributeUndoTestArrayFastRemove( pTest, pOriginal, pElement2, "int_array_test", 0, (int)0 ); RunSingleAttributeUndoTestArrayRemove( pTest, pOriginal, pElement2, "int_array_test", 0, (int)0 ); RunSingleAttributeUndoTestArrayRemoveMultiple( pTest, pOriginal, pElement2, "int_array_test", 0, 2, (int)0 ); RunSingleAttributeUndoTestElementArrayRemove( pTest, pOriginal, pElement7, "children", 0 ); // RemoveAll RunSingleAttributeUndoTestArrayRemoveAll( pTest, pOriginal, pElement2, "int_array_test", false ); // Purge RunSingleAttributeUndoTestArrayRemoveAll( pTest, pOriginal, pElement2, "int_array_test", true ); CUtlVector< int > foo; foo.AddToTail( 55 ); foo.AddToTail( 56 ); foo.AddToTail( 57 ); foo.AddToTail( 58 ); foo.AddToTail( 59 ); RunSingleAttributeUndoTestArrayCopyFrom( pTest, pOriginal, pElement2, "int_array_test", foo ); } void RunUndoTests( CUtlVector< DmElementHandle_t >& handles, CDmElement *pTest, CDmElement *pOriginal ) { DmObjectId_t id; CreateUniqueId( &id ); VMatrix mat, mat2; MatrixBuildRotateZ( mat, 55 ); MatrixBuildRotateZ( mat2, -55 ); int i; unsigned char buf[256]; unsigned char buf2[256]; for ( i = 0; i < 256; ++i ) { buf[i] = i+100; buf2[i] = 127 + 255 - i; } Assert( handles.Count() == 7 ); CDmElement *pElement = pTest; CDmElement *pElement2 = GetElement( handles[ 1 ] ); RunSingleSetAttributeUndoTest( pTest, pOriginal, pElement, "element_test", (CDmElement *)NULL ); RunSingleSetAttributeUndoTest( pTest, pOriginal, pElement, "int_test", 55 ); RunSingleSetAttributeUndoTest( pTest, pOriginal, pElement, "float_test", 55.0f ); RunSingleSetAttributeUndoTest( pTest, pOriginal, pElement, "bool_test", false ); // RunSingleSetAttributeUndoTest( pTest, pOriginal, pElement, "id_test", id ); RunSingleSetAttributeUndoTest( pTest, pOriginal, pElement, "string_test", "55test" ); RunSingleSetAttributeUndoTestBinary( pTest, pOriginal, pElement, "binary_test", buf, 256 ); RunSingleSetAttributeUndoTest( pTest, pOriginal, pElement, "color_test", Color( 55, 55, 55, 55 ) ); RunSingleSetAttributeUndoTest( pTest, pOriginal, pElement, "vector2d_test", Vector2D( 55.0f, -55.0f ) ); RunSingleSetAttributeUndoTest( pTest, pOriginal, pElement, "vector3d_test", Vector( 55.0f, -55.0f, 55.0f ) ); RunSingleSetAttributeUndoTest( pTest, pOriginal, pElement, "vector4d_test", Vector4D( 55.0f, -55.0f, 55.0f, 55.0f ) ); RunSingleSetAttributeUndoTest( pTest, pOriginal, pElement, "qangle_test", QAngle( 55.0f, 55.0f, -55.0f ) ); RunSingleSetAttributeUndoTest( pTest, pOriginal, pElement, "quat_test", Quaternion( 1.0f, -1.0f, 0.0f, 55.0f ) ); RunSingleSetAttributeUndoTest( pTest, pOriginal, pElement, "vmatrix_test", mat ); // Now run a single test with a bunch of operations occurring at the same time { { CUndoScopeGuard guard( "biggish", "smallish" ); pElement->SetValue( "bool_test", false ); pElement->SetValue( "int_test", 55 ); pElement->SetValue( "float_test", 55.0f ); pElement->SetValue( "color_test", Color( 55, 55, 55, 55 ) ); pElement->SetValue( "vector2d_test", Vector2D( 55.0f, -55.0f ) ); pElement->SetValue( "vector3d_test", Vector( 55.0f, -55.0f, 55.0f ) ); pElement->SetValue( "vector4d_test", Vector4D( 55.0f, -55.0f, 55.0f, 55.0f ) ); pElement->SetValue( "qangle_test", QAngle( 55.0f, 55.0f, -55.0f ) ); pElement->SetValue( "quat_test", Quaternion( 1.0f, -1.0f, 0.0f, 55.0f ) ); pElement->SetValue( "vmatrix_test", mat ); pElement->SetValue( "string_test", "55test" ); pElement->SetValue( "binary_test", buf, 256 ); } g_pDataModel->Undo(); AssertEqualElementHierarchies( false, pTest, pOriginal ); g_pDataModel->Redo(); g_pDataModel->Undo(); AssertEqualElementHierarchies( false, pTest, pOriginal ); } // Now run a test with multiple items in the stack { // Push 1 { CUndoScopeGuard guard( "biggish1", "smallish1" ); pElement->SetValue( "bool_test", false ); pElement->SetValue( "int_test", 55 ); pElement->SetValue( "float_test", 55.0f ); pElement->SetValue( "color_test", Color( 55, 55, 55, 55 ) ); } // Push 2 { CUndoScopeGuard guard( "biggish2", "smallish2" ); pElement->SetValue( "vector2d_test", Vector2D( 55.0f, -55.0f ) ); pElement->SetValue( "vector3d_test", Vector( 55.0f, -55.0f, 55.0f ) ); pElement->SetValue( "vector4d_test", Vector4D( 55.0f, -55.0f, 55.0f, 55.0f ) ); pElement->SetValue( "qangle_test", QAngle( 55.0f, 55.0f, -55.0f ) ); pElement->SetValue( "quat_test", Quaternion( 1.0f, -1.0f, 0.0f, 55.0f ) ); } // Push 3 { CUndoScopeGuard guard( "biggish3", "smallish3" ); pElement->SetValue( "vmatrix_test", mat ); pElement->SetValue( "string_test", "55test" ); pElement->SetValue( "binary_test", buf, 256 ); } // Tests { g_pDataModel->Undo(); g_pDataModel->Undo(); g_pDataModel->Undo(); AssertEqualElementHierarchies( false, pTest, pOriginal ); g_pDataModel->Redo(); g_pDataModel->Redo(); g_pDataModel->Redo(); g_pDataModel->Undo(); g_pDataModel->Undo(); g_pDataModel->Undo(); AssertEqualElementHierarchies( false, pTest, pOriginal ); } } // Now run "add" tests on a subset -- add adds an attribute where one didn't already exist RunSingleAddAttributeUndoTest( pTest, pOriginal, pElement2, "int_test_added", 55 ); // Now run "remove" tests on a subset of attributes -- removes an existing attribute by name RunSingleRemoveAttributeUndoTest( pTest, pOriginal, pTest, "int_test" ); } #include "datamodel/dmehandle.h" void RunUndoTestCreateElement() { DmFileId_t fileid = g_pDataModel->FindOrCreateFileId( "" ); CDmElement *element = NULL; { CUndoScopeGuard guard( "create" ); element = CreateElement< CDmElement >( "test", fileid ); } CDmeHandle< CDmElement > hChannel; hChannel = element; Assert( hChannel.Get() ); g_pDataModel->Undo(); Assert( !hChannel.Get() ); g_pDataModel->Redo(); Assert( hChannel.Get() ); g_pDataModel->Undo(); // It's on the redo stack, but marked as kill and all ptrs are NULL to it Assert( !hChannel.Get() ); g_pDataModel->ClearUndo(); g_pDataModel->ClearRedo(); g_pDataModel->RemoveFileId( fileid ); } DEFINE_TESTCASE_NOSUITE( DmxUndoRedoTest ) { Msg( "Running undo tests...\n" ); #ifdef _DEBUG int nStartingCount = g_pDataModel->GetAllocatedElementCount(); #endif CUndoScopeGuard sg( "Create Test Scenes" ); DmFileId_t fileid = g_pDataModel->FindOrCreateFileId( "" ); CUtlVector< DmElementHandle_t > handles; CreateTestScene( handles, fileid ); DmElementHandle_t hOriginal = handles[ 0 ]; handles.RemoveAll(); CreateTestScene( handles, fileid ); DmElementHandle_t hTest = handles[ 0 ]; sg.Release(); CDmElement *pOriginal = static_cast( g_pDataModel->GetElement( hOriginal ) ); CDmElement *pTest = static_cast(g_pDataModel->GetElement( hTest ) ); AssertEqualElementHierarchies( false, pTest, pOriginal ); RunUndoTests( handles, pTest, pOriginal ); RunUndoTestsArray( handles, pTest, pOriginal ); RunUndoTestCreateElement(); g_pDataModel->ClearUndo(); g_pDataModel->RemoveFileId( fileid ); #ifdef _DEBUG int nEndingCount = g_pDataModel->GetAllocatedElementCount(); AssertEquals( nEndingCount, nStartingCount ); if ( nEndingCount != nStartingCount ) { for ( DmElementHandle_t hElement = g_pDataModel->FirstAllocatedElement() ; hElement != DMELEMENT_HANDLE_INVALID; hElement = g_pDataModel->NextAllocatedElement( hElement ) ) { CDmElement *pElement = g_pDataModel->GetElement( hElement ); Assert( pElement ); if ( !pElement ) return; Msg( "[%s : %s] in memory\n", pElement->GetName(), pElement->GetTypeString() ); } } #endif } #include "datamodel/dmelementfactoryhelper.h" //----------------------------------------------------------------------------- // CDmeExternal - element class used for testing external attributes //----------------------------------------------------------------------------- class CDmeExternal : public CDmElement { DEFINE_ELEMENT( CDmeExternal, CDmElement ); public: CDmaVar< float > m_External; }; IMPLEMENT_ELEMENT_FACTORY( DmeExternal, CDmeExternal ); void CDmeExternal::OnConstruction() { m_External .InitAndSet( this, "external", 99.9f ); } void CDmeExternal::OnDestruction() { } USING_ELEMENT_FACTORY( DmeExternal ); DEFINE_TESTCASE_NOSUITE( DmxExternalAttributeTest ) { Msg( "Running external attribute test...\n" ); DmFileId_t fileid = g_pDataModel->FindOrCreateFileId( "" ); CDmeExternal *pOriginal = 0; #ifdef _DEBUG int nStartingCount = g_pDataModel->GetAllocatedElementCount(); #endif { CUndoScopeGuard guard( "External" ); pOriginal = CreateElement( "foo", fileid ); for ( int m = 0; m < 1; ++m ) { CDmeExternal *discard = CreateElement( "foo", fileid ); g_pDataModel->DestroyElement( discard->GetHandle() ); } } // Now mess with vars g_pDataModel->Undo(); g_pDataModel->Redo(); { CUndoScopeGuard guard( "External2" ); pOriginal->m_External.Set( 100.0f ); } g_pDataModel->ClearUndo(); g_pDataModel->RemoveFileId( fileid ); #ifdef _DEBUG int nEndingCount = g_pDataModel->GetAllocatedElementCount(); AssertEquals( nEndingCount, nStartingCount ); if ( nEndingCount != nStartingCount ) { for ( DmElementHandle_t hElement = g_pDataModel->FirstAllocatedElement() ; hElement != DMELEMENT_HANDLE_INVALID; hElement = g_pDataModel->NextAllocatedElement( hElement ) ) { CDmElement *pElement = g_pDataModel->GetElement( hElement ); Assert( pElement ); if ( !pElement ) return; Msg( "[%s : %s] in memory\n", pElement->GetName(), pElement->GetTypeString() ); } } #endif } void Assert_InvalidAndNULL( CDmeHandle< CDmElement > &hElement ) { Shipping_Assert( !hElement.Get() ); if ( !hElement.Get() ) { g_pDataModel->MarkHandleValid( hElement.GetHandle() ); Shipping_Assert( !hElement.Get() ); if ( hElement.Get() ) { g_pDataModel->MarkHandleInvalid( hElement.GetHandle() ); } } } void Assert_InvalidButNonNULL( CDmeHandle< CDmElement > &hElement ) { Shipping_Assert( !hElement.Get() ); if ( !hElement.Get() ) { g_pDataModel->MarkHandleValid( hElement.GetHandle() ); Shipping_Assert( hElement.Get() ); if ( hElement.Get() ) { g_pDataModel->MarkHandleInvalid( hElement.GetHandle() ); } } } void Assert_ValidAndNonNULL( CDmeHandle< CDmElement > &hElement ) { Shipping_Assert( hElement.Get() ); } DEFINE_TESTCASE_NOSUITE( DmxReferenceCountingTest ) { Msg( "Running external attribute test...\n" ); DmFileId_t fileid = g_pDataModel->FindOrCreateFileId( "" ); CDmeHandle< CDmElement > hRoot; CDmeHandle< CDmElement > hChild1, hChild2, hChild3, hChild4, hChild5; CDmeHandle< CDmElement > hGrandChild1, hGrandChild2, hGrandChild3, hGrandChild4, hGrandChild5, hGrandChild6, hGrandChild7; CDmeCountedHandle hStrong6, hStrong7; g_pDmElementFramework->BeginEdit(); int nStartingCount = g_pDataModel->GetAllocatedElementCount(); Shipping_Assert( nStartingCount == 0 ); { CUndoScopeGuard guard( "Create RefCountTest Elements" ); hRoot = CreateElement( "root", fileid ); CDmrElementArray<> arrayRoot( hRoot, "children", true ); g_pDataModel->SetFileRoot( fileid, hRoot->GetHandle() ); hChild1 = CreateElement( "child1", fileid ); CDmrElementArray<> arrayChild1( hChild1, "children", true ); arrayRoot.AddToTail( hChild1.Get() ); hChild2 = CreateElement( "child2", fileid ); hChild2->AddAttributeElement( "child" ); arrayRoot.AddToTail( hChild2.Get() ); hChild3 = CreateElement( "child3", fileid ); hChild3->AddAttributeElement( "child" ); arrayRoot.AddToTail( hChild3.Get() ); hChild4 = CreateElement( "child4", fileid ); hChild4->AddAttributeElement( "child" ); arrayRoot.AddToTail( hChild4.Get() ); hChild5 = CreateElement( "child5", fileid ); CDmrElementArray<> arrayChild5( hChild5, "children", true ); arrayRoot.AddToTail( hChild5.Get() ); hGrandChild1 = CreateElement( "grandchild1", fileid ); arrayChild1.AddToTail( hGrandChild1.Get() ); hGrandChild2 = CreateElement( "grandchild2", fileid ); arrayChild1.AddToTail( hGrandChild2.Get() ); hChild2->SetValue( "child", hGrandChild2.GetHandle() ); hGrandChild3 = CreateElement( "grandchild3", fileid ); arrayChild1.AddToTail( hGrandChild3.Get() ); hChild3->SetValue( "child", hGrandChild3.GetHandle() ); hGrandChild4 = CreateElement( "grandchild4", fileid ); arrayChild1.AddToTail( hGrandChild4.Get() ); hChild4->SetValue( "child", hGrandChild4.GetHandle() ); hGrandChild5 = CreateElement( "grandchild5", fileid ); arrayChild1.AddToTail( hGrandChild5.Get() ); arrayChild5.AddToTail( hGrandChild5.Get() ); hGrandChild6 = CreateElement( "grandchild6", fileid ); arrayChild1.AddToTail( hGrandChild6.Get() ); hStrong6 = hGrandChild6; hGrandChild7 = CreateElement( "grandchild7", fileid ); arrayChild1.AddToTail( hGrandChild7.Get() ); hStrong7 = hGrandChild7; } g_pDmElementFramework->BeginEdit(); int nCreateCount = g_pDataModel->GetAllocatedElementCount(); Assert( nCreateCount == nStartingCount + 13 ); Assert_ValidAndNonNULL ( hRoot ); Assert_ValidAndNonNULL ( hChild1 ); Assert_ValidAndNonNULL ( hChild2 ); Assert_ValidAndNonNULL ( hChild3 ); Assert_ValidAndNonNULL ( hChild4 ); Assert_ValidAndNonNULL ( hChild5 ); Assert_ValidAndNonNULL ( hGrandChild1 ); Assert_ValidAndNonNULL ( hGrandChild2 ); Assert_ValidAndNonNULL ( hGrandChild3 ); Assert_ValidAndNonNULL ( hGrandChild4 ); Assert_ValidAndNonNULL ( hGrandChild5 ); Assert_ValidAndNonNULL ( hGrandChild6 ); Assert_ValidAndNonNULL ( hGrandChild7 ); g_pDataModel->ClearUndo(); g_pDmElementFramework->BeginEdit(); int nPostCreateCount = g_pDataModel->GetAllocatedElementCount(); Shipping_Assert( nPostCreateCount == nCreateCount ); Assert_ValidAndNonNULL ( hRoot ); Assert_ValidAndNonNULL ( hChild1 ); Assert_ValidAndNonNULL ( hChild2 ); Assert_ValidAndNonNULL ( hChild3 ); Assert_ValidAndNonNULL ( hChild4 ); Assert_ValidAndNonNULL ( hChild5 ); Assert_ValidAndNonNULL ( hGrandChild1 ); Assert_ValidAndNonNULL ( hGrandChild2 ); Assert_ValidAndNonNULL ( hGrandChild3 ); Assert_ValidAndNonNULL ( hGrandChild4 ); Assert_ValidAndNonNULL ( hGrandChild5 ); Assert_ValidAndNonNULL ( hGrandChild6 ); Assert_ValidAndNonNULL ( hGrandChild7 ); { CUndoScopeGuard guard( "Edit RefCountTest Elements" ); CDmrGenericArray children( hChild1, "children" ); children.RemoveAll(); // grandchild1 unref'ed to 0, grandchild2..6 unref'ed to 1 hChild2->SetValue( "child", DMELEMENT_HANDLE_INVALID ); // grandchild2 unref'ed to 0 g_pDataModel->DestroyElement( hChild3 ); // grandchild3 is unref'ed to 0 CDmrElementArray<> children5( hChild5, "children" ); children5.Set( 0, NULL ); // grandchild5 is unref'ed to 0 hStrong6 = DMELEMENT_HANDLE_INVALID; // grandchild6 is unref'ed to 0 } g_pDmElementFramework->BeginEdit(); int nEditCount = g_pDataModel->GetAllocatedElementCount(); Shipping_Assert( nEditCount == nCreateCount - 1 ); Assert_ValidAndNonNULL ( hRoot ); Assert_ValidAndNonNULL ( hChild1 ); Assert_ValidAndNonNULL ( hChild2 ); Assert_InvalidButNonNULL( hChild3 ); Assert_ValidAndNonNULL ( hChild4 ); Assert_ValidAndNonNULL ( hChild5 ); Assert_ValidAndNonNULL ( hGrandChild1 ); Assert_ValidAndNonNULL ( hGrandChild2 ); Assert_ValidAndNonNULL ( hGrandChild3 ); Assert_ValidAndNonNULL ( hGrandChild4 ); Assert_ValidAndNonNULL ( hGrandChild5 ); Assert_ValidAndNonNULL ( hGrandChild6 ); Assert_ValidAndNonNULL ( hGrandChild7 ); g_pDataModel->Undo(); g_pDmElementFramework->BeginEdit(); int nUndoCount = g_pDataModel->GetAllocatedElementCount(); Shipping_Assert( nUndoCount == nCreateCount ); Assert_ValidAndNonNULL ( hRoot ); Assert_ValidAndNonNULL ( hChild1 ); Assert_ValidAndNonNULL ( hChild2 ); Assert_ValidAndNonNULL ( hChild3 ); Assert_ValidAndNonNULL ( hChild4 ); Assert_ValidAndNonNULL ( hChild5 ); Assert_ValidAndNonNULL ( hGrandChild1 ); Assert_ValidAndNonNULL ( hGrandChild2 ); Assert_ValidAndNonNULL ( hGrandChild3 ); Assert_ValidAndNonNULL ( hGrandChild4 ); Assert_ValidAndNonNULL ( hGrandChild5 ); Assert_ValidAndNonNULL ( hGrandChild6 ); Assert_ValidAndNonNULL ( hGrandChild7 ); g_pDataModel->Redo(); g_pDmElementFramework->BeginEdit(); int nRedoCount = g_pDataModel->GetAllocatedElementCount(); Shipping_Assert( nRedoCount == nEditCount ); Assert_ValidAndNonNULL ( hRoot ); Assert_ValidAndNonNULL ( hChild1 ); Assert_ValidAndNonNULL ( hChild2 ); Assert_InvalidButNonNULL( hChild3 ); Assert_ValidAndNonNULL ( hChild4 ); Assert_ValidAndNonNULL ( hChild5 ); Assert_ValidAndNonNULL ( hGrandChild1 ); Assert_ValidAndNonNULL ( hGrandChild2 ); Assert_ValidAndNonNULL ( hGrandChild3 ); Assert_ValidAndNonNULL ( hGrandChild4 ); Assert_ValidAndNonNULL ( hGrandChild5 ); Assert_ValidAndNonNULL ( hGrandChild6 ); Assert_ValidAndNonNULL ( hGrandChild7 ); g_pDataModel->ClearUndo(); g_pDmElementFramework->BeginEdit(); int nClearUndoCount = g_pDataModel->GetAllocatedElementCount(); Shipping_Assert( nClearUndoCount == nCreateCount - 6 ); Assert_ValidAndNonNULL ( hRoot ); Assert_ValidAndNonNULL ( hChild1 ); Assert_ValidAndNonNULL ( hChild2 ); Assert_InvalidAndNULL ( hChild3 ); Assert_ValidAndNonNULL ( hChild4 ); Assert_ValidAndNonNULL ( hChild5 ); Assert_InvalidAndNULL ( hGrandChild1 ); Assert_InvalidAndNULL ( hGrandChild2 ); Assert_InvalidAndNULL ( hGrandChild3 ); Assert_ValidAndNonNULL ( hGrandChild4 ); Assert_InvalidAndNULL ( hGrandChild5 ); Assert_InvalidAndNULL ( hGrandChild6 ); Assert_ValidAndNonNULL ( hGrandChild7 ); g_pDataModel->RemoveFileId( fileid ); }