//========= 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 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() {} // 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