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.

1096 lines
34 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 "movieobjects/movieobjects.h"
  11. #include "tier1/utlbuffer.h"
  12. #include "filesystem.h"
  13. // From dmxtestserialization.cpp
  14. bool AssertEqualElementHierarchies( bool quiet, DmElementHandle_t src1, DmElementHandle_t src2 );
  15. bool AssertUnEqualElementHierarchies( DmElementHandle_t src1, DmElementHandle_t src2 );
  16. void CreateTestScene( CUtlVector< DmElementHandle_t >& handles, DmFileId_t fileid );
  17. bool AssertEqualElementHierarchies( bool quiet, CDmElement *src1, CDmElement *src2 )
  18. {
  19. DmElementHandle_t h1 = src1->GetHandle();
  20. DmElementHandle_t h2 = src2->GetHandle();
  21. return AssertEqualElementHierarchies( quiet, h1, h2 );
  22. }
  23. bool AssertUnEqualElementHierarchies( CDmElement *src1, CDmElement *src2 )
  24. {
  25. return AssertUnEqualElementHierarchies( src1->GetHandle(), src2->GetHandle() );
  26. }
  27. //-----------------------------------------------------------------------------
  28. // Purpose:
  29. // Input : -
  30. //-----------------------------------------------------------------------------
  31. void DescribeUndo()
  32. {
  33. CUtlVector< UndoInfo_t > list;
  34. g_pDataModel->GetUndoInfo( list );
  35. for ( int i = list.Count() - 1; i >= 0; --i )
  36. {
  37. UndoInfo_t& entry = list[ i ];
  38. if ( entry.terminator )
  39. {
  40. Msg( "[ '%s' ] -- %i operations\n", entry.undo, entry.numoperations );
  41. }
  42. Msg( " +[ '%s' ]\n", entry.desc );
  43. }
  44. }
  45. template< class T >
  46. void RunSingleSetAttributeUndoTest( CDmElement *pTest, CDmElement *pOriginal, CDmElement *pElement, const char *attribute, const T& newVal )
  47. {
  48. {
  49. CUndoScopeGuard guard( attribute, attribute );
  50. pElement->SetValue( attribute, newVal );
  51. }
  52. g_pDataModel->Undo();
  53. AssertEqualElementHierarchies( false, pTest, pOriginal );
  54. g_pDataModel->Redo();
  55. g_pDataModel->Undo();
  56. AssertEqualElementHierarchies( false, pTest, pOriginal );
  57. }
  58. void RunSingleSetAttributeUndoTestBinary( CDmElement *pTest, CDmElement *pOriginal, CDmElement *pElement, const char *attribute, const void *data, size_t size )
  59. {
  60. {
  61. CUndoScopeGuard guard( attribute, attribute );
  62. pElement->SetValue( attribute, data, size );
  63. }
  64. AssertUnEqualElementHierarchies( pTest, pOriginal );
  65. g_pDataModel->Undo();
  66. AssertEqualElementHierarchies( false, pTest, pOriginal );
  67. g_pDataModel->Redo();
  68. AssertUnEqualElementHierarchies( pTest, pOriginal );
  69. g_pDataModel->Undo();
  70. AssertEqualElementHierarchies( false, pTest, pOriginal );
  71. }
  72. template< class T >
  73. void RunSingleSetAttributeUndoTestArray( CDmElement *pTest, CDmElement *pOriginal, CDmElement *pElement, const char *attribute, int slot, const T& newVal )
  74. {
  75. {
  76. CUndoScopeGuard guard( attribute, attribute );
  77. CDmrArray< T > array( pElement, attribute );
  78. array.Set( slot, newVal );
  79. }
  80. AssertUnEqualElementHierarchies( pTest, pOriginal );
  81. g_pDataModel->Undo();
  82. AssertEqualElementHierarchies( false, pTest, pOriginal );
  83. g_pDataModel->Redo();
  84. AssertUnEqualElementHierarchies( pTest, pOriginal );
  85. g_pDataModel->Undo();
  86. AssertEqualElementHierarchies( false, pTest, pOriginal );
  87. }
  88. template<> void RunSingleSetAttributeUndoTestArray<DmElementHandle_t>( CDmElement *pTest, CDmElement *pOriginal, CDmElement *pElement, const char *attribute, int slot, const DmElementHandle_t& newVal )
  89. {
  90. {
  91. CUndoScopeGuard guard( attribute, attribute );
  92. CDmrElementArray<> array( pElement, attribute );
  93. array.SetHandle( slot, newVal );
  94. }
  95. AssertUnEqualElementHierarchies( pTest, pOriginal );
  96. g_pDataModel->Undo();
  97. AssertEqualElementHierarchies( false, pTest, pOriginal );
  98. g_pDataModel->Redo();
  99. AssertUnEqualElementHierarchies( pTest, pOriginal );
  100. g_pDataModel->Undo();
  101. AssertEqualElementHierarchies( false, pTest, pOriginal );
  102. }
  103. template< class T >
  104. void RunSingleAttributeUndoTestArrayAddToHead( CDmElement *pTest, CDmElement *pOriginal, CDmElement *pElement, const char *attribute, const T& newVal )
  105. {
  106. {
  107. CUndoScopeGuard guard( attribute, attribute );
  108. CDmrArray< T > array( pElement, attribute );
  109. array.InsertBefore( 0, newVal );
  110. }
  111. AssertUnEqualElementHierarchies( pTest, pOriginal );
  112. g_pDataModel->Undo();
  113. AssertEqualElementHierarchies( false, pTest, pOriginal );
  114. g_pDataModel->Redo();
  115. AssertUnEqualElementHierarchies( pTest, pOriginal );
  116. g_pDataModel->Undo();
  117. AssertEqualElementHierarchies( false, pTest, pOriginal );
  118. }
  119. template< class T >
  120. void RunSingleAttributeUndoTestArrayAddToTail( CDmElement *pTest, CDmElement *pOriginal, CDmElement *pElement, const char *attribute, const T& newVal )
  121. {
  122. {
  123. CUndoScopeGuard guard( attribute, attribute );
  124. CDmrArray< T > array( pElement, attribute );
  125. array.AddToTail( newVal );
  126. }
  127. AssertUnEqualElementHierarchies( pTest, pOriginal );
  128. g_pDataModel->Undo();
  129. AssertEqualElementHierarchies( false, pTest, pOriginal );
  130. g_pDataModel->Redo();
  131. AssertUnEqualElementHierarchies( pTest, pOriginal );
  132. g_pDataModel->Undo();
  133. AssertEqualElementHierarchies( false, pTest, pOriginal );
  134. }
  135. template< class T >
  136. void RunSingleAttributeUndoTestArrayInsertBefore( CDmElement *pTest, CDmElement *pOriginal, CDmElement *pElement, const char *attribute, int slot, const T& newVal )
  137. {
  138. {
  139. CUndoScopeGuard guard( attribute, attribute );
  140. CDmrArray< T > array( pElement, attribute );
  141. array.InsertBefore( slot, newVal );
  142. }
  143. AssertUnEqualElementHierarchies( pTest, pOriginal );
  144. g_pDataModel->Undo();
  145. AssertEqualElementHierarchies( false, pTest, pOriginal );
  146. g_pDataModel->Redo();
  147. AssertUnEqualElementHierarchies( pTest, pOriginal );
  148. g_pDataModel->Undo();
  149. AssertEqualElementHierarchies( false, pTest, pOriginal );
  150. }
  151. template< class T >
  152. void RunSingleAttributeUndoTestArrayFastRemove( CDmElement *pTest, CDmElement *pOriginal, CDmElement *pElement, const char *attribute, int slot, T typeDeducer )
  153. {
  154. {
  155. CUndoScopeGuard guard( attribute, attribute );
  156. CDmrArray< T > array( pElement, attribute );
  157. array.FastRemove( slot );
  158. }
  159. AssertUnEqualElementHierarchies( pTest, pOriginal );
  160. g_pDataModel->Undo();
  161. AssertEqualElementHierarchies( false, pTest, pOriginal );
  162. g_pDataModel->Redo();
  163. AssertUnEqualElementHierarchies( pTest, pOriginal );
  164. g_pDataModel->Undo();
  165. AssertEqualElementHierarchies( false, pTest, pOriginal );
  166. }
  167. void RunSingleAttributeUndoTestElementArrayRemove( CDmElement *pTest, CDmElement *pOriginal, CDmElement *pElement, const char *attribute, int slot )
  168. {
  169. {
  170. CUndoScopeGuard guard( attribute, attribute );
  171. CDmrElementArray<> array( pElement, attribute );
  172. array.Remove( slot );
  173. }
  174. DescribeUndo();
  175. AssertUnEqualElementHierarchies( pTest, pOriginal );
  176. g_pDataModel->Undo();
  177. AssertEqualElementHierarchies( false, pTest, pOriginal );
  178. g_pDataModel->Redo();
  179. AssertUnEqualElementHierarchies( pTest, pOriginal );
  180. g_pDataModel->Undo();
  181. AssertEqualElementHierarchies( false, pTest, pOriginal );
  182. }
  183. template< class T >
  184. void RunSingleAttributeUndoTestArrayRemove( CDmElement *pTest, CDmElement *pOriginal, CDmElement *pElement, const char *attribute, int slot, T typeDeducer )
  185. {
  186. {
  187. CUndoScopeGuard guard( attribute, attribute );
  188. CDmrArray<T> array( pElement, attribute );
  189. array.Remove( slot );
  190. }
  191. AssertUnEqualElementHierarchies( pTest, pOriginal );
  192. g_pDataModel->Undo();
  193. AssertEqualElementHierarchies( false, pTest, pOriginal );
  194. g_pDataModel->Redo();
  195. AssertUnEqualElementHierarchies( pTest, pOriginal );
  196. g_pDataModel->Undo();
  197. AssertEqualElementHierarchies( false, pTest, pOriginal );
  198. }
  199. template< class T >
  200. void RunSingleAttributeUndoTestArrayRemoveMultiple( CDmElement *pTest, CDmElement *pOriginal, CDmElement *pElement, const char *attribute, int slot, int count, T typeDeducer )
  201. {
  202. {
  203. CUndoScopeGuard guard( attribute, attribute );
  204. CDmrArray< T > array( pElement, attribute );
  205. array.RemoveMultiple( slot, count );
  206. }
  207. AssertUnEqualElementHierarchies( pTest, pOriginal );
  208. g_pDataModel->Undo();
  209. AssertEqualElementHierarchies( false, pTest, pOriginal );
  210. g_pDataModel->Redo();
  211. AssertUnEqualElementHierarchies( pTest, pOriginal );
  212. g_pDataModel->Undo();
  213. AssertEqualElementHierarchies( false, pTest, pOriginal );
  214. }
  215. template< class T >
  216. void RunSingleAttributeUndoTestArrayRemoveAll( CDmElement *pTest, CDmElement *pOriginal, CDmElement *pElement, const char *attribute, bool purge )
  217. {
  218. {
  219. CUndoScopeGuard guard( attribute, attribute );
  220. CDmrArray< T > array( pElement, attribute );
  221. if( purge )
  222. {
  223. array.Purge();
  224. }
  225. else
  226. {
  227. array.RemoveAll();
  228. }
  229. }
  230. AssertUnEqualElementHierarchies( pTest, pOriginal );
  231. g_pDataModel->Undo();
  232. AssertEqualElementHierarchies( false, pTest, pOriginal );
  233. g_pDataModel->Redo();
  234. AssertUnEqualElementHierarchies( pTest, pOriginal );
  235. g_pDataModel->Undo();
  236. AssertEqualElementHierarchies( false, pTest, pOriginal );
  237. }
  238. template< class T >
  239. void RunSingleAttributeUndoTestArrayCopyFrom( CDmElement *pTest, CDmElement *pOriginal, CDmElement *pElement, const char *attribute, const CUtlVector<T>& list )
  240. {
  241. {
  242. CUndoScopeGuard guard( attribute, attribute );
  243. CDmrArray<T> array( pElement, attribute );
  244. array.CopyArray( list.Base(), list.Count() );
  245. }
  246. AssertUnEqualElementHierarchies( pTest, pOriginal );
  247. g_pDataModel->Undo();
  248. AssertEqualElementHierarchies( false, pTest, pOriginal );
  249. g_pDataModel->Redo();
  250. AssertUnEqualElementHierarchies( pTest, pOriginal );
  251. g_pDataModel->Undo();
  252. AssertEqualElementHierarchies( false, pTest, pOriginal );
  253. }
  254. void RunSingleSetAttributeUndoTestArrayBinary( CDmElement *pTest, CDmElement *pOriginal, CDmElement *pElement, const char *attribute, int slot, const void *data, size_t size )
  255. {
  256. {
  257. CUndoScopeGuard guard( attribute, attribute );
  258. CUtlBinaryBlock block( (const void *)data, size );
  259. CDmrArray< CUtlBinaryBlock > array( pElement, attribute );
  260. array.Set( slot, block );
  261. }
  262. AssertUnEqualElementHierarchies( pTest, pOriginal );
  263. g_pDataModel->Undo();
  264. AssertEqualElementHierarchies( false, pTest, pOriginal );
  265. g_pDataModel->Redo();
  266. AssertUnEqualElementHierarchies( pTest, pOriginal );
  267. g_pDataModel->Undo();
  268. AssertEqualElementHierarchies( false, pTest, pOriginal );
  269. }
  270. template< class T >
  271. void RunSingleSetAttributeUndoTestArrayWhole( CDmElement *pTest, CDmElement *pOriginal, CDmElement *pElement, const char *attribute, CUtlVector< T >& newVal )
  272. {
  273. {
  274. CUndoScopeGuard guard( attribute, attribute );
  275. IDmAttributeArray< T > *pArray = static_cast< IDmAttributeArray< T > * >( pElement->GetAttribute( "attribute" ) );
  276. pArray->SetValue( newVal );
  277. }
  278. AssertUnEqualElementHierarchies( pTest, pOriginal );
  279. g_pDataModel->Undo();
  280. AssertEqualElementHierarchies( false, pTest, pOriginal );
  281. g_pDataModel->Redo();
  282. AssertUnEqualElementHierarchies( pTest, pOriginal );
  283. g_pDataModel->Undo();
  284. AssertEqualElementHierarchies( false, pTest, pOriginal );
  285. }
  286. template< class T >
  287. void RunSingleAddAttributeUndoTest( CDmElement *pTest, CDmElement *pOriginal, CDmElement *pElement, const char *attribute, const T& newVal )
  288. {
  289. {
  290. CUndoScopeGuard guard( attribute, attribute );
  291. pElement->SetValue( attribute, newVal );
  292. }
  293. AssertUnEqualElementHierarchies( pTest, pOriginal );
  294. g_pDataModel->Undo();
  295. AssertEqualElementHierarchies( false, pTest, pOriginal );
  296. g_pDataModel->Redo();
  297. AssertUnEqualElementHierarchies( pTest, pOriginal );
  298. g_pDataModel->Undo();
  299. AssertEqualElementHierarchies( false, pTest, pOriginal );
  300. }
  301. void RunSingleRemoveAttributeUndoTest( CDmElement *pTest, CDmElement *pOriginal, CDmElement *pElement, const char *attribute )
  302. {
  303. AssertEqualElementHierarchies( false, pTest, pOriginal );
  304. {
  305. CUndoScopeGuard guard( attribute, attribute );
  306. pElement->RemoveAttribute( attribute );
  307. }
  308. AssertUnEqualElementHierarchies( pTest, pOriginal );
  309. g_pDataModel->Undo();
  310. AssertEqualElementHierarchies( false, pTest, pOriginal );
  311. g_pDataModel->Redo();
  312. AssertUnEqualElementHierarchies( pTest, pOriginal );
  313. g_pDataModel->Undo();
  314. AssertEqualElementHierarchies( false, pTest, pOriginal );
  315. }
  316. void RunUndoTestsArray( CUtlVector< DmElementHandle_t >& handles, CDmElement *pTest, CDmElement *pOriginal )
  317. {
  318. DmObjectId_t id;
  319. CreateUniqueId( &id );
  320. VMatrix mat, mat2;
  321. MatrixBuildRotateZ( mat, 55 );
  322. MatrixBuildRotateZ( mat2, -55 );
  323. int i;
  324. unsigned char buf[256];
  325. unsigned char buf2[256];
  326. for ( i = 0; i < 256; ++i )
  327. {
  328. buf[i] = i+55500;
  329. buf2[i] = 55000 + 255 - i;
  330. }
  331. Assert( handles.Count() == 7 );
  332. //CDmElement *pElement = pTest;
  333. CDmElement *pElement2 = GetElement< CDmElement >( handles[ 1 ] );
  334. CDmElement *pElement3 = GetElement< CDmElement >( handles[ 2 ] );
  335. CDmElement *pElement4 = GetElement< CDmElement >( handles[ 3 ] );
  336. CDmElement *pElement5 = GetElement< CDmElement >( handles[ 4 ] );
  337. CDmElement *pElement6 = GetElement< CDmElement >( handles[ 5 ] );
  338. CDmElement *pElement7 = GetElement< CDmElement >( handles[ 6 ] );
  339. RunSingleSetAttributeUndoTestArray( pTest, pOriginal, pElement2, "int_array_test", 0, 55 );
  340. RunSingleSetAttributeUndoTestArray( pTest, pOriginal, pElement2, "float_array_test", 0, 55.0f );
  341. RunSingleSetAttributeUndoTestArray( pTest, pOriginal, pElement2, "bool_array_test", 0, true );
  342. RunSingleSetAttributeUndoTestArray( pTest, pOriginal, pElement3, "color_array_test", 0, Color( 55, 55, 55, 55 ) );
  343. RunSingleSetAttributeUndoTestArray( pTest, pOriginal, pElement3, "vector2d_array_test", 0, Vector2D( 55.0f, -55.0f ) );
  344. RunSingleSetAttributeUndoTestArray( pTest, pOriginal, pElement3, "vector3d_array_test", 0, Vector( 55.0f, -55.0f, 55.0f ) );
  345. RunSingleSetAttributeUndoTestArray( pTest, pOriginal, pElement4, "vector4d_array_test", 0, Vector4D( 55.0f, -55.0f, 55.0f, 55.0f ) );
  346. RunSingleSetAttributeUndoTestArray( pTest, pOriginal, pElement4, "qangle_array_test", 0, QAngle( 55.0f, 55.0f, -55.0f ) );
  347. RunSingleSetAttributeUndoTestArray( pTest, pOriginal, pElement4, "quat_array_test", 0, Quaternion( 1.0f, -1.0f, 0.0f, 55.0f ) );
  348. RunSingleSetAttributeUndoTestArray( pTest, pOriginal, pElement5, "vmatrix_array_test", 0, mat );
  349. CUtlString newString( "55test" );
  350. RunSingleSetAttributeUndoTestArray( pTest, pOriginal, pElement5, "string_array_test", 0, newString );
  351. RunSingleSetAttributeUndoTestArrayBinary( pTest, pOriginal, pElement5, "binary_array_test", 0, buf, 256 );
  352. // RunSingleSetAttributeUndoTestArray( pTest, pOriginal, pElement6, "elementid_array_test", 0, id );
  353. RunSingleSetAttributeUndoTestArray( pTest, pOriginal, pElement6, "element_array_test", 0, pElement2->GetHandle() );
  354. RunSingleSetAttributeUndoTestArray( pTest, pOriginal, pElement7, "element_array_test", 0, pElement5->GetHandle() );
  355. {
  356. RunSingleSetAttributeUndoTestArray( pTest, pOriginal, pElement2, "int_array_test", 0, 55 );
  357. RunSingleSetAttributeUndoTestArray( pTest, pOriginal, pElement2, "float_array_test", 0, 55.0f );
  358. RunSingleSetAttributeUndoTestArray( pTest, pOriginal, pElement2, "bool_array_test", 0, true );
  359. RunSingleSetAttributeUndoTestArray( pTest, pOriginal, pElement3, "color_array_test", 0, Color( 55, 55, 55, 55 ) );
  360. RunSingleSetAttributeUndoTestArray( pTest, pOriginal, pElement3, "vector2d_array_test", 0, Vector2D( 55.0f, -55.0f ) );
  361. RunSingleSetAttributeUndoTestArray( pTest, pOriginal, pElement3, "vector3d_array_test", 0, Vector( 55.0f, -55.0f, 55.0f ) );
  362. RunSingleSetAttributeUndoTestArray( pTest, pOriginal, pElement4, "vector4d_array_test", 0, Vector4D( 55.0f, -55.0f, 55.0f, 55.0f ) );
  363. RunSingleSetAttributeUndoTestArray( pTest, pOriginal, pElement4, "qangle_array_test", 0, QAngle( 55.0f, 55.0f, -55.0f ) );
  364. RunSingleSetAttributeUndoTestArray( pTest, pOriginal, pElement4, "quat_array_test", 0, Quaternion( 1.0f, -1.0f, 0.0f, 55.0f ) );
  365. RunSingleSetAttributeUndoTestArray( pTest, pOriginal, pElement5, "vmatrix_array_test", 0, mat );
  366. CUtlString newString( "55test" );
  367. RunSingleSetAttributeUndoTestArray( pTest, pOriginal, pElement5, "string_array_test", 0, newString );
  368. RunSingleSetAttributeUndoTestArrayBinary( pTest, pOriginal, pElement5, "binary_array_test", 0, buf, 256 );
  369. // RunSingleSetAttributeUndoTestArray( pTest, pOriginal, pElement6, "elementid_array_test", 0, id );
  370. RunSingleSetAttributeUndoTestArray( pTest, pOriginal, pElement6, "element_array_test", 0, pElement2->GetHandle() );
  371. RunSingleSetAttributeUndoTestArray( pTest, pOriginal, pElement7, "element_array_test", 0, pElement5->GetHandle() );
  372. }
  373. RunSingleAttributeUndoTestArrayAddToHead( pTest, pOriginal, pElement2, "int_array_test", 55 );
  374. RunSingleAttributeUndoTestArrayAddToTail( pTest, pOriginal, pElement2, "int_array_test", 55 );
  375. RunSingleAttributeUndoTestArrayInsertBefore( pTest, pOriginal, pElement2, "int_array_test", 0, 55 );
  376. RunSingleAttributeUndoTestArrayFastRemove( pTest, pOriginal, pElement2, "int_array_test", 0, (int)0 );
  377. RunSingleAttributeUndoTestArrayRemove( pTest, pOriginal, pElement2, "int_array_test", 0, (int)0 );
  378. RunSingleAttributeUndoTestArrayRemoveMultiple( pTest, pOriginal, pElement2, "int_array_test", 0, 2, (int)0 );
  379. RunSingleAttributeUndoTestElementArrayRemove( pTest, pOriginal, pElement7, "children", 0 );
  380. // RemoveAll
  381. RunSingleAttributeUndoTestArrayRemoveAll<int>( pTest, pOriginal, pElement2, "int_array_test", false );
  382. // Purge
  383. RunSingleAttributeUndoTestArrayRemoveAll<int>( pTest, pOriginal, pElement2, "int_array_test", true );
  384. CUtlVector< int > foo;
  385. foo.AddToTail( 55 );
  386. foo.AddToTail( 56 );
  387. foo.AddToTail( 57 );
  388. foo.AddToTail( 58 );
  389. foo.AddToTail( 59 );
  390. RunSingleAttributeUndoTestArrayCopyFrom( pTest, pOriginal, pElement2, "int_array_test", foo );
  391. }
  392. void RunUndoTests( CUtlVector< DmElementHandle_t >& handles, CDmElement *pTest, CDmElement *pOriginal )
  393. {
  394. DmObjectId_t id;
  395. CreateUniqueId( &id );
  396. VMatrix mat, mat2;
  397. MatrixBuildRotateZ( mat, 55 );
  398. MatrixBuildRotateZ( mat2, -55 );
  399. int i;
  400. unsigned char buf[256];
  401. unsigned char buf2[256];
  402. for ( i = 0; i < 256; ++i )
  403. {
  404. buf[i] = i+100;
  405. buf2[i] = 127 + 255 - i;
  406. }
  407. Assert( handles.Count() == 7 );
  408. CDmElement *pElement = pTest;
  409. CDmElement *pElement2 = GetElement<CDmElement>( handles[ 1 ] );
  410. RunSingleSetAttributeUndoTest( pTest, pOriginal, pElement, "element_test", (CDmElement *)NULL );
  411. RunSingleSetAttributeUndoTest( pTest, pOriginal, pElement, "int_test", 55 );
  412. RunSingleSetAttributeUndoTest( pTest, pOriginal, pElement, "float_test", 55.0f );
  413. RunSingleSetAttributeUndoTest( pTest, pOriginal, pElement, "bool_test", false );
  414. // RunSingleSetAttributeUndoTest( pTest, pOriginal, pElement, "id_test", id );
  415. RunSingleSetAttributeUndoTest( pTest, pOriginal, pElement, "string_test", "55test" );
  416. RunSingleSetAttributeUndoTestBinary( pTest, pOriginal, pElement, "binary_test", buf, 256 );
  417. RunSingleSetAttributeUndoTest( pTest, pOriginal, pElement, "color_test", Color( 55, 55, 55, 55 ) );
  418. RunSingleSetAttributeUndoTest( pTest, pOriginal, pElement, "vector2d_test", Vector2D( 55.0f, -55.0f ) );
  419. RunSingleSetAttributeUndoTest( pTest, pOriginal, pElement, "vector3d_test", Vector( 55.0f, -55.0f, 55.0f ) );
  420. RunSingleSetAttributeUndoTest( pTest, pOriginal, pElement, "vector4d_test", Vector4D( 55.0f, -55.0f, 55.0f, 55.0f ) );
  421. RunSingleSetAttributeUndoTest( pTest, pOriginal, pElement, "qangle_test", QAngle( 55.0f, 55.0f, -55.0f ) );
  422. RunSingleSetAttributeUndoTest( pTest, pOriginal, pElement, "quat_test", Quaternion( 1.0f, -1.0f, 0.0f, 55.0f ) );
  423. RunSingleSetAttributeUndoTest( pTest, pOriginal, pElement, "vmatrix_test", mat );
  424. // Now run a single test with a bunch of operations occurring at the same time
  425. {
  426. {
  427. CUndoScopeGuard guard( "biggish", "smallish" );
  428. pElement->SetValue( "bool_test", false );
  429. pElement->SetValue( "int_test", 55 );
  430. pElement->SetValue( "float_test", 55.0f );
  431. pElement->SetValue( "color_test", Color( 55, 55, 55, 55 ) );
  432. pElement->SetValue( "vector2d_test", Vector2D( 55.0f, -55.0f ) );
  433. pElement->SetValue( "vector3d_test", Vector( 55.0f, -55.0f, 55.0f ) );
  434. pElement->SetValue( "vector4d_test", Vector4D( 55.0f, -55.0f, 55.0f, 55.0f ) );
  435. pElement->SetValue( "qangle_test", QAngle( 55.0f, 55.0f, -55.0f ) );
  436. pElement->SetValue( "quat_test", Quaternion( 1.0f, -1.0f, 0.0f, 55.0f ) );
  437. pElement->SetValue( "vmatrix_test", mat );
  438. pElement->SetValue( "string_test", "55test" );
  439. pElement->SetValue( "binary_test", buf, 256 );
  440. }
  441. g_pDataModel->Undo();
  442. AssertEqualElementHierarchies( false, pTest, pOriginal );
  443. g_pDataModel->Redo();
  444. g_pDataModel->Undo();
  445. AssertEqualElementHierarchies( false, pTest, pOriginal );
  446. }
  447. // Now run a test with multiple items in the stack
  448. {
  449. // Push 1
  450. {
  451. CUndoScopeGuard guard( "biggish1", "smallish1" );
  452. pElement->SetValue( "bool_test", false );
  453. pElement->SetValue( "int_test", 55 );
  454. pElement->SetValue( "float_test", 55.0f );
  455. pElement->SetValue( "color_test", Color( 55, 55, 55, 55 ) );
  456. }
  457. // Push 2
  458. {
  459. CUndoScopeGuard guard( "biggish2", "smallish2" );
  460. pElement->SetValue( "vector2d_test", Vector2D( 55.0f, -55.0f ) );
  461. pElement->SetValue( "vector3d_test", Vector( 55.0f, -55.0f, 55.0f ) );
  462. pElement->SetValue( "vector4d_test", Vector4D( 55.0f, -55.0f, 55.0f, 55.0f ) );
  463. pElement->SetValue( "qangle_test", QAngle( 55.0f, 55.0f, -55.0f ) );
  464. pElement->SetValue( "quat_test", Quaternion( 1.0f, -1.0f, 0.0f, 55.0f ) );
  465. }
  466. // Push 3
  467. {
  468. CUndoScopeGuard guard( "biggish3", "smallish3" );
  469. pElement->SetValue( "vmatrix_test", mat );
  470. pElement->SetValue( "string_test", "55test" );
  471. pElement->SetValue( "binary_test", buf, 256 );
  472. }
  473. // Tests
  474. {
  475. g_pDataModel->Undo();
  476. g_pDataModel->Undo();
  477. g_pDataModel->Undo();
  478. AssertEqualElementHierarchies( false, pTest, pOriginal );
  479. g_pDataModel->Redo();
  480. g_pDataModel->Redo();
  481. g_pDataModel->Redo();
  482. g_pDataModel->Undo();
  483. g_pDataModel->Undo();
  484. g_pDataModel->Undo();
  485. AssertEqualElementHierarchies( false, pTest, pOriginal );
  486. }
  487. }
  488. // Now run "add" tests on a subset -- add adds an attribute where one didn't already exist
  489. RunSingleAddAttributeUndoTest( pTest, pOriginal, pElement2, "int_test_added", 55 );
  490. // Now run "remove" tests on a subset of attributes -- removes an existing attribute by name
  491. RunSingleRemoveAttributeUndoTest( pTest, pOriginal, pTest, "int_test" );
  492. }
  493. #include "datamodel/dmehandle.h"
  494. void RunUndoTestCreateElement()
  495. {
  496. DmFileId_t fileid = g_pDataModel->FindOrCreateFileId( "<RunUndoTestCreateElement>" );
  497. CDmElement *element = NULL;
  498. {
  499. CUndoScopeGuard guard( "create" );
  500. element = CreateElement< CDmElement >( "test", fileid );
  501. }
  502. CDmeHandle< CDmElement > hChannel;
  503. hChannel = element;
  504. Assert( hChannel.Get() );
  505. g_pDataModel->Undo();
  506. Assert( !hChannel.Get() );
  507. g_pDataModel->Redo();
  508. Assert( hChannel.Get() );
  509. g_pDataModel->Undo(); // It's on the redo stack, but marked as kill and all ptrs are NULL to it
  510. Assert( !hChannel.Get() );
  511. g_pDataModel->ClearUndo();
  512. g_pDataModel->ClearRedo();
  513. g_pDataModel->RemoveFileId( fileid );
  514. }
  515. DEFINE_TESTCASE_NOSUITE( DmxUndoRedoTest )
  516. {
  517. Msg( "Running undo tests...\n" );
  518. #ifdef _DEBUG
  519. int nStartingCount = g_pDataModel->GetAllocatedElementCount();
  520. #endif
  521. CUndoScopeGuard sg( "Create Test Scenes" );
  522. DmFileId_t fileid = g_pDataModel->FindOrCreateFileId( "<DmxUndoRedoTest>" );
  523. CUtlVector< DmElementHandle_t > handles;
  524. CreateTestScene( handles, fileid );
  525. DmElementHandle_t hOriginal = handles[ 0 ];
  526. handles.RemoveAll();
  527. CreateTestScene( handles, fileid );
  528. DmElementHandle_t hTest = handles[ 0 ];
  529. sg.Release();
  530. CDmElement *pOriginal = static_cast<CDmElement*>( g_pDataModel->GetElement( hOriginal ) );
  531. CDmElement *pTest = static_cast<CDmElement*>(g_pDataModel->GetElement( hTest ) );
  532. AssertEqualElementHierarchies( false, pTest, pOriginal );
  533. RunUndoTests( handles, pTest, pOriginal );
  534. RunUndoTestsArray( handles, pTest, pOriginal );
  535. RunUndoTestCreateElement();
  536. g_pDataModel->ClearUndo();
  537. g_pDataModel->RemoveFileId( fileid );
  538. #ifdef _DEBUG
  539. int nEndingCount = g_pDataModel->GetAllocatedElementCount();
  540. AssertEquals( nEndingCount, nStartingCount );
  541. if ( nEndingCount != nStartingCount )
  542. {
  543. for ( DmElementHandle_t hElement = g_pDataModel->FirstAllocatedElement() ;
  544. hElement != DMELEMENT_HANDLE_INVALID;
  545. hElement = g_pDataModel->NextAllocatedElement( hElement ) )
  546. {
  547. CDmElement *pElement = g_pDataModel->GetElement( hElement );
  548. Assert( pElement );
  549. if ( !pElement )
  550. return;
  551. Msg( "[%s : %s] in memory\n", pElement->GetName(), pElement->GetTypeString() );
  552. }
  553. }
  554. #endif
  555. }
  556. #include "datamodel/dmelementfactoryhelper.h"
  557. //-----------------------------------------------------------------------------
  558. // CDmeExternal - element class used for testing external attributes
  559. //-----------------------------------------------------------------------------
  560. class CDmeExternal : public CDmElement
  561. {
  562. DEFINE_ELEMENT( CDmeExternal, CDmElement );
  563. public:
  564. CDmaVar< float > m_External;
  565. };
  566. IMPLEMENT_ELEMENT_FACTORY( DmeExternal, CDmeExternal );
  567. void CDmeExternal::OnConstruction()
  568. {
  569. m_External .InitAndSet( this, "external", 99.9f );
  570. }
  571. void CDmeExternal::OnDestruction()
  572. {
  573. }
  574. USING_ELEMENT_FACTORY( DmeExternal );
  575. DEFINE_TESTCASE_NOSUITE( DmxExternalAttributeTest )
  576. {
  577. Msg( "Running external attribute test...\n" );
  578. DmFileId_t fileid = g_pDataModel->FindOrCreateFileId( "<DmxExternalAttributeTest>" );
  579. CDmeExternal *pOriginal = 0;
  580. #ifdef _DEBUG
  581. int nStartingCount = g_pDataModel->GetAllocatedElementCount();
  582. #endif
  583. {
  584. CUndoScopeGuard guard( "External" );
  585. pOriginal = CreateElement<CDmeExternal>( "foo", fileid );
  586. for ( int m = 0; m < 1; ++m )
  587. {
  588. CDmeExternal *discard = CreateElement<CDmeExternal>( "foo", fileid );
  589. g_pDataModel->DestroyElement( discard->GetHandle() );
  590. }
  591. }
  592. // Now mess with vars
  593. g_pDataModel->Undo();
  594. g_pDataModel->Redo();
  595. {
  596. CUndoScopeGuard guard( "External2" );
  597. pOriginal->m_External.Set( 100.0f );
  598. }
  599. g_pDataModel->ClearUndo();
  600. g_pDataModel->RemoveFileId( fileid );
  601. #ifdef _DEBUG
  602. int nEndingCount = g_pDataModel->GetAllocatedElementCount();
  603. AssertEquals( nEndingCount, nStartingCount );
  604. if ( nEndingCount != nStartingCount )
  605. {
  606. for ( DmElementHandle_t hElement = g_pDataModel->FirstAllocatedElement() ;
  607. hElement != DMELEMENT_HANDLE_INVALID;
  608. hElement = g_pDataModel->NextAllocatedElement( hElement ) )
  609. {
  610. CDmElement *pElement = g_pDataModel->GetElement( hElement );
  611. Assert( pElement );
  612. if ( !pElement )
  613. return;
  614. Msg( "[%s : %s] in memory\n", pElement->GetName(), pElement->GetTypeString() );
  615. }
  616. }
  617. #endif
  618. }
  619. void Assert_InvalidAndNULL( CDmeHandle< CDmElement > &hElement )
  620. {
  621. Shipping_Assert( !hElement.Get() );
  622. if ( !hElement.Get() )
  623. {
  624. g_pDataModel->MarkHandleValid( hElement.GetHandle() );
  625. Shipping_Assert( !hElement.Get() );
  626. if ( hElement.Get() )
  627. {
  628. g_pDataModel->MarkHandleInvalid( hElement.GetHandle() );
  629. }
  630. }
  631. }
  632. void Assert_InvalidButNonNULL( CDmeHandle< CDmElement > &hElement )
  633. {
  634. Shipping_Assert( !hElement.Get() );
  635. if ( !hElement.Get() )
  636. {
  637. g_pDataModel->MarkHandleValid( hElement.GetHandle() );
  638. Shipping_Assert( hElement.Get() );
  639. if ( hElement.Get() )
  640. {
  641. g_pDataModel->MarkHandleInvalid( hElement.GetHandle() );
  642. }
  643. }
  644. }
  645. void Assert_ValidAndNonNULL( CDmeHandle< CDmElement > &hElement )
  646. {
  647. Shipping_Assert( hElement.Get() );
  648. }
  649. DEFINE_TESTCASE_NOSUITE( DmxReferenceCountingTest )
  650. {
  651. Msg( "Running external attribute test...\n" );
  652. DmFileId_t fileid = g_pDataModel->FindOrCreateFileId( "<DmxReferenceCountingTest>" );
  653. CDmeHandle< CDmElement > hRoot;
  654. CDmeHandle< CDmElement > hChild1, hChild2, hChild3, hChild4, hChild5;
  655. CDmeHandle< CDmElement > hGrandChild1, hGrandChild2, hGrandChild3, hGrandChild4, hGrandChild5, hGrandChild6, hGrandChild7;
  656. CDmeCountedHandle hStrong6, hStrong7;
  657. g_pDmElementFramework->BeginEdit();
  658. int nStartingCount = g_pDataModel->GetAllocatedElementCount();
  659. Shipping_Assert( nStartingCount == 0 );
  660. {
  661. CUndoScopeGuard guard( "Create RefCountTest Elements" );
  662. hRoot = CreateElement<CDmElement>( "root", fileid );
  663. CDmrElementArray<> arrayRoot( hRoot, "children", true );
  664. g_pDataModel->SetFileRoot( fileid, hRoot->GetHandle() );
  665. hChild1 = CreateElement<CDmElement>( "child1", fileid );
  666. CDmrElementArray<> arrayChild1( hChild1, "children", true );
  667. arrayRoot.AddToTail( hChild1.Get() );
  668. hChild2 = CreateElement<CDmElement>( "child2", fileid );
  669. hChild2->AddAttributeElement<CDmElement>( "child" );
  670. arrayRoot.AddToTail( hChild2.Get() );
  671. hChild3 = CreateElement<CDmElement>( "child3", fileid );
  672. hChild3->AddAttributeElement<CDmElement>( "child" );
  673. arrayRoot.AddToTail( hChild3.Get() );
  674. hChild4 = CreateElement<CDmElement>( "child4", fileid );
  675. hChild4->AddAttributeElement<CDmElement>( "child" );
  676. arrayRoot.AddToTail( hChild4.Get() );
  677. hChild5 = CreateElement<CDmElement>( "child5", fileid );
  678. CDmrElementArray<> arrayChild5( hChild5, "children", true );
  679. arrayRoot.AddToTail( hChild5.Get() );
  680. hGrandChild1 = CreateElement<CDmElement>( "grandchild1", fileid );
  681. arrayChild1.AddToTail( hGrandChild1.Get() );
  682. hGrandChild2 = CreateElement<CDmElement>( "grandchild2", fileid );
  683. arrayChild1.AddToTail( hGrandChild2.Get() );
  684. hChild2->SetValue( "child", hGrandChild2.GetHandle() );
  685. hGrandChild3 = CreateElement<CDmElement>( "grandchild3", fileid );
  686. arrayChild1.AddToTail( hGrandChild3.Get() );
  687. hChild3->SetValue( "child", hGrandChild3.GetHandle() );
  688. hGrandChild4 = CreateElement<CDmElement>( "grandchild4", fileid );
  689. arrayChild1.AddToTail( hGrandChild4.Get() );
  690. hChild4->SetValue( "child", hGrandChild4.GetHandle() );
  691. hGrandChild5 = CreateElement<CDmElement>( "grandchild5", fileid );
  692. arrayChild1.AddToTail( hGrandChild5.Get() );
  693. arrayChild5.AddToTail( hGrandChild5.Get() );
  694. hGrandChild6 = CreateElement<CDmElement>( "grandchild6", fileid );
  695. arrayChild1.AddToTail( hGrandChild6.Get() );
  696. hStrong6 = hGrandChild6;
  697. hGrandChild7 = CreateElement<CDmElement>( "grandchild7", fileid );
  698. arrayChild1.AddToTail( hGrandChild7.Get() );
  699. hStrong7 = hGrandChild7;
  700. }
  701. g_pDmElementFramework->BeginEdit();
  702. int nCreateCount = g_pDataModel->GetAllocatedElementCount();
  703. Assert( nCreateCount == nStartingCount + 13 );
  704. Assert_ValidAndNonNULL ( hRoot );
  705. Assert_ValidAndNonNULL ( hChild1 );
  706. Assert_ValidAndNonNULL ( hChild2 );
  707. Assert_ValidAndNonNULL ( hChild3 );
  708. Assert_ValidAndNonNULL ( hChild4 );
  709. Assert_ValidAndNonNULL ( hChild5 );
  710. Assert_ValidAndNonNULL ( hGrandChild1 );
  711. Assert_ValidAndNonNULL ( hGrandChild2 );
  712. Assert_ValidAndNonNULL ( hGrandChild3 );
  713. Assert_ValidAndNonNULL ( hGrandChild4 );
  714. Assert_ValidAndNonNULL ( hGrandChild5 );
  715. Assert_ValidAndNonNULL ( hGrandChild6 );
  716. Assert_ValidAndNonNULL ( hGrandChild7 );
  717. g_pDataModel->ClearUndo();
  718. g_pDmElementFramework->BeginEdit();
  719. int nPostCreateCount = g_pDataModel->GetAllocatedElementCount();
  720. Shipping_Assert( nPostCreateCount == nCreateCount );
  721. Assert_ValidAndNonNULL ( hRoot );
  722. Assert_ValidAndNonNULL ( hChild1 );
  723. Assert_ValidAndNonNULL ( hChild2 );
  724. Assert_ValidAndNonNULL ( hChild3 );
  725. Assert_ValidAndNonNULL ( hChild4 );
  726. Assert_ValidAndNonNULL ( hChild5 );
  727. Assert_ValidAndNonNULL ( hGrandChild1 );
  728. Assert_ValidAndNonNULL ( hGrandChild2 );
  729. Assert_ValidAndNonNULL ( hGrandChild3 );
  730. Assert_ValidAndNonNULL ( hGrandChild4 );
  731. Assert_ValidAndNonNULL ( hGrandChild5 );
  732. Assert_ValidAndNonNULL ( hGrandChild6 );
  733. Assert_ValidAndNonNULL ( hGrandChild7 );
  734. {
  735. CUndoScopeGuard guard( "Edit RefCountTest Elements" );
  736. CDmrGenericArray children( hChild1, "children" );
  737. children.RemoveAll(); // grandchild1 unref'ed to 0, grandchild2..6 unref'ed to 1
  738. hChild2->SetValue( "child", DMELEMENT_HANDLE_INVALID ); // grandchild2 unref'ed to 0
  739. g_pDataModel->DestroyElement( hChild3 ); // grandchild3 is unref'ed to 0
  740. CDmrElementArray<> children5( hChild5, "children" );
  741. children5.Set( 0, NULL ); // grandchild5 is unref'ed to 0
  742. hStrong6 = DMELEMENT_HANDLE_INVALID; // grandchild6 is unref'ed to 0
  743. }
  744. g_pDmElementFramework->BeginEdit();
  745. int nEditCount = g_pDataModel->GetAllocatedElementCount();
  746. Shipping_Assert( nEditCount == nCreateCount - 1 );
  747. Assert_ValidAndNonNULL ( hRoot );
  748. Assert_ValidAndNonNULL ( hChild1 );
  749. Assert_ValidAndNonNULL ( hChild2 );
  750. Assert_InvalidButNonNULL( hChild3 );
  751. Assert_ValidAndNonNULL ( hChild4 );
  752. Assert_ValidAndNonNULL ( hChild5 );
  753. Assert_ValidAndNonNULL ( hGrandChild1 );
  754. Assert_ValidAndNonNULL ( hGrandChild2 );
  755. Assert_ValidAndNonNULL ( hGrandChild3 );
  756. Assert_ValidAndNonNULL ( hGrandChild4 );
  757. Assert_ValidAndNonNULL ( hGrandChild5 );
  758. Assert_ValidAndNonNULL ( hGrandChild6 );
  759. Assert_ValidAndNonNULL ( hGrandChild7 );
  760. g_pDataModel->Undo();
  761. g_pDmElementFramework->BeginEdit();
  762. int nUndoCount = g_pDataModel->GetAllocatedElementCount();
  763. Shipping_Assert( nUndoCount == nCreateCount );
  764. Assert_ValidAndNonNULL ( hRoot );
  765. Assert_ValidAndNonNULL ( hChild1 );
  766. Assert_ValidAndNonNULL ( hChild2 );
  767. Assert_ValidAndNonNULL ( hChild3 );
  768. Assert_ValidAndNonNULL ( hChild4 );
  769. Assert_ValidAndNonNULL ( hChild5 );
  770. Assert_ValidAndNonNULL ( hGrandChild1 );
  771. Assert_ValidAndNonNULL ( hGrandChild2 );
  772. Assert_ValidAndNonNULL ( hGrandChild3 );
  773. Assert_ValidAndNonNULL ( hGrandChild4 );
  774. Assert_ValidAndNonNULL ( hGrandChild5 );
  775. Assert_ValidAndNonNULL ( hGrandChild6 );
  776. Assert_ValidAndNonNULL ( hGrandChild7 );
  777. g_pDataModel->Redo();
  778. g_pDmElementFramework->BeginEdit();
  779. int nRedoCount = g_pDataModel->GetAllocatedElementCount();
  780. Shipping_Assert( nRedoCount == nEditCount );
  781. Assert_ValidAndNonNULL ( hRoot );
  782. Assert_ValidAndNonNULL ( hChild1 );
  783. Assert_ValidAndNonNULL ( hChild2 );
  784. Assert_InvalidButNonNULL( hChild3 );
  785. Assert_ValidAndNonNULL ( hChild4 );
  786. Assert_ValidAndNonNULL ( hChild5 );
  787. Assert_ValidAndNonNULL ( hGrandChild1 );
  788. Assert_ValidAndNonNULL ( hGrandChild2 );
  789. Assert_ValidAndNonNULL ( hGrandChild3 );
  790. Assert_ValidAndNonNULL ( hGrandChild4 );
  791. Assert_ValidAndNonNULL ( hGrandChild5 );
  792. Assert_ValidAndNonNULL ( hGrandChild6 );
  793. Assert_ValidAndNonNULL ( hGrandChild7 );
  794. g_pDataModel->ClearUndo();
  795. g_pDmElementFramework->BeginEdit();
  796. int nClearUndoCount = g_pDataModel->GetAllocatedElementCount();
  797. Shipping_Assert( nClearUndoCount == nCreateCount - 6 );
  798. Assert_ValidAndNonNULL ( hRoot );
  799. Assert_ValidAndNonNULL ( hChild1 );
  800. Assert_ValidAndNonNULL ( hChild2 );
  801. Assert_InvalidAndNULL ( hChild3 );
  802. Assert_ValidAndNonNULL ( hChild4 );
  803. Assert_ValidAndNonNULL ( hChild5 );
  804. Assert_InvalidAndNULL ( hGrandChild1 );
  805. Assert_InvalidAndNULL ( hGrandChild2 );
  806. Assert_InvalidAndNULL ( hGrandChild3 );
  807. Assert_ValidAndNonNULL ( hGrandChild4 );
  808. Assert_InvalidAndNULL ( hGrandChild5 );
  809. Assert_InvalidAndNULL ( hGrandChild6 );
  810. Assert_ValidAndNonNULL ( hGrandChild7 );
  811. g_pDataModel->RemoveFileId( fileid );
  812. }