mirror of
https://github.com/nillerusr/source-engine.git
synced 2024-12-23 06:36:54 +00:00
210 lines
4.8 KiB
C++
210 lines
4.8 KiB
C++
//========= 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 );
|
|
}
|
|
}
|
|
}
|