//========= Copyright Valve Corporation, All rights reserved. ============// // // Purpose: // //============================================================================= #ifndef DMELEMENTFACTORYHELPER_H #define DMELEMENTFACTORYHELPER_H #ifdef _WIN32 #pragma once #endif #include "datamodel/dmattribute.h" #include "datamodel/dmattributevar.h" #include "datamodel/dmelement.h" #include "datamodel/idatamodel.h" #include "tier1/utlsymbol.h" #include "tier1/utlvector.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(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 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 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 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 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 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 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