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.

760 lines
25 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: Unit test program for DMX testing
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #include "unitlib/unitlib.h"
  8. #include "datamodel/dmelement.h"
  9. #include "datamodel/idatamodel.h"
  10. #include "tier1/utlbuffer.h"
  11. #include "filesystem.h"
  12. #include "datamodel/dmehandle.h"
  13. #include "tier2/tier2.h"
  14. bool AssertEqualElementHierarchies( bool quiet, DmElementHandle_t src1, DmElementHandle_t src2 );
  15. bool AssertUnEqualElementHierarchies( DmElementHandle_t src1, DmElementHandle_t src2 )
  16. {
  17. bool equal = AssertEqualElementHierarchies( true, src1, src2 );
  18. if ( equal )
  19. {
  20. AssertMsg( 0, "Hierarchies equal, expecting mismatch\n" );
  21. }
  22. return !equal;
  23. }
  24. void CreateTestScene( CUtlVector< DmElementHandle_t >& handles, DmFileId_t fileid )
  25. {
  26. DmObjectId_t id;
  27. CreateUniqueId( &id );
  28. VMatrix mat, mat2;
  29. MatrixBuildRotateZ( mat, 45 );
  30. MatrixBuildRotateZ( mat2, 30 );
  31. int i;
  32. unsigned char buf[256];
  33. unsigned char buf2[256];
  34. for ( i = 0; i < 256; ++i )
  35. {
  36. buf[i] = i;
  37. buf2[i] = 255 - i;
  38. }
  39. CDmElement *pElement = CreateElement<CDmElement>( "root", fileid );
  40. Assert( pElement );
  41. CDmElement *pElement2 = CreateElement<CDmElement>( "shared_child", fileid );
  42. Assert( pElement2 );
  43. CDmElement *pElement3 = CreateElement<CDmElement>( "unique_child", fileid );
  44. Assert( pElement3 );
  45. CDmElement *pElement4 = CreateElement<CDmElement>( "shared_array_element", fileid );
  46. Assert( pElement4 );
  47. CDmElement *pElement5 = CreateElement<CDmElement>( "unique_array_element", fileid );
  48. Assert( pElement5 );
  49. CDmElement *pElement6 = CreateElement<CDmElement>( "shared_element", fileid );
  50. Assert( pElement6 );
  51. CDmElement *pElement7 = CreateElement<CDmElement>( "unique_element", fileid );
  52. Assert( pElement7 );
  53. g_pDataModel->SetFileRoot( fileid, pElement->GetHandle() );
  54. handles.AddToTail( pElement->GetHandle() );
  55. handles.AddToTail( pElement2->GetHandle() );
  56. handles.AddToTail( pElement3->GetHandle() );
  57. handles.AddToTail( pElement4->GetHandle() );
  58. handles.AddToTail( pElement5->GetHandle() );
  59. handles.AddToTail( pElement6->GetHandle() );
  60. handles.AddToTail( pElement7->GetHandle() );
  61. pElement->SetValue( "id_test", id );
  62. pElement->SetValue( "bool_test", true );
  63. pElement->SetValue( "int_test", 2 );
  64. pElement->SetValue( "float_test", 3.0f );
  65. pElement->SetValue( "color_test", Color( 0, 64, 128, 255 ) );
  66. pElement->SetValue( "vector2d_test", Vector2D( 1.0f, -1.0f ) );
  67. pElement->SetValue( "vector3d_test", Vector( 1.0f, -1.0f, 0.0f ) );
  68. pElement->SetValue( "vector4d_test", Vector4D( 1.0f, -1.0f, 0.0f, 2.0f ) );
  69. pElement->SetValue( "qangle_test", QAngle( 0.0f, 90.0f, -90.0f ) );
  70. pElement->SetValue( "quat_test", Quaternion( 1.0f, -1.0f, 0.0f, 2.0f ) );
  71. pElement->SetValue( "vmatrix_test", mat );
  72. pElement->SetValue( "string_test", "test" );
  73. pElement->SetValue( "binary_test", buf, 256 );
  74. // Test DONTSAVE
  75. // pElement->SetValue( "dontsave", true );
  76. // CDmAttribute *pAttribute = pElement->GetAttribute( "dontsave" );
  77. // pAttribute->AddFlag( FATTRIB_DONTSAVE );
  78. CDmrArray< bool > boolVec( pElement2, "bool_array_test", true );
  79. boolVec.AddToTail( false );
  80. boolVec.AddToTail( true );
  81. CDmrArray< int > intVec( pElement2, "int_array_test", true );
  82. intVec.AddToTail( 0 );
  83. intVec.AddToTail( 1 );
  84. intVec.AddToTail( 2 );
  85. CDmrArray< float > floatVec( pElement2, "float_array_test", true );
  86. floatVec.AddToTail( -1.0f );
  87. floatVec.AddToTail( 0.0f );
  88. floatVec.AddToTail( 1.0f );
  89. CDmrArray< Color > colorVec( pElement3, "color_array_test", true );
  90. colorVec.AddToTail( Color( 0, 0, 0, 255 ) );
  91. colorVec.AddToTail( Color( 64, 64, 64, 255 ) );
  92. colorVec.AddToTail( Color( 128, 128, 128, 255 ) );
  93. CDmrArray< Vector2D > vector2DVec( pElement3, "vector2d_array_test", true );
  94. vector2DVec.AddToTail( Vector2D( -1.0f, -1.0f ) );
  95. vector2DVec.AddToTail( Vector2D( 1.0f, 1.0f ) );
  96. CDmrArray< Vector > vector3DVec( pElement3, "vector3d_array_test", true );
  97. vector3DVec.AddToTail( Vector( 1.0f, -1.0f, 0.0f ) );
  98. vector3DVec.AddToTail( Vector( 2.0f, -2.0f, 0.0f ) );
  99. CDmrArray< Vector4D > vector4DVec( pElement4, "vector4d_array_test", true );
  100. vector4DVec.AddToTail( Vector4D( 1.0f, -1.0f, 0.0f, 2.0f ) );
  101. vector4DVec.AddToTail( Vector4D( 2.0f, -2.0f, 0.0f, 4.0f ) );
  102. CDmrArray< QAngle > angleVec( pElement4, "qangle_array_test", true );
  103. angleVec.AddToTail( QAngle( 1.0f, -1.0f, 0.0f ) );
  104. angleVec.AddToTail( QAngle( 2.0f, -2.0f, 0.0f ) );
  105. CDmrArray< Quaternion > quatVec( pElement4, "quat_array_test", true );
  106. quatVec.AddToTail( Quaternion( 1.0f, -1.0f, 0.0f, 2.0f ) );
  107. quatVec.AddToTail( Quaternion( 2.0f, -2.0f, 0.0f, 4.0f ) );
  108. CDmrArray< VMatrix > matVec( pElement5, "vmatrix_array_test", true );
  109. matVec.AddToTail( mat );
  110. matVec.AddToTail( mat2 );
  111. CDmrStringArray stringVec( pElement5, "string_array_test", true );
  112. stringVec.AddToTail( "string1" );
  113. stringVec.AddToTail( "string2" );
  114. stringVec.AddToTail( "string3" );
  115. CDmrArray< CUtlBinaryBlock > binaryVec( pElement5, "binary_array_test", true );
  116. CUtlBinaryBlock block( (const void *)buf, 256 );
  117. i = binaryVec.AddToTail( block );
  118. CUtlBinaryBlock block2( (const void *)buf2, 256 );
  119. i = binaryVec.AddToTail( block2);
  120. CDmrArray< DmObjectId_t > idVec( pElement6, "elementid_array_test", true );
  121. i = idVec.AddToTail( pElement6->GetId() );
  122. i = idVec.AddToTail( pElement5->GetId() );
  123. i = idVec.AddToTail( pElement4->GetId() );
  124. CDmrElementArray< > elementVec( pElement6, "element_array_test", true );
  125. elementVec.AddToTail( pElement4 );
  126. elementVec.AddToTail( pElement5 );
  127. CDmrElementArray< > elementVec2( pElement7, "element_array_test", true );
  128. elementVec2.AddToTail( pElement2 );
  129. elementVec2.AddToTail( pElement4 );
  130. pElement->SetValue( "element_test", pElement7 );
  131. pElement->SetValue( "shared_element_test", pElement6 );
  132. CDmrElementArray<> children( pElement, "children", true );
  133. children.InsertBefore( 0, pElement2 );
  134. children.InsertBefore( 1, pElement3 );
  135. pElement7->SetValue( "shared_element_test", pElement6 );
  136. CDmrElementArray<> children2( pElement7, "children", true );
  137. children2.InsertBefore( 0, pElement2 );
  138. }
  139. DmElementHandle_t CreateTestScene( DmFileId_t fileid )
  140. {
  141. CUtlVector< DmElementHandle_t > handles;
  142. CreateTestScene( handles, fileid );
  143. return handles[ 0 ];
  144. }
  145. DmElementHandle_t CreateKeyValuesTestScene( DmFileId_t fileid )
  146. {
  147. CDmElement *pElement = CreateElement<CDmElement>( "root", fileid );
  148. Assert( pElement );
  149. CDmElement *pElement2 = CreateElement<CDmElement>( "shared_child", fileid );
  150. Assert( pElement2 );
  151. CDmElement *pElement3 = CreateElement<CDmElement>( "unique_child", fileid );
  152. Assert( pElement3 );
  153. CDmElement *pElement4 = CreateElement<CDmElement>( "shared_array_element", fileid );
  154. Assert( pElement4 );
  155. CDmElement *pElement5 = CreateElement<CDmElement>( "unique_array_element", fileid );
  156. Assert( pElement5 );
  157. CDmElement *pElement6 = CreateElement<CDmElement>( "shared_element", fileid );
  158. Assert( pElement6 );
  159. CDmElement *pElement7 = CreateElement<CDmElement>( "unique_element", fileid );
  160. Assert( pElement7 );
  161. g_pDataModel->SetFileRoot( fileid, pElement->GetHandle() );
  162. pElement->SetValue( "int_test", 2 );
  163. pElement->SetValue( "float_test", 3.0f );
  164. pElement->SetValue( "string_test", "test" );
  165. CDmrElementArray<> eVec( pElement6, "element_array_test", true );
  166. eVec.AddToTail( pElement4 );
  167. eVec.AddToTail( pElement5 );
  168. CDmrElementArray<> eVec2( pElement7, "element_array_test", true );
  169. eVec2.AddToTail( pElement2 );
  170. eVec2.AddToTail( pElement4 );
  171. pElement->SetValue( "element_test", pElement7 );
  172. pElement->SetValue( "shared_element_test", pElement6 );
  173. CDmrElementArray<> children( pElement, "children", true );
  174. children.InsertBefore( 0, pElement2 );
  175. children.InsertBefore( 1, pElement3 );
  176. pElement7->SetValue( "shared_element_test", pElement6 );
  177. CDmrElementArray<> children2( pElement7, "children", true );
  178. children2.InsertBefore( 0, pElement2 );
  179. return pElement->GetHandle();
  180. }
  181. template< class T >
  182. bool AssertEqualsTest( bool quiet, const T& src1, const T& src2 )
  183. {
  184. if ( !( src1 == src2 ))
  185. {
  186. if ( !quiet )
  187. {
  188. AssertMsg( 0, "Results not equal, expecting equal\n" );
  189. }
  190. return false;
  191. }
  192. return true;
  193. }
  194. template< class T >
  195. bool AssertEqualsUtlVector( bool quiet, const CUtlVector<T> &src1, const CUtlVector<T> &src2 )
  196. {
  197. bool retval = true;
  198. if ( src1.Count() != src2.Count() )
  199. {
  200. if ( !quiet )
  201. {
  202. AssertEqualsTest( quiet, src1.Count(), src2.Count() );
  203. }
  204. retval = false;
  205. }
  206. for ( int i = 0; i < src1.Count(); ++i )
  207. {
  208. if ( !src2.IsValidIndex( i ) )
  209. continue;
  210. if ( !( src1[i] == src2[i] ) )
  211. {
  212. if ( !quiet )
  213. {
  214. AssertEqualsTest( quiet, src1[i], src2[i] );
  215. }
  216. retval = false;
  217. }
  218. }
  219. return retval;
  220. }
  221. template< class T >
  222. bool AssertEqualsUtlVector( bool quiet, CDmAttribute *pAttribute1, CDmAttribute *pAttribute2 )
  223. {
  224. CDmrArray<T> src1( pAttribute1 );
  225. CDmrArray<T> src2( pAttribute2 );
  226. return AssertEqualsUtlVector( quiet, src1.Get(), src2.Get() );
  227. }
  228. bool AssertEqualAttributes( bool quiet, CDmAttribute *pAttribute1, CDmAttribute *pAttribute2 )
  229. {
  230. // Always follow ptrs to elements...
  231. if ( pAttribute1->GetType() != AT_ELEMENT_ARRAY &&
  232. pAttribute1->GetType() != AT_ELEMENT )
  233. {
  234. // Dirty flag checking here is to avoid infinite recursive loops
  235. if ( !pAttribute1->IsFlagSet( FATTRIB_DIRTY ) && !pAttribute2->IsFlagSet( FATTRIB_DIRTY ) )
  236. return true;
  237. }
  238. if ( !pAttribute1 )
  239. {
  240. if ( !quiet )
  241. {
  242. AssertMsg( 0, "AssertEqualAttributes: pAttribute1 is NULL\n" );
  243. }
  244. return false;
  245. }
  246. if ( !pAttribute2 )
  247. {
  248. if ( !quiet )
  249. {
  250. AssertMsg( 0, "AssertEqualAttributes: pAttribute2 is NULL\n" );
  251. }
  252. return false;
  253. }
  254. bool retval = true;
  255. pAttribute1->RemoveFlag( FATTRIB_DIRTY );
  256. pAttribute2->RemoveFlag( FATTRIB_DIRTY );
  257. if ( pAttribute1->GetType() != pAttribute2->GetType() )
  258. {
  259. if ( !quiet )
  260. {
  261. AssertMsg( 0, "pAttribute1->GetType() == pAttribute2->GetType()" );
  262. }
  263. retval = false;
  264. }
  265. switch( pAttribute1->GetType() )
  266. {
  267. case AT_INT:
  268. return AssertEqualsTest( quiet, pAttribute1->GetValue<int>( ), pAttribute2->GetValue<int>( ) );
  269. case AT_FLOAT:
  270. return AssertEqualsTest( quiet, pAttribute1->GetValue<float>( ), pAttribute2->GetValue<float>( ) );
  271. case AT_BOOL:
  272. return AssertEqualsTest( quiet, pAttribute1->GetValue<bool>( ), pAttribute2->GetValue<bool>( ) );
  273. case AT_STRING:
  274. return AssertEqualsTest( quiet, pAttribute1->GetValue<CUtlString>( ), pAttribute2->GetValue<CUtlString>( ) );
  275. case AT_VOID:
  276. return AssertEqualsTest( quiet, pAttribute1->GetValue<CUtlBinaryBlock>( ), pAttribute2->GetValue<CUtlBinaryBlock>( ) );
  277. case AT_OBJECTID:
  278. return true; // skip this for now - two elements can't have the same id, and CreateTestScene currently creates random test_id's each time...
  279. /*
  280. {
  281. if ( !g_pDataModel->IsEqual( pAttribute1->GetValue<DmObjectId_t>( ), pAttribute2->GetValue<DmObjectId_t>( ) ) )
  282. {
  283. if ( !quiet )
  284. {
  285. Assert( g_pDataModel->IsEqual( pAttribute1->GetValue<DmObjectId_t>( ), pAttribute2->GetValue<DmObjectId_t>( ) ) );
  286. }
  287. return false;
  288. }
  289. return true;
  290. }
  291. break;
  292. */
  293. case AT_COLOR:
  294. return AssertEqualsTest( quiet, pAttribute1->GetValue<Color>( ), pAttribute2->GetValue<Color>( ) );
  295. case AT_VECTOR2:
  296. return AssertEqualsTest( quiet, pAttribute1->GetValue<Vector2D>( ), pAttribute2->GetValue<Vector2D>( ) );
  297. case AT_VECTOR3:
  298. return AssertEqualsTest( quiet, pAttribute1->GetValue<Vector>( ), pAttribute2->GetValue<Vector>( ) );
  299. case AT_VECTOR4:
  300. return AssertEqualsTest( quiet, pAttribute1->GetValue<Vector4D>( ), pAttribute2->GetValue<Vector4D>( ) );
  301. case AT_QANGLE:
  302. return AssertEqualsTest( quiet, pAttribute1->GetValue<QAngle>( ), pAttribute2->GetValue<QAngle>( ) );
  303. case AT_QUATERNION:
  304. return AssertEqualsTest( quiet, pAttribute1->GetValue<Quaternion>( ), pAttribute2->GetValue<Quaternion>( ) );
  305. case AT_VMATRIX:
  306. return AssertEqualsTest( quiet, pAttribute1->GetValue<VMatrix>( ), pAttribute2->GetValue<VMatrix>( ) );
  307. case AT_ELEMENT:
  308. return AssertEqualElementHierarchies( quiet, pAttribute1->GetValue<DmElementHandle_t>( ), pAttribute2->GetValue<DmElementHandle_t>( ) );
  309. case AT_ELEMENT_ARRAY:
  310. {
  311. const CDmrElementArray< CDmElement > src1( pAttribute1 );
  312. const CDmrElementArray< CDmElement > src2( pAttribute2 );
  313. bool differs = !AssertEqualsTest( quiet, src1.Count(), src2.Count() );
  314. bool differs2 = false;
  315. for ( int i = 0; i < src1.Count(); ++i )
  316. {
  317. differs2 |= !AssertEqualElementHierarchies( quiet, src1[ i ]->GetHandle(), src2[ i ]->GetHandle() );
  318. }
  319. return ( !differs && !differs2 );
  320. }
  321. break;
  322. case AT_INT_ARRAY:
  323. return AssertEqualsUtlVector<int>( quiet, pAttribute1, pAttribute2 );
  324. case AT_FLOAT_ARRAY:
  325. return AssertEqualsUtlVector<float>( quiet, pAttribute1, pAttribute2 );
  326. case AT_BOOL_ARRAY:
  327. return AssertEqualsUtlVector<bool>( quiet, pAttribute1, pAttribute2 );
  328. case AT_STRING_ARRAY:
  329. return AssertEqualsUtlVector<CUtlString>( quiet, pAttribute1, pAttribute2 );
  330. case AT_VOID_ARRAY:
  331. return AssertEqualsUtlVector<CUtlBinaryBlock>( quiet, pAttribute1, pAttribute2 );
  332. case AT_OBJECTID_ARRAY:
  333. {
  334. const CDmrArray<DmObjectId_t> src1( pAttribute1 );
  335. const CDmrArray<DmObjectId_t> src2( pAttribute2 );
  336. bool differs = AssertEqualsTest( quiet, src1.Count(), src2.Count() );
  337. return differs; // skip this for now - CreateTestScene currently creates random ids each time...
  338. /*
  339. bool differs2 = false;
  340. for ( int i = 0; i < src1.Count(); ++i )
  341. {
  342. if ( !g_pDataModel->IsEqual( src1[i], src2[i] ) )
  343. {
  344. differs2 = true;
  345. if ( !quiet )
  346. {
  347. Assert( g_pDataModel->IsEqual( src1[i], src2[i] ) );
  348. }
  349. }
  350. }
  351. return ( !differs && !differs2 );
  352. */
  353. }
  354. break;
  355. case AT_COLOR_ARRAY:
  356. return AssertEqualsUtlVector<Color>( quiet, pAttribute1, pAttribute2 );
  357. case AT_VECTOR2_ARRAY:
  358. return AssertEqualsUtlVector<Vector2D>( quiet, pAttribute1, pAttribute2 );
  359. case AT_VECTOR3_ARRAY:
  360. return AssertEqualsUtlVector<Vector>( quiet, pAttribute1, pAttribute2 );
  361. case AT_VECTOR4_ARRAY:
  362. return AssertEqualsUtlVector<Vector4D>( quiet, pAttribute1, pAttribute2 );
  363. case AT_QANGLE_ARRAY:
  364. return AssertEqualsUtlVector<QAngle>( quiet, pAttribute1, pAttribute2 );
  365. case AT_QUATERNION_ARRAY:
  366. return AssertEqualsUtlVector<Quaternion>( quiet, pAttribute1, pAttribute2 );
  367. case AT_VMATRIX_ARRAY:
  368. return AssertEqualsUtlVector<VMatrix>( quiet, pAttribute1, pAttribute2 );
  369. }
  370. return retval;
  371. }
  372. bool AssertEqualElementHierarchies( bool quiet, DmElementHandle_t src1, DmElementHandle_t src2 )
  373. {
  374. CDmElement *pSrc1 = g_pDataModel->GetElement( src1 );
  375. CDmElement *pSrc2 = g_pDataModel->GetElement( src2 );
  376. if ( !pSrc1 || !pSrc2 )
  377. return false;
  378. // Assume equality
  379. bool retval = true;
  380. if ( pSrc1->GetType() != pSrc2->GetType() )
  381. {
  382. if ( !quiet )
  383. {
  384. AssertMsg( 0, "pSrc1->GetType() == pSrc2->GetType()" );
  385. }
  386. retval = false;
  387. }
  388. if ( Q_strcmp( pSrc1->GetName(), pSrc2->GetName() ) )
  389. {
  390. if ( !quiet )
  391. {
  392. AssertMsg2( 0, "Q_strcmp( %s, %s )", pSrc1->GetName(), pSrc2->GetName() );
  393. }
  394. retval = false;
  395. }
  396. if ( pSrc1->AttributeCount() != pSrc2->AttributeCount() )
  397. {
  398. if ( !quiet )
  399. {
  400. AssertMsg( 0, "pSrc1->NumAttributes() == pSrc2->NumAttributes()" );
  401. }
  402. retval = false;
  403. }
  404. for ( CDmAttribute *pAttribute1 = pSrc1->FirstAttribute(); pAttribute1; pAttribute1 = pAttribute1->NextAttribute() )
  405. {
  406. const char *pName = pAttribute1->GetName();
  407. if ( !pSrc2->HasAttribute( pName ) )
  408. {
  409. if ( !quiet )
  410. {
  411. AssertMsg1( 0, "pSrc2->HasAttribute( %s ) failed\n", pName );
  412. }
  413. retval = false;
  414. }
  415. else
  416. {
  417. CDmAttribute *pAttribute2 = pSrc2->GetAttribute( pName );
  418. bool differs = !AssertEqualAttributes( quiet, pAttribute1, pAttribute2 );
  419. if ( differs )
  420. {
  421. retval = false;
  422. }
  423. }
  424. }
  425. return retval;
  426. }
  427. void TestDeleteOldCR( const char *pSerializationType )
  428. {
  429. DmFileId_t testFileID = g_pDataModel->FindOrCreateFileId( "<TestDeleteOldCR>" );
  430. DmElementHandle_t hRoot = CreateTestScene( testFileID );
  431. int nTestElements = g_pDataModel->NumElementsInFile( testFileID );
  432. const char *pFileName = "DeleteOld.dmx";
  433. CDmElement *pRoot = static_cast< CDmElement* >( g_pDataModel->GetElement( hRoot ) );
  434. bool bOk = g_pDataModel->SaveToFile( pFileName, NULL, pSerializationType, "dmx", pRoot );
  435. Shipping_Assert( bOk );
  436. CDmElement *pReadInRoot = NULL;
  437. DmFileId_t readFileID = g_pDataModel->RestoreFromFile( pFileName, NULL, NULL, &pReadInRoot, CR_DELETE_OLD );
  438. Shipping_Assert( readFileID != DMFILEID_INVALID );
  439. if ( pReadInRoot )
  440. {
  441. Shipping_Assert( pReadInRoot->GetHandle() == hRoot );
  442. Shipping_Assert( g_pDataModel->GetElement( hRoot ) == pReadInRoot );
  443. Shipping_Assert( g_pDataModel->NumElementsInFile( testFileID ) == 0 );
  444. Shipping_Assert( g_pDataModel->NumElementsInFile( readFileID ) == nTestElements );
  445. CDmeHandle< CDmElement > rootHandle( hRoot ); // keeps a reference to root around, even after the file is unloaded
  446. g_pDataModel->UnloadFile( readFileID );
  447. Shipping_Assert( g_pDataModel->NumElementsInFile( readFileID ) == 0 );
  448. Shipping_Assert( g_pDataModel->GetElement( hRoot ) == NULL );
  449. DmFileId_t readFileID2 = g_pDataModel->RestoreFromFile( pFileName, NULL, NULL, &pReadInRoot, CR_DELETE_OLD );
  450. Shipping_Assert( readFileID2 == readFileID );
  451. Shipping_Assert( pReadInRoot->GetHandle() == hRoot );
  452. Shipping_Assert( g_pDataModel->GetElement( hRoot ) == pReadInRoot );
  453. Shipping_Assert( g_pDataModel->NumElementsInFile( testFileID ) == 0 );
  454. Shipping_Assert( g_pDataModel->NumElementsInFile( readFileID ) == nTestElements );
  455. g_pDataModel->RemoveFileId( readFileID );
  456. }
  457. else
  458. {
  459. Msg( "Failed to load %s back from disk!!!", pFileName );
  460. }
  461. g_pDataModel->RemoveFileId( testFileID );
  462. }
  463. void TestDeleteNewCR( const char *pSerializationType )
  464. {
  465. DmFileId_t testFileID = g_pDataModel->FindOrCreateFileId( "<TestDeleteNewCR>" );
  466. DmElementHandle_t hRoot = CreateTestScene( testFileID );
  467. int nTestElements = g_pDataModel->NumElementsInFile( testFileID );
  468. const char *pFileName = "DeleteNew.dmx";
  469. CDmElement *pRoot = static_cast< CDmElement* >( g_pDataModel->GetElement( hRoot ) );
  470. bool bOk = g_pDataModel->SaveToFile( pFileName, NULL, pSerializationType, "dmx", pRoot );
  471. Shipping_Assert( bOk );
  472. CDmElement *pReadInRoot = NULL;
  473. DmFileId_t readFileID = g_pDataModel->RestoreFromFile( pFileName, NULL, NULL, &pReadInRoot, CR_DELETE_NEW );
  474. Shipping_Assert( readFileID != DMFILEID_INVALID );
  475. Shipping_Assert( g_pDataModel->GetElement( hRoot ) == pRoot );
  476. Shipping_Assert( pRoot->GetHandle() == hRoot );
  477. Shipping_Assert( pReadInRoot == pRoot ); // RestoreFromFile now returns the old element when the new root is deleted
  478. Shipping_Assert( g_pDataModel->NumElementsInFile( testFileID ) == nTestElements );
  479. Shipping_Assert( g_pDataModel->NumElementsInFile( readFileID ) == 0 );
  480. g_pDataModel->UnloadFile( readFileID );
  481. Shipping_Assert( g_pDataModel->NumElementsInFile( readFileID ) == 0 );
  482. DmFileId_t readFileID2 = g_pDataModel->RestoreFromFile( pFileName, NULL, NULL, &pReadInRoot, CR_DELETE_NEW );
  483. Shipping_Assert( readFileID2 == readFileID );
  484. Shipping_Assert( g_pDataModel->GetElement( hRoot ) == pRoot );
  485. Shipping_Assert( pRoot->GetHandle() == hRoot );
  486. Shipping_Assert( pReadInRoot == pRoot ); // RestoreFromFile now returns the old element when the new root is deleted
  487. Shipping_Assert( g_pDataModel->NumElementsInFile( testFileID ) == nTestElements );
  488. Shipping_Assert( g_pDataModel->NumElementsInFile( readFileID ) == 0 );
  489. g_pDataModel->RemoveFileId( readFileID );
  490. g_pDataModel->RemoveFileId( testFileID );
  491. }
  492. void TestCopyNewCR( const char *pSerializationType )
  493. {
  494. DmFileId_t testFileID = g_pDataModel->FindOrCreateFileId( "<TestCopyNewCR>" );
  495. DmElementHandle_t hRoot = CreateTestScene( testFileID );
  496. int nTestElements = g_pDataModel->NumElementsInFile( testFileID );
  497. const char *pFileName = "CopyNew.dmx";
  498. CDmElement *pRoot = g_pDataModel->GetElement( hRoot );
  499. bool bOk = g_pDataModel->SaveToFile( pFileName, NULL, pSerializationType, "dmx", pRoot );
  500. Shipping_Assert( bOk );
  501. CDmElement *pReadInRoot = NULL;
  502. DmFileId_t readFileID = g_pDataModel->RestoreFromFile( pFileName, NULL, NULL, &pReadInRoot, CR_COPY_NEW );
  503. Shipping_Assert( readFileID != DMFILEID_INVALID );
  504. if ( pReadInRoot )
  505. {
  506. DmElementHandle_t hReadInRoot = pReadInRoot->GetHandle();
  507. Shipping_Assert( g_pDataModel->GetElement( hRoot ) == pRoot );
  508. Shipping_Assert( pRoot->GetHandle() == hRoot );
  509. Shipping_Assert( pReadInRoot->GetHandle() != hRoot );
  510. Shipping_Assert( !IsUniqueIdEqual( pRoot->GetId(), pReadInRoot->GetId() ) );
  511. Shipping_Assert( g_pDataModel->NumElementsInFile( testFileID ) == nTestElements );
  512. Shipping_Assert( g_pDataModel->NumElementsInFile( readFileID ) == nTestElements );
  513. g_pDataModel->UnloadFile( readFileID );
  514. Shipping_Assert( g_pDataModel->NumElementsInFile( readFileID ) == 0 );
  515. Shipping_Assert( g_pDataModel->GetElement( hReadInRoot ) == NULL );
  516. DmFileId_t readFileID2 = g_pDataModel->RestoreFromFile( pFileName, NULL, NULL, &pReadInRoot, CR_COPY_NEW );
  517. Shipping_Assert( readFileID2 == readFileID );
  518. Shipping_Assert( g_pDataModel->GetElement( hRoot ) == pRoot );
  519. Shipping_Assert( pRoot->GetHandle() == hRoot );
  520. Shipping_Assert( pReadInRoot->GetHandle() != hRoot );
  521. Shipping_Assert( !IsUniqueIdEqual( pRoot->GetId(), pReadInRoot->GetId() ) );
  522. Shipping_Assert( g_pDataModel->NumElementsInFile( testFileID ) == nTestElements );
  523. Shipping_Assert( g_pDataModel->NumElementsInFile( readFileID ) == nTestElements );
  524. g_pDataModel->RemoveFileId( readFileID );
  525. }
  526. else
  527. {
  528. Msg( "Failed to load %s back from disk!!!", pFileName );
  529. }
  530. g_pDataModel->RemoveFileId( testFileID );
  531. }
  532. void TestForceCopyCR( const char *pSerializationType )
  533. {
  534. DmFileId_t testFileID = g_pDataModel->FindOrCreateFileId( "<TestForceCopyCR>" );
  535. DmElementHandle_t hRoot = CreateTestScene( testFileID );
  536. int nTestElements = g_pDataModel->NumElementsInFile( testFileID );
  537. const char *pFileName = "ForceCopy.dmx";
  538. CDmElement *pRoot = static_cast< CDmElement* >( g_pDataModel->GetElement( hRoot ) );
  539. bool bOk = g_pDataModel->SaveToFile( pFileName, NULL, pSerializationType, "dmx", pRoot );
  540. Shipping_Assert( bOk );
  541. CDmElement *pReadInRoot = NULL;
  542. DmFileId_t readFileID = g_pDataModel->RestoreFromFile( pFileName, NULL, NULL, &pReadInRoot, CR_FORCE_COPY );
  543. Shipping_Assert( readFileID != DMFILEID_INVALID );
  544. if ( pReadInRoot )
  545. {
  546. DmElementHandle_t hReadInRoot = pReadInRoot->GetHandle();
  547. Shipping_Assert( g_pDataModel->GetElement( hRoot ) == pRoot );
  548. Shipping_Assert( pRoot->GetHandle() == hRoot );
  549. Shipping_Assert( pReadInRoot->GetHandle() != hRoot );
  550. Shipping_Assert( !IsUniqueIdEqual( pRoot->GetId(), pReadInRoot->GetId() ) );
  551. Shipping_Assert( g_pDataModel->NumElementsInFile( testFileID ) == nTestElements );
  552. Shipping_Assert( g_pDataModel->NumElementsInFile( readFileID ) == nTestElements );
  553. g_pDataModel->UnloadFile( readFileID );
  554. Shipping_Assert( g_pDataModel->NumElementsInFile( readFileID ) == 0 );
  555. Shipping_Assert( g_pDataModel->GetElement( hReadInRoot ) == NULL );
  556. DmFileId_t readFileID2 = g_pDataModel->RestoreFromFile( pFileName, NULL, NULL, &pReadInRoot, CR_FORCE_COPY );
  557. Shipping_Assert( readFileID2 == readFileID );
  558. Shipping_Assert( g_pDataModel->GetElement( hRoot ) == pRoot );
  559. Shipping_Assert( pRoot->GetHandle() == hRoot );
  560. Shipping_Assert( pReadInRoot->GetHandle() != hRoot );
  561. Shipping_Assert( !IsUniqueIdEqual( pRoot->GetId(), pReadInRoot->GetId() ) );
  562. Shipping_Assert( g_pDataModel->NumElementsInFile( testFileID ) == nTestElements );
  563. Shipping_Assert( g_pDataModel->NumElementsInFile( readFileID ) == nTestElements );
  564. g_pDataModel->RemoveFileId( readFileID );
  565. }
  566. else
  567. {
  568. Msg( "Failed to load %s back from disk!!!", pFileName );
  569. }
  570. g_pDataModel->RemoveFileId( testFileID );
  571. }
  572. void TestConflictResolution( const char *pSerializationType )
  573. {
  574. TestDeleteOldCR( pSerializationType );
  575. TestDeleteNewCR( pSerializationType );
  576. TestCopyNewCR( pSerializationType );
  577. TestForceCopyCR( pSerializationType );
  578. }
  579. void TestSerializationMethod( const char *pSerializationType )
  580. {
  581. DmFileId_t testFileID = g_pDataModel->FindOrCreateFileId( "<CreateTestScene>" );
  582. DmElementHandle_t hRoot = CreateTestScene( testFileID );
  583. const char *pFileName = "dmxtest.dmx";
  584. CDmElement *pRoot = static_cast<CDmElement*>(g_pDataModel->GetElement(hRoot));
  585. bool bOk = g_pDataModel->SaveToFile( pFileName, NULL, pSerializationType, "dmx", pRoot );
  586. Shipping_Assert( bOk );
  587. CDmElement *pReadInRoot = NULL;
  588. DmFileId_t dmxFileID = g_pDataModel->RestoreFromFile( pFileName, NULL, NULL, &pReadInRoot, CR_FORCE_COPY );
  589. Shipping_Assert( dmxFileID != DMFILEID_INVALID );
  590. if ( pReadInRoot )
  591. {
  592. AssertEqualElementHierarchies( false, hRoot, pReadInRoot->GetHandle() );
  593. g_pDataModel->RemoveFileId( dmxFileID );
  594. }
  595. else
  596. {
  597. Msg( "Failed to load dmxtest.dmx back from disk!!!" );
  598. }
  599. g_pDataModel->RemoveFileId( testFileID );
  600. TestConflictResolution( pSerializationType );
  601. }
  602. DEFINE_TESTCASE_NOSUITE( DmxSerializationTest )
  603. {
  604. Msg( "Running dmx serialization tests...\n" );
  605. CDisableUndoScopeGuard sg;
  606. TestSerializationMethod( "keyvalues2" );
  607. TestSerializationMethod( "keyvalues2_flat" );
  608. TestSerializationMethod( "xml" );
  609. TestSerializationMethod( "xml_flat" );
  610. TestSerializationMethod( "binary" );
  611. int nEndingCount = g_pDataModel->GetAllocatedElementCount();
  612. AssertEqualsTest( false, 0, nEndingCount );
  613. }