You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
171 lines
3.7 KiB
171 lines
3.7 KiB
//========= Copyright © 1996-2009, Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
// $NoKeywords: $ |
|
//=============================================================================// |
|
|
|
#ifndef ASW_GENERIC_CLASSMAP_H |
|
#define ASW_GENERIC_CLASSMAP_H |
|
#ifdef _WIN32 |
|
#pragma once |
|
#endif |
|
|
|
template <class T> |
|
class CGenericClassmap |
|
{ |
|
public: |
|
typedef T *( *DISPATCHFUNCTION )( void ); |
|
|
|
CGenericClassmap() { } |
|
~CGenericClassmap() { } |
|
|
|
void Add( const char *mapname, const char *classname, int size, DISPATCHFUNCTION factory = 0 ); |
|
char const *Lookup( const char *classname ); |
|
T *CreateInstance( const char *mapname ); |
|
int GetClassSize( const char *classname ); |
|
|
|
private: |
|
class classentry_t |
|
{ |
|
public: |
|
classentry_t() |
|
{ |
|
mapname[ 0 ] = 0; |
|
factory = 0; |
|
size = -1; |
|
} |
|
|
|
char const *GetMapName() const |
|
{ |
|
return mapname; |
|
} |
|
|
|
void SetMapName( char const *newname ) |
|
{ |
|
Q_strncpy( mapname, newname, sizeof( mapname ) ); |
|
} |
|
|
|
DISPATCHFUNCTION factory; |
|
int size; |
|
private: |
|
char mapname[ 40 ]; |
|
}; |
|
|
|
CUtlDict< classentry_t, unsigned short > m_ClassDict; |
|
}; |
|
|
|
template <class T> |
|
void CGenericClassmap< T >::Add( const char *mapname, const char *classname, int size, DISPATCHFUNCTION factory ) |
|
{ |
|
const char *map = Lookup( classname ); |
|
if ( map && !Q_strcasecmp( mapname, map ) ) |
|
return; |
|
|
|
if ( map ) |
|
{ |
|
int index = m_ClassDict.Find( classname ); |
|
Assert( index != m_ClassDict.InvalidIndex() ); |
|
m_ClassDict.RemoveAt( index ); |
|
} |
|
|
|
classentry_t element; |
|
element.SetMapName( mapname ); |
|
element.factory = factory; |
|
element.size = size; |
|
m_ClassDict.Insert( classname, element ); |
|
} |
|
|
|
template <class T> |
|
const char *CGenericClassmap< T >::Lookup( const char *classname ) |
|
{ |
|
unsigned short index; |
|
static classentry_t lookup; |
|
|
|
index = m_ClassDict.Find( classname ); |
|
if ( index == m_ClassDict.InvalidIndex() ) |
|
return NULL; |
|
|
|
lookup = m_ClassDict.Element( index ); |
|
return lookup.GetMapName(); |
|
} |
|
|
|
template <class T> |
|
T *CGenericClassmap< T >::CreateInstance( const char *mapname ) |
|
{ |
|
int c = m_ClassDict.Count(); |
|
int i; |
|
|
|
for ( i = 0; i < c; i++ ) |
|
{ |
|
classentry_t *lookup = &m_ClassDict[ i ]; |
|
if ( !lookup ) |
|
continue; |
|
|
|
if ( Q_stricmp( lookup->GetMapName(), mapname ) ) |
|
continue; |
|
|
|
if ( !lookup->factory ) |
|
{ |
|
#if defined( _DEBUG ) |
|
Msg( "No factory for %s/%s\n", lookup->GetMapName(), m_ClassDict.GetElementName( i ) ); |
|
#endif |
|
continue; |
|
} |
|
|
|
return ( *lookup->factory )(); |
|
} |
|
|
|
return NULL; |
|
} |
|
|
|
template <class T> |
|
int CGenericClassmap< T >::GetClassSize( const char *classname ) |
|
{ |
|
int c = m_ClassDict.Count(); |
|
int i; |
|
|
|
for ( i = 0; i < c; i++ ) |
|
{ |
|
classentry_t *lookup = &m_ClassDict[ i ]; |
|
if ( !lookup ) |
|
continue; |
|
|
|
if ( Q_strcmp( lookup->GetMapName(), classname ) ) |
|
continue; |
|
|
|
return lookup->size; |
|
} |
|
|
|
return -1; |
|
} |
|
|
|
#if 0 |
|
// example |
|
|
|
// to hold the database: |
|
static CGenericClassmap< CAI_BehaviorBase > m_BehaviorClasses; |
|
|
|
// macro for easy factory creation / use: |
|
#define LINK_BEHAVIOR_TO_CLASS( localName, className ) \ |
|
static CAI_BehaviorBase *C##className##Factory( void ) \ |
|
{ \ |
|
return static_cast< CAI_BehaviorBase * >( new className ); \ |
|
}; \ |
|
class C##localName##Foo \ |
|
{ \ |
|
public: \ |
|
C##localName##Foo( void ) \ |
|
{ \ |
|
CAI_BehaviorBase::m_BehaviorClasses.Add( #localName, #className, \ |
|
sizeof( className ),&C##className##Factory ); \ |
|
} \ |
|
}; \ |
|
static C##localName##Foo g_C##localName##Foo; |
|
|
|
// example of macro use: |
|
LINK_BEHAVIOR_TO_CLASSNAME( CAI_ASW_ScuttleBehavior ); |
|
|
|
#endif |
|
|
|
#endif // ASW_GENERIC_CLASSMAP_H
|
|
|