Counter Strike : Global Offensive Source Code
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

  1. //========= Copyright � 1996-2009, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #ifndef ASW_GENERIC_CLASSMAP_H
  8. #define ASW_GENERIC_CLASSMAP_H
  9. #ifdef _WIN32
  10. #pragma once
  11. #endif
  12. template <class T>
  13. class CGenericClassmap
  14. {
  15. public:
  16. typedef T *( *DISPATCHFUNCTION )( void );
  17. CGenericClassmap() { }
  18. ~CGenericClassmap() { }
  19. void Add( const char *mapname, const char *classname, int size, DISPATCHFUNCTION factory = 0 );
  20. char const *Lookup( const char *classname );
  21. T *CreateInstance( const char *mapname );
  22. int GetClassSize( const char *classname );
  23. private:
  24. class classentry_t
  25. {
  26. public:
  27. classentry_t()
  28. {
  29. mapname[ 0 ] = 0;
  30. factory = 0;
  31. size = -1;
  32. }
  33. char const *GetMapName() const
  34. {
  35. return mapname;
  36. }
  37. void SetMapName( char const *newname )
  38. {
  39. Q_strncpy( mapname, newname, sizeof( mapname ) );
  40. }
  41. DISPATCHFUNCTION factory;
  42. int size;
  43. private:
  44. char mapname[ 40 ];
  45. };
  46. CUtlDict< classentry_t, unsigned short > m_ClassDict;
  47. };
  48. template <class T>
  49. void CGenericClassmap< T >::Add( const char *mapname, const char *classname, int size, DISPATCHFUNCTION factory )
  50. {
  51. const char *map = Lookup( classname );
  52. if ( map && !Q_strcasecmp( mapname, map ) )
  53. return;
  54. if ( map )
  55. {
  56. int index = m_ClassDict.Find( classname );
  57. Assert( index != m_ClassDict.InvalidIndex() );
  58. m_ClassDict.RemoveAt( index );
  59. }
  60. classentry_t element;
  61. element.SetMapName( mapname );
  62. element.factory = factory;
  63. element.size = size;
  64. m_ClassDict.Insert( classname, element );
  65. }
  66. template <class T>
  67. const char *CGenericClassmap< T >::Lookup( const char *classname )
  68. {
  69. unsigned short index;
  70. static classentry_t lookup;
  71. index = m_ClassDict.Find( classname );
  72. if ( index == m_ClassDict.InvalidIndex() )
  73. return NULL;
  74. lookup = m_ClassDict.Element( index );
  75. return lookup.GetMapName();
  76. }
  77. template <class T>
  78. T *CGenericClassmap< T >::CreateInstance( const char *mapname )
  79. {
  80. int c = m_ClassDict.Count();
  81. int i;
  82. for ( i = 0; i < c; i++ )
  83. {
  84. classentry_t *lookup = &m_ClassDict[ i ];
  85. if ( !lookup )
  86. continue;
  87. if ( Q_stricmp( lookup->GetMapName(), mapname ) )
  88. continue;
  89. if ( !lookup->factory )
  90. {
  91. #if defined( _DEBUG )
  92. Msg( "No factory for %s/%s\n", lookup->GetMapName(), m_ClassDict.GetElementName( i ) );
  93. #endif
  94. continue;
  95. }
  96. return ( *lookup->factory )();
  97. }
  98. return NULL;
  99. }
  100. template <class T>
  101. int CGenericClassmap< T >::GetClassSize( const char *classname )
  102. {
  103. int c = m_ClassDict.Count();
  104. int i;
  105. for ( i = 0; i < c; i++ )
  106. {
  107. classentry_t *lookup = &m_ClassDict[ i ];
  108. if ( !lookup )
  109. continue;
  110. if ( Q_strcmp( lookup->GetMapName(), classname ) )
  111. continue;
  112. return lookup->size;
  113. }
  114. return -1;
  115. }
  116. #if 0
  117. // example
  118. // to hold the database:
  119. static CGenericClassmap< CAI_BehaviorBase > m_BehaviorClasses;
  120. // macro for easy factory creation / use:
  121. #define LINK_BEHAVIOR_TO_CLASS( localName, className ) \
  122. static CAI_BehaviorBase *C##className##Factory( void ) \
  123. { \
  124. return static_cast< CAI_BehaviorBase * >( new className ); \
  125. }; \
  126. class C##localName##Foo \
  127. { \
  128. public: \
  129. C##localName##Foo( void ) \
  130. { \
  131. CAI_BehaviorBase::m_BehaviorClasses.Add( #localName, #className, \
  132. sizeof( className ),&C##className##Factory ); \
  133. } \
  134. }; \
  135. static C##localName##Foo g_C##localName##Foo;
  136. // example of macro use:
  137. LINK_BEHAVIOR_TO_CLASSNAME( CAI_ASW_ScuttleBehavior );
  138. #endif
  139. #endif // ASW_GENERIC_CLASSMAP_H