source-engine/public/datamodel/dmelementfactoryhelper.h

191 lines
6.0 KiB
C++

//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================
#ifndef DMELEMENTFACTORYHELPER_H
#define DMELEMENTFACTORYHELPER_H
#ifdef _WIN32
#pragma once
#endif
#include "datamodel/idatamodel.h"
#include "datamodel/dmelement.h"
#include "datamodel/dmattribute.h"
#include "datamodel/dmattributevar.h"
#include "tier1/utlvector.h"
#include "tier1/utlsymbol.h"
//-----------------------------------------------------------------------------
// Internal interface for IDmElementFactory
//-----------------------------------------------------------------------------
class IDmElementFactoryInternal : public IDmElementFactory
{
public:
virtual void SetElementTypeSymbol( CUtlSymbol sym ) = 0;
virtual bool IsAbstract() const = 0;
};
//-----------------------------------------------------------------------------
// Class used to register factories into a global list
//-----------------------------------------------------------------------------
class CDmElementFactoryHelper
{
public:
// Static list of helpers
static CDmElementFactoryHelper *s_pHelpers[2];
// Create all the hud elements
static void InstallFactories( );
public:
// Construction
CDmElementFactoryHelper( const char *pClassName, IDmElementFactoryInternal *pFactory, bool bIsStandardFactory );
// Accessors
CDmElementFactoryHelper *GetNext( void );
const char *GetClassname();
IDmElementFactoryInternal *GetFactory();
private:
// Next factory in list
CDmElementFactoryHelper *m_pNext;
// Creation function to use for this technology
IDmElementFactoryInternal *m_pFactory;
const char *m_pszClassname;
};
//-----------------------------------------------------------------------------
// Inline methods
//-----------------------------------------------------------------------------
inline const char *CDmElementFactoryHelper::GetClassname()
{
return m_pszClassname;
}
inline IDmElementFactoryInternal *CDmElementFactoryHelper::GetFactory()
{
return m_pFactory;
}
//-----------------------------------------------------------------------------
// Helper Template factory for simple creation of factories
//-----------------------------------------------------------------------------
template <class T >
class CDmElementFactory : public IDmElementFactoryInternal
{
public:
CDmElementFactory( const char *pLookupName ) : m_pLookupName( pLookupName ) {}
// Creation, destruction
virtual CDmElement* Create( DmElementHandle_t handle, const char *pElementType, const char *pElementName, DmFileId_t fileid, const DmObjectId_t &id )
{
return new T( handle, m_pLookupName, id, pElementName, fileid );
}
virtual void Destroy( DmElementHandle_t hElement )
{
CDmElement *pElement = g_pDataModel->GetElement( hElement );
if ( pElement )
{
T *pActualElement = static_cast< T* >( pElement );
delete pActualElement;
}
}
// Sets the type symbol, used for "isa" implementation
virtual void SetElementTypeSymbol( CUtlSymbol sym )
{
T::SetTypeSymbol( sym );
}
virtual bool IsAbstract() const { return false; }
private:
const char *m_pLookupName;
};
template < class T >
class CDmAbstractElementFactory : public IDmElementFactoryInternal
{
public:
CDmAbstractElementFactory() = default;
// Creation, destruction
virtual CDmElement* Create( DmElementHandle_t handle, const char *pElementType, const char *pElementName, DmFileId_t fileid, const DmObjectId_t &id )
{
return NULL;
}
virtual void Destroy( DmElementHandle_t hElement )
{
}
// Sets the type symbol, used for "isa" implementation
virtual void SetElementTypeSymbol( CUtlSymbol sym )
{
T::SetTypeSymbol( sym );
}
virtual bool IsAbstract() const { return true; }
private:
};
//-----------------------------------------------------------------------------
// Helper macro to create the class factory
//-----------------------------------------------------------------------------
#if defined( MOVIEOBJECTS_LIB ) || defined ( DATAMODEL_LIB ) || defined ( DMECONTROLS_LIB )
#define IMPLEMENT_ELEMENT_FACTORY( lookupName, className ) \
IMPLEMENT_ELEMENT( className ) \
CDmElementFactory< className > g_##className##_Factory( #lookupName ); \
CDmElementFactoryHelper g_##className##_Helper( #lookupName, &g_##className##_Factory, true ); \
className *g_##className##LinkerHack = NULL;
#define IMPLEMENT_ABSTRACT_ELEMENT( lookupName, className ) \
IMPLEMENT_ELEMENT( className ) \
CDmAbstractElementFactory< className > g_##className##_Factory; \
CDmElementFactoryHelper g_##className##_Helper( #lookupName, &g_##className##_Factory, true ); \
className *g_##className##LinkerHack = NULL;
#else
#define IMPLEMENT_ELEMENT_FACTORY( lookupName, className ) \
IMPLEMENT_ELEMENT( className ) \
CDmElementFactory< className > g_##className##_Factory( #lookupName ); \
CDmElementFactoryHelper g_##className##_Helper( #lookupName, &g_##className##_Factory, false ); \
className *g_##className##LinkerHack = NULL;
#define IMPLEMENT_ABSTRACT_ELEMENT( lookupName, className ) \
IMPLEMENT_ELEMENT( className ) \
CDmAbstractElementFactory< className > g_##className##_Factory; \
CDmElementFactoryHelper g_##className##_Helper( #lookupName, &g_##className##_Factory, false ); \
className *g_##className##LinkerHack = NULL;
#endif
// Used by classes defined in movieobjects or scenedatabase that must be explicitly installed
#define IMPLEMENT_ELEMENT_FACTORY_INSTALL_EXPLICITLY( lookupName, className ) \
IMPLEMENT_ELEMENT( className ) \
CDmElementFactory< className > g_##className##_Factory( #lookupName ); \
CDmElementFactoryHelper g_##className##_Helper( #lookupName, &g_##className##_Factory, false ); \
className *g_##className##LinkerHack = NULL;
//-----------------------------------------------------------------------------
// Installs dm element factories
//-----------------------------------------------------------------------------
void InstallDmElementFactories( );
#endif // DMELEMENTFACTORYHELPER_H