csgo-2018-source/datamodel/dmelementfactoryhelper.cpp

157 lines
4.9 KiB
C++
Raw Permalink Normal View History

2021-07-25 12:11:47 +08:00
//====== Copyright <20> 1996-2004, Valve Corporation, All rights reserved. =======
//
// Purpose:
//
//=============================================================================
#include "datamodel/dmelementfactoryhelper.h"
#include "tier0/dbg.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
CDmElementFactoryHelper *CDmElementFactoryHelper::s_pHelpers[2] = { NULL, NULL };
//-----------------------------------------------------------------------------
// Constructor
//-----------------------------------------------------------------------------
CDmElementFactoryHelper::CDmElementFactoryHelper( const char *classname, CDmElementFactoryInternal *pFactory, bool bIsStandardFactory )
: m_pParent( NULL ), m_pChild( NULL ), m_pSibling( NULL )
{
m_pNext = s_pHelpers[bIsStandardFactory];
s_pHelpers[bIsStandardFactory] = this;
// Set attributes
Assert( pFactory );
m_pFactory = pFactory;
Assert( classname );
m_pszClassname = classname;
}
//-----------------------------------------------------------------------------
// Installs all factories into the datamodel system
//-----------------------------------------------------------------------------
// NOTE: The name of this extern is defined by the macro IMPLEMENT_ELEMENT_FACTORY
extern CDmElementFactoryHelper g_CDmElement_Helper;
void CDmElementFactoryHelper::InstallFactories()
{
static bool s_bInstalled = false;
if ( s_bInstalled )
return;
s_bInstalled = true;
// Just set up the type symbols of the other factories
for ( CDmElementFactoryHelper *pHelper = s_pHelpers[ 0 ]; pHelper; pHelper = pHelper->GetNext() )
{
CDmElementFactoryInternal *pFactory = pHelper->GetFactory();
g_pDataModel->AddElementFactory( pHelper );
// Set up the type symbol. Note this can't be done at
// constructor time since we don't have a DataModel pointer then
pFactory->SetElementTypeSymbol( g_pDataModel->GetSymbol( pHelper->GetClassname() ) );
}
for ( CDmElementFactoryHelper *pHelper = s_pHelpers[ 1 ]; pHelper; pHelper = pHelper->GetNext() )
{
// Add factories to database, but not if they've been overridden
if ( !g_pDataModel->HasElementFactory( pHelper->GetClassname() ) )
{
CDmElementFactoryInternal *pFactory = pHelper->GetFactory();
g_pDataModel->AddElementFactory( pHelper );
// Set up the type symbol. Note this can't be done at
// constructor time since we don't have a DataModel pointer then
// Backward compat--don't let the type symbol be 'DmeElement'
if ( Q_stricmp( pHelper->GetClassname(), "DmeElement" ) )
{
pFactory->SetElementTypeSymbol( g_pDataModel->GetSymbol( pHelper->GetClassname() ) );
}
}
}
// Also install the DmElement factory as the default factory
g_pDataModel->SetDefaultElementFactory( g_CDmElement_Helper.GetFactory() );
for ( int i = 0; i < 2; ++i )
{
for ( CDmElementFactoryHelper *pHelper = s_pHelpers[ i ]; pHelper; pHelper = pHelper->GetNext() )
{
CDmElementFactoryInternal *pFactory = pHelper->GetFactory();
CUtlSymbolLarge parentElementTypeSym = pFactory->GetParentElementTypeSymbol();
if ( !parentElementTypeSym.IsValid() )
continue; // helper has no parent, and therefore no sibling
const char *pParentFactoryName = parentElementTypeSym.String();
CDmElementFactoryHelper *pParent = g_pDataModel->GetElementFactoryHelper( pParentFactoryName );
if ( !pParent )
continue;
const char *pClassName = pHelper->GetClassname();
CDmElementFactoryHelper *pSibling = pParent->GetChild();
if ( !pSibling || V_stricmp( pClassName, pSibling->GetClassname() ) < 0 )
{
pParent->m_pChild = pHelper;
pHelper->m_pSibling = pSibling;
Assert( pHelper->m_pSibling != pHelper );
}
else
{
while ( true )
{
CDmElementFactoryHelper *pNext = pSibling->GetSibling();
if ( !pNext || V_stricmp( pClassName, pNext->GetClassname() ) < 0 )
break;
pSibling = pNext;
}
pHelper->m_pSibling = pSibling->m_pSibling;
Assert( pHelper->m_pSibling != pHelper );
pSibling->m_pSibling = pHelper;
Assert( pSibling->m_pSibling != pSibling );
}
}
}
}
//-----------------------------------------------------------------------------
// Installs all DmElement factories
//-----------------------------------------------------------------------------
void InstallDmElementFactories()
{
CDmElementFactoryHelper::InstallFactories();
}
//-----------------------------------------------------------------------------
void CDmElementFactoryInternal::AddOnElementCreatedCallback( IDmeElementCreated *pCallback )
{
if ( m_CallBackList.Find( pCallback ) == m_CallBackList.InvalidIndex() )
{
m_CallBackList.AddToTail( pCallback );
}
}
void CDmElementFactoryInternal::RemoveOnElementCreatedCallback( IDmeElementCreated *pCallback )
{
m_CallBackList.FindAndRemove( pCallback );
}
void CDmElementFactoryInternal::OnElementCreated( CDmElement* pElement )
{
for ( int i = 0; i < m_CallBackList.Count(); i++ )
{
m_CallBackList[i]->OnElementCreated( pElement );
}
}