157 lines
4.9 KiB
C++
157 lines
4.9 KiB
C++
|
//====== 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 );
|
|||
|
}
|
|||
|
}
|
|||
|
|