source-engine-2018-hl2_src/datamodel/DmElementFramework.cpp

210 lines
4.8 KiB
C++
Raw Normal View History

2020-04-23 00:56:21 +08:00
//========= 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 );
}
}
}