diff options
Diffstat (limited to 'datamodel/DmElementFramework.cpp')
| -rw-r--r-- | datamodel/DmElementFramework.cpp | 209 |
1 files changed, 209 insertions, 0 deletions
diff --git a/datamodel/DmElementFramework.cpp b/datamodel/DmElementFramework.cpp new file mode 100644 index 0000000..94813b2 --- /dev/null +++ b/datamodel/DmElementFramework.cpp @@ -0,0 +1,209 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//============================================================================= + +#include "DmElementFramework.h" +#include "datamodel.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + + +//----------------------------------------------------------------------------- +// Singleton instance +//----------------------------------------------------------------------------- +static CDmElementFramework g_DmElementFramework; +CDmElementFramework *g_pDmElementFrameworkImp = &g_DmElementFramework; +IDmElementFramework *g_pDmElementFramework = &g_DmElementFramework; + + +//----------------------------------------------------------------------------- +// Constructor +//----------------------------------------------------------------------------- +CDmElementFramework::CDmElementFramework() : m_phase( PH_EDIT ), m_dirtyElements( 128, 256 ) +{ +} + + +//----------------------------------------------------------------------------- +// Methods of IAppSystem +//----------------------------------------------------------------------------- +bool CDmElementFramework::Connect( CreateInterfaceFn factory ) +{ + return true; +} + +void CDmElementFramework::Disconnect() +{ +} + +void *CDmElementFramework::QueryInterface( const char *pInterfaceName ) +{ + if ( !V_strcmp( pInterfaceName, VDMELEMENTFRAMEWORK_VERSION ) ) + return (IDmElementFramework*)this; + + return NULL; +} + +InitReturnVal_t CDmElementFramework::Init( ) +{ + return INIT_OK; +} + +void CDmElementFramework::Shutdown() +{ + m_dependencyGraph.Cleanup(); +} + + +//----------------------------------------------------------------------------- +// element framework phase transition methods +//----------------------------------------------------------------------------- +void CDmElementFramework::EditApply() +{ + g_pDataModelImp->RemoveUnreferencedElements(); +} + +void CDmElementFramework::Resolve( bool clearDirtyFlags ) +{ + int nCount = m_dirtyElements.Count(); + for ( int ei = 0; ei < nCount; ++ei ) + { + DmElementHandle_t h = m_dirtyElements[ ei ]; + CDmElement *pElement = g_pDataModel->GetElement( h ); + if ( !pElement ) + continue; + + pElement->Resolve(); + + if ( clearDirtyFlags ) + { + CDmeElementAccessor::MarkDirty( pElement, false ); // marks element clean + CDmeElementAccessor::MarkAttributesClean( pElement ); // marks all attributes clean + } + } + + if ( clearDirtyFlags ) + { + m_dirtyElements.RemoveAll(); + } +} + + +//----------------------------------------------------------------------------- +// Returns the current phase +//----------------------------------------------------------------------------- +DmPhase_t CDmElementFramework::GetPhase() +{ + return FastGetPhase(); +} + +void CDmElementFramework::SetOperators( const CUtlVector< IDmeOperator* > &operators ) +{ + VPROF( "CDmElementFramework::SetOperators()" ); + m_dependencyGraph.Reset( operators ); +} + +void CDmElementFramework::BeginEdit() +{ + Assert( m_phase == PH_EDIT || m_phase == PH_OUTPUT ); + + if ( m_phase == PH_EDIT ) + { + m_phase = PH_EDIT_APPLY; + EditApply(); + + m_phase = PH_EDIT_RESOLVE; + Resolve( false ); + } + + m_phase = PH_EDIT; +} + +void CDmElementFramework::Operate( bool bResolve ) +{ + VPROF( "CDmElementFramework::Operate" ); + + Assert( m_phase == PH_EDIT || m_phase == PH_OUTPUT ); + + if ( m_phase == PH_EDIT ) + { + { + VPROF( "CDmElementFramework::PH_EDIT_APPLY" ); + m_phase = PH_EDIT_APPLY; + EditApply(); + } + + { + VPROF( "CDmElementFramework::PH_EDIT_RESOLVE" ); + m_phase = PH_EDIT_RESOLVE; + Resolve( false ); + } + } + + { + VPROF( "CDmElementFramework::PH_DEPENDENCY" ); + m_phase = PH_DEPENDENCY; + bool cycle = m_dependencyGraph.CullAndSortOperators(); + if ( cycle ) + { + Warning( "Operator cycle found during dependency graph traversal!\n" ); + } + } + + { + VPROF( "CDmElementFramework::PH_OPERATE" ); + m_phase = PH_OPERATE; + const CUtlVector< IDmeOperator* > &operatorsToRun = m_dependencyGraph.GetSortedOperators(); + uint on = operatorsToRun.Count(); + for ( uint oi = 0; oi < on; ++oi ) + { + operatorsToRun[ oi ]->Operate(); + } + } + + if ( bResolve ) + { + VPROF( "CDmElementFramework::PH_OPERATE_RESOLVE" ); + m_phase = PH_OPERATE_RESOLVE; + Resolve( true ); + + m_phase = PH_OUTPUT; + } +} + +void CDmElementFramework::Resolve() +{ + VPROF( "CDmElementFramework::Resolve" ); + + Assert( m_phase == PH_OPERATE ); + + m_phase = PH_OPERATE_RESOLVE; + Resolve( true ); + + m_phase = PH_OUTPUT; +} + +void CDmElementFramework::AddElementToDirtyList( DmElementHandle_t hElement ) +{ + m_dirtyElements.AddToTail( hElement ); +} + +void CDmElementFramework::RemoveCleanElementsFromDirtyList() +{ + int nCount = m_dirtyElements.Count(); + while ( --nCount >= 0 ) + { + DmElementHandle_t h = m_dirtyElements[ nCount ]; + CDmElement *pElement = g_pDataModel->GetElement( h ); + if ( !pElement ) + continue; + + if ( !CDmeElementAccessor::IsDirty( pElement ) ) + { + m_dirtyElements.FastRemove( nCount ); + } + } +} |