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.

209 lines
4.8 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================
  6. #include "DmElementFramework.h"
  7. #include "datamodel.h"
  8. // memdbgon must be the last include file in a .cpp file!!!
  9. #include "tier0/memdbgon.h"
  10. //-----------------------------------------------------------------------------
  11. // Singleton instance
  12. //-----------------------------------------------------------------------------
  13. static CDmElementFramework g_DmElementFramework;
  14. CDmElementFramework *g_pDmElementFrameworkImp = &g_DmElementFramework;
  15. IDmElementFramework *g_pDmElementFramework = &g_DmElementFramework;
  16. //-----------------------------------------------------------------------------
  17. // Constructor
  18. //-----------------------------------------------------------------------------
  19. CDmElementFramework::CDmElementFramework() : m_phase( PH_EDIT ), m_dirtyElements( 128, 256 )
  20. {
  21. }
  22. //-----------------------------------------------------------------------------
  23. // Methods of IAppSystem
  24. //-----------------------------------------------------------------------------
  25. bool CDmElementFramework::Connect( CreateInterfaceFn factory )
  26. {
  27. return true;
  28. }
  29. void CDmElementFramework::Disconnect()
  30. {
  31. }
  32. void *CDmElementFramework::QueryInterface( const char *pInterfaceName )
  33. {
  34. if ( !V_strcmp( pInterfaceName, VDMELEMENTFRAMEWORK_VERSION ) )
  35. return (IDmElementFramework*)this;
  36. return NULL;
  37. }
  38. InitReturnVal_t CDmElementFramework::Init( )
  39. {
  40. return INIT_OK;
  41. }
  42. void CDmElementFramework::Shutdown()
  43. {
  44. m_dependencyGraph.Cleanup();
  45. }
  46. //-----------------------------------------------------------------------------
  47. // element framework phase transition methods
  48. //-----------------------------------------------------------------------------
  49. void CDmElementFramework::EditApply()
  50. {
  51. g_pDataModelImp->RemoveUnreferencedElements();
  52. }
  53. void CDmElementFramework::Resolve( bool clearDirtyFlags )
  54. {
  55. int nCount = m_dirtyElements.Count();
  56. for ( int ei = 0; ei < nCount; ++ei )
  57. {
  58. DmElementHandle_t h = m_dirtyElements[ ei ];
  59. CDmElement *pElement = g_pDataModel->GetElement( h );
  60. if ( !pElement )
  61. continue;
  62. pElement->Resolve();
  63. if ( clearDirtyFlags )
  64. {
  65. CDmeElementAccessor::MarkDirty( pElement, false ); // marks element clean
  66. CDmeElementAccessor::MarkAttributesClean( pElement ); // marks all attributes clean
  67. }
  68. }
  69. if ( clearDirtyFlags )
  70. {
  71. m_dirtyElements.RemoveAll();
  72. }
  73. }
  74. //-----------------------------------------------------------------------------
  75. // Returns the current phase
  76. //-----------------------------------------------------------------------------
  77. DmPhase_t CDmElementFramework::GetPhase()
  78. {
  79. return FastGetPhase();
  80. }
  81. void CDmElementFramework::SetOperators( const CUtlVector< IDmeOperator* > &operators )
  82. {
  83. VPROF( "CDmElementFramework::SetOperators()" );
  84. m_dependencyGraph.Reset( operators );
  85. }
  86. void CDmElementFramework::BeginEdit()
  87. {
  88. Assert( m_phase == PH_EDIT || m_phase == PH_OUTPUT );
  89. if ( m_phase == PH_EDIT )
  90. {
  91. m_phase = PH_EDIT_APPLY;
  92. EditApply();
  93. m_phase = PH_EDIT_RESOLVE;
  94. Resolve( false );
  95. }
  96. m_phase = PH_EDIT;
  97. }
  98. void CDmElementFramework::Operate( bool bResolve )
  99. {
  100. VPROF( "CDmElementFramework::Operate" );
  101. Assert( m_phase == PH_EDIT || m_phase == PH_OUTPUT );
  102. if ( m_phase == PH_EDIT )
  103. {
  104. {
  105. VPROF( "CDmElementFramework::PH_EDIT_APPLY" );
  106. m_phase = PH_EDIT_APPLY;
  107. EditApply();
  108. }
  109. {
  110. VPROF( "CDmElementFramework::PH_EDIT_RESOLVE" );
  111. m_phase = PH_EDIT_RESOLVE;
  112. Resolve( false );
  113. }
  114. }
  115. {
  116. VPROF( "CDmElementFramework::PH_DEPENDENCY" );
  117. m_phase = PH_DEPENDENCY;
  118. bool cycle = m_dependencyGraph.CullAndSortOperators();
  119. if ( cycle )
  120. {
  121. Warning( "Operator cycle found during dependency graph traversal!\n" );
  122. }
  123. }
  124. {
  125. VPROF( "CDmElementFramework::PH_OPERATE" );
  126. m_phase = PH_OPERATE;
  127. const CUtlVector< IDmeOperator* > &operatorsToRun = m_dependencyGraph.GetSortedOperators();
  128. uint on = operatorsToRun.Count();
  129. for ( uint oi = 0; oi < on; ++oi )
  130. {
  131. operatorsToRun[ oi ]->Operate();
  132. }
  133. }
  134. if ( bResolve )
  135. {
  136. VPROF( "CDmElementFramework::PH_OPERATE_RESOLVE" );
  137. m_phase = PH_OPERATE_RESOLVE;
  138. Resolve( true );
  139. m_phase = PH_OUTPUT;
  140. }
  141. }
  142. void CDmElementFramework::Resolve()
  143. {
  144. VPROF( "CDmElementFramework::Resolve" );
  145. Assert( m_phase == PH_OPERATE );
  146. m_phase = PH_OPERATE_RESOLVE;
  147. Resolve( true );
  148. m_phase = PH_OUTPUT;
  149. }
  150. void CDmElementFramework::AddElementToDirtyList( DmElementHandle_t hElement )
  151. {
  152. m_dirtyElements.AddToTail( hElement );
  153. }
  154. void CDmElementFramework::RemoveCleanElementsFromDirtyList()
  155. {
  156. int nCount = m_dirtyElements.Count();
  157. while ( --nCount >= 0 )
  158. {
  159. DmElementHandle_t h = m_dirtyElements[ nCount ];
  160. CDmElement *pElement = g_pDataModel->GetElement( h );
  161. if ( !pElement )
  162. continue;
  163. if ( !CDmeElementAccessor::IsDirty( pElement ) )
  164. {
  165. m_dirtyElements.FastRemove( nCount );
  166. }
  167. }
  168. }