|
|
//====== Copyright � 1996-2004, Valve Corporation, All rights reserved. =======
//http://www.nfl.com/gamecenter/2010010900/2009/POST18/eagles@cowboys#tab:watch
// 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/utlsymbollarge.h"
//-----------------------------------------------------------------------------
// Internal interface for IDmElementFactory
//-----------------------------------------------------------------------------
class CDmElementFactoryInternal : public IDmElementFactory { public: virtual void SetElementTypeSymbol( CUtlSymbolLarge sym ) = 0; virtual bool IsAbstract() const = 0;
virtual CUtlSymbolLarge GetElementTypeSymbol() const = 0; virtual CUtlSymbolLarge GetParentElementTypeSymbol() const = 0;
virtual void AddOnElementCreatedCallback( IDmeElementCreated *pCallback ); virtual void RemoveOnElementCreatedCallback( IDmeElementCreated *pCallback ); virtual void OnElementCreated( CDmElement* pElement ); private: CUtlVector< IDmeElementCreated* > m_CallBackList; };
//-----------------------------------------------------------------------------
// 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, CDmElementFactoryInternal *pFactory, bool bIsStandardFactory );
// Accessors
CDmElementFactoryHelper *GetNext () { return m_pNext; } CDmElementFactoryHelper *GetParent () { return m_pParent; } CDmElementFactoryHelper *GetChild () { return m_pChild; } CDmElementFactoryHelper *GetSibling() { return m_pSibling; }
const char *GetClassname(); CDmElementFactoryInternal *GetFactory();
private: CDmElementFactoryHelper() {}
// Next factory in list
CDmElementFactoryHelper *m_pNext;
// class hierarchy links
CDmElementFactoryHelper *m_pParent; CDmElementFactoryHelper *m_pChild; CDmElementFactoryHelper *m_pSibling;
// Creation function to use for this technology
CDmElementFactoryInternal *m_pFactory; const char *m_pszClassname; };
//-----------------------------------------------------------------------------
// Inline methods
//-----------------------------------------------------------------------------
inline const char *CDmElementFactoryHelper::GetClassname() { return m_pszClassname; }
inline CDmElementFactoryInternal *CDmElementFactoryHelper::GetFactory() { return m_pFactory; }
//-----------------------------------------------------------------------------
// Helper Template factory for simple creation of factories
//-----------------------------------------------------------------------------
template < class T > class CDmElementFactory : public CDmElementFactoryInternal { 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( CUtlSymbolLarge sym ) { T::SetTypeSymbol( sym ); }
virtual bool IsAbstract() const { return false; }
virtual CUtlSymbolLarge GetElementTypeSymbol() const { return T::GetStaticTypeSymbol(); } virtual CUtlSymbolLarge GetParentElementTypeSymbol() const { CUtlSymbolLarge baseClassSym = T::BaseClass::GetStaticTypeSymbol(); if ( baseClassSym == T::GetStaticTypeSymbol() ) return UTL_INVAL_SYMBOL_LARGE; // only CDmElement has itself as it's BaseClass - this lets us know we're at the top of the hierarchy
return baseClassSym; }
private: const char *m_pLookupName; };
template < class T > class CDmAbstractElementFactory : public CDmElementFactoryInternal { 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( CUtlSymbolLarge sym ) { T::SetTypeSymbol( sym ); }
virtual bool IsAbstract() const { return true; }
virtual CUtlSymbolLarge GetElementTypeSymbol() const { return T::GetStaticTypeSymbol(); } virtual CUtlSymbolLarge GetParentElementTypeSymbol() const { CUtlSymbolLarge baseClassSym = T::BaseClass::GetStaticTypeSymbol(); if ( baseClassSym == T::GetStaticTypeSymbol() ) return UTL_INVAL_SYMBOL_LARGE; // only CDmElement has itself as it's BaseClass - this lets us know we're at the top of the hierarchy
return baseClassSym; }
private: };
//-----------------------------------------------------------------------------
// Helper macro to create the class factory
//-----------------------------------------------------------------------------
#if defined( MOVIEOBJECTS_LIB ) || defined ( DATAMODEL_LIB ) || defined ( DMECONTROLS_LIB ) || defined ( MDLOBJECTS_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;
//-----------------------------------------------------------------------------
// Used to instantiate classes in libs from dlls/exes
//-----------------------------------------------------------------------------
#define USING_ELEMENT_FACTORY( className ) \
extern C##className *g_##C##className##LinkerHack; \ C##className *g_##C##className##PullInModule = g_##C##className##LinkerHack;
//-----------------------------------------------------------------------------
// Installs dm element factories
//-----------------------------------------------------------------------------
void InstallDmElementFactories( );
#endif // DMELEMENTFACTORYHELPER_H
|