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
209 lines
4.8 KiB
//========= 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 ); |
|
} |
|
} |
|
}
|
|
|