Team Fortress 2 Source Code as on 22/4/2020
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.

381 lines
17 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #ifndef MESSAGEMAP_H
  8. #define MESSAGEMAP_H
  9. #ifdef _WIN32
  10. #pragma once
  11. #endif
  12. #include "tier1/utlvector.h"
  13. // more flexible than default pointers to members code required for casting member function pointers
  14. //#pragma pointers_to_members( full_generality, virtual_inheritance )
  15. namespace vgui
  16. {
  17. ////////////// MESSAGEMAP DEFINITIONS //////////////
  18. //-----------------------------------------------------------------------------
  19. // Purpose: parameter data type enumeration
  20. // used internal but the shortcut macros require this to be exposed
  21. //-----------------------------------------------------------------------------
  22. enum DataType_t
  23. {
  24. DATATYPE_VOID,
  25. DATATYPE_CONSTCHARPTR,
  26. DATATYPE_INT,
  27. DATATYPE_FLOAT,
  28. DATATYPE_PTR,
  29. DATATYPE_BOOL,
  30. DATATYPE_KEYVALUES,
  31. DATATYPE_CONSTWCHARPTR,
  32. DATATYPE_UINT64,
  33. DATATYPE_HANDLE, // It's an int, really
  34. };
  35. #ifdef WIN32
  36. class __virtual_inheritance Panel;
  37. #else
  38. class Panel;
  39. #endif
  40. typedef unsigned int VPANEL;
  41. typedef void (Panel::*MessageFunc_t)(void);
  42. //-----------------------------------------------------------------------------
  43. // Purpose: Single item in a message map
  44. // Contains the information to map a string message name with parameters
  45. // to a function call
  46. //-----------------------------------------------------------------------------
  47. #pragma warning(disable:4121)
  48. struct MessageMapItem_t
  49. {
  50. const char *name;
  51. // VC6 aligns this to 16-bytes. Since some of the code has been compiled with VC6,
  52. // we need to enforce the alignment on later compilers to remain compatible.
  53. ALIGN16 MessageFunc_t func;
  54. int numParams;
  55. DataType_t firstParamType;
  56. const char *firstParamName;
  57. DataType_t secondParamType;
  58. const char *secondParamName;
  59. int nameSymbol;
  60. int firstParamSymbol;
  61. int secondParamSymbol;
  62. };
  63. #define DECLARE_PANELMESSAGEMAP( className ) \
  64. static void AddToMap( char const *scriptname, vgui::MessageFunc_t function, int paramCount, int p1type, const char *p1name, int p2type, const char *p2name ) \
  65. { \
  66. vgui::PanelMessageMap *map = vgui::FindOrAddPanelMessageMap( GetPanelClassName() ); \
  67. \
  68. vgui::MessageMapItem_t entry; \
  69. entry.name = scriptname; \
  70. entry.func = function; \
  71. entry.numParams = paramCount; \
  72. entry.firstParamType = (vgui::DataType_t)p1type; \
  73. entry.firstParamName = p1name; \
  74. entry.secondParamType = (vgui::DataType_t)p2type; \
  75. entry.secondParamName = p2name; \
  76. entry.nameSymbol = 0; \
  77. entry.firstParamSymbol = 0; \
  78. entry.secondParamSymbol = 0; \
  79. \
  80. map->entries.AddToTail( entry ); \
  81. } \
  82. \
  83. static void ChainToMap( void ) \
  84. { \
  85. static bool chained = false; \
  86. if ( chained ) \
  87. return; \
  88. chained = true; \
  89. vgui::PanelMessageMap *map = vgui::FindOrAddPanelMessageMap( GetPanelClassName() ); \
  90. map->pfnClassName = &GetPanelClassName; \
  91. if ( map && GetPanelBaseClassName() && GetPanelBaseClassName()[0] ) \
  92. { \
  93. map->baseMap = vgui::FindOrAddPanelMessageMap( GetPanelBaseClassName() ); \
  94. } \
  95. } \
  96. \
  97. class className##_RegisterMap; \
  98. friend class className##_RegisterMap; \
  99. class className##_RegisterMap \
  100. { \
  101. public: \
  102. className##_RegisterMap() \
  103. { \
  104. className::ChainToMap(); \
  105. } \
  106. }; \
  107. className##_RegisterMap m_RegisterClass; \
  108. \
  109. virtual vgui::PanelMessageMap *GetMessageMap() \
  110. { \
  111. static vgui::PanelMessageMap *s_pMap = vgui::FindOrAddPanelMessageMap( GetPanelClassName() ); \
  112. return s_pMap; \
  113. }
  114. #if !defined( _XBOX )
  115. #define VGUI_USEKEYBINDINGMAPS 1
  116. #endif
  117. #if defined( VGUI_USEKEYBINDINGMAPS )
  118. #define DECLARE_CLASS_SIMPLE( className, baseClassName ) \
  119. typedef baseClassName BaseClass; \
  120. typedef className ThisClass; \
  121. public: \
  122. DECLARE_PANELMESSAGEMAP( className ); \
  123. DECLARE_PANELANIMATION( className ); \
  124. DECLARE_KEYBINDINGMAP( className ); \
  125. static char const *GetPanelClassName() { return #className; } \
  126. static char const *GetPanelBaseClassName() { return #baseClassName; }
  127. #define DECLARE_CLASS_SIMPLE_NOBASE( className ) \
  128. typedef className ThisClass; \
  129. public: \
  130. DECLARE_PANELMESSAGEMAP( className ); \
  131. DECLARE_PANELANIMATION( className ); \
  132. DECLARE_KEYBINDINGMAP( className ); \
  133. static char const *GetPanelClassName() { return #className; } \
  134. static char const *GetPanelBaseClassName() { return NULL; }
  135. #else // no keybinding maps
  136. #define DECLARE_CLASS_SIMPLE( className, baseClassName ) \
  137. typedef baseClassName BaseClass; \
  138. typedef className ThisClass; \
  139. public: \
  140. DECLARE_PANELMESSAGEMAP( className ); \
  141. DECLARE_PANELANIMATION( className ); \
  142. static char const *GetPanelClassName() { return #className; } \
  143. static char const *GetPanelBaseClassName() { return #baseClassName; }
  144. #define DECLARE_CLASS_SIMPLE_NOBASE( className ) \
  145. typedef className ThisClass; \
  146. public: \
  147. DECLARE_PANELMESSAGEMAP( className ); \
  148. DECLARE_PANELANIMATION( className ); \
  149. static char const *GetPanelClassName() { return #className; } \
  150. static char const *GetPanelBaseClassName() { return NULL; }
  151. #endif // !VGUI_USEKEYBINDINGMAPS
  152. #define _MessageFuncCommon( name, scriptname, paramCount, p1type, p1name, p2type, p2name ) \
  153. class PanelMessageFunc_##name; \
  154. friend class PanelMessageFunc_##name; \
  155. class PanelMessageFunc_##name \
  156. { \
  157. public: \
  158. static void InitVar() \
  159. { \
  160. static bool bAdded = false; \
  161. if ( !bAdded ) \
  162. { \
  163. bAdded = true; \
  164. AddToMap( scriptname, (vgui::MessageFunc_t)&ThisClass::name, paramCount, p1type, p1name, p2type, p2name ); \
  165. } \
  166. } \
  167. PanelMessageFunc_##name() \
  168. { \
  169. PanelMessageFunc_##name::InitVar(); \
  170. } \
  171. }; \
  172. PanelMessageFunc_##name m_##name##_register; \
  173. // Use this macro to define a message mapped function
  174. // must end with a semicolon ';', or with a function
  175. // no parameter
  176. #define MESSAGE_FUNC( name, scriptname ) _MessageFuncCommon( name, scriptname, 0, 0, 0, 0, 0 ); virtual void name( void )
  177. // one parameter
  178. #define MESSAGE_FUNC_INT( name, scriptname, p1 ) _MessageFuncCommon( name, scriptname, 1, vgui::DATATYPE_INT, #p1, 0, 0 ); virtual void name( int p1 )
  179. #define MESSAGE_FUNC_UINT64( name, scriptname, p1 ) _MessageFuncCommon( name, scriptname, 1, vgui::DATATYPE_UINT64, #p1, 0, 0 ); virtual void name( uint64 p1 )
  180. #define MESSAGE_FUNC_PTR( name, scriptname, p1 ) _MessageFuncCommon( name, scriptname, 1, vgui::DATATYPE_PTR, #p1, 0, 0 ); virtual void name( vgui::Panel *p1 )
  181. #define MESSAGE_FUNC_HANDLE( name, scriptname, p1 ) _MessageFuncCommon( name, scriptname, 1, vgui::DATATYPE_HANDLE, #p1, 0, 0 ); virtual void name( vgui::VPANEL p1 )
  182. #define MESSAGE_FUNC_ENUM( name, scriptname, t1, p1 ) _MessageFuncCommon( name, scriptname, 1, vgui::DATATYPE_INT, #p1, 0, 0 ); virtual void name( t1 p1 )
  183. #define MESSAGE_FUNC_FLOAT( name, scriptname, p1 ) _MessageFuncCommon( name, scriptname, 1, vgui::DATATYPE_FLOAT, #p1, 0, 0 ); virtual void name( float p1 )
  184. #define MESSAGE_FUNC_CHARPTR( name, scriptname, p1 ) _MessageFuncCommon( name, scriptname, 1, vgui::DATATYPE_CONSTCHARPTR, #p1, 0, 0 ); virtual void name( const char *p1 )
  185. #define MESSAGE_FUNC_WCHARPTR( name, scriptname, p1 ) _MessageFuncCommon( name, scriptname, 1, vgui::DATATYPE_CONSTWCHARPTR, #p1, 0, 0 ); virtual void name( const wchar_t *p1 )
  186. // two parameters
  187. #define MESSAGE_FUNC_INT_INT( name, scriptname, p1, p2 ) _MessageFuncCommon( name, scriptname, 2, vgui::DATATYPE_INT, #p1, vgui::DATATYPE_INT, #p2 ); virtual void name( int p1, int p2 )
  188. #define MESSAGE_FUNC_PTR_INT( name, scriptname, p1, p2 ) _MessageFuncCommon( name, scriptname, 2, vgui::DATATYPE_PTR, #p1, vgui::DATATYPE_INT, #p2 ); virtual void name( vgui::Panel *p1, int p2 )
  189. #define MESSAGE_FUNC_HANDLE_INT( name, scriptname, p1, p2 ) _MessageFuncCommon( name, scriptname, 2, vgui::DATATYPE_HANDLE, #p1, vgui::DATATYPE_INT, #p2 ); virtual void name( vgui::VPANEL p1, int p2 )
  190. #define MESSAGE_FUNC_ENUM_ENUM( name, scriptname, t1, p1, t2, p2 ) _MessageFuncCommon( name, scriptname, 2, vgui::DATATYPE_INT, #p1, vgui::DATATYPE_INT, #p2 ); virtual void name( t1 p1, t2 p2 )
  191. #define MESSAGE_FUNC_INT_CHARPTR( name, scriptname, p1, p2 ) _MessageFuncCommon( name, scriptname, 2, vgui::DATATYPE_INT, #p1, vgui::DATATYPE_CONSTCHARPTR, #p2 ); virtual void name( int p1, const char *p2 )
  192. #define MESSAGE_FUNC_PTR_CHARPTR( name, scriptname, p1, p2 ) _MessageFuncCommon( name, scriptname, 2, vgui::DATATYPE_PTR, #p1, vgui::DATATYPE_CONSTCHARPTR, #p2 ); virtual void name( vgui::Panel *p1, const char *p2 )
  193. #define MESSAGE_FUNC_HANDLE_CHARPTR( name, scriptname, p1, p2 ) _MessageFuncCommon( name, scriptname, 2, vgui::DATATYPE_HANDLE, #p1, vgui::DATATYPE_CONSTCHARPTR, #p2 ); virtual void name( vgui::VPANEL p1, const char *p2 )
  194. #define MESSAGE_FUNC_PTR_WCHARPTR( name, scriptname, p1, p2 ) _MessageFuncCommon( name, scriptname, 2, vgui::DATATYPE_PTR, #p1, vgui::DATATYPE_CONSTWCHARPTR, #p2 ); virtual void name( vgui::Panel *p1, const wchar_t *p2 )
  195. #define MESSAGE_FUNC_HANDLE_WCHARPTR( name, scriptname, p1, p2 ) _MessageFuncCommon( name, scriptname, 2, vgui::DATATYPE_HANDLE, #p1, vgui::DATATYPE_CONSTWCHARPTR, #p2 ); virtual void name( vgui::VPANEL p1, const wchar_t *p2 )
  196. #define MESSAGE_FUNC_CHARPTR_CHARPTR( name, scriptname, p1, p2 ) _MessageFuncCommon( name, scriptname, 2, vgui::DATATYPE_CONSTCHARPTR, #p1, vgui::DATATYPE_CONSTCHARPTR, #p2 ); virtual void name( const char *p1, const char *p2 )
  197. // unlimited parameters (passed in the whole KeyValues)
  198. #define MESSAGE_FUNC_PARAMS( name, scriptname, p1 ) _MessageFuncCommon( name, scriptname, 1, vgui::DATATYPE_KEYVALUES, NULL, 0, 0 ); virtual void name( KeyValues *p1 )
  199. // no-virtual function version
  200. #define MESSAGE_FUNC_NV( name, scriptname ) _MessageFuncCommon( name, scriptname, 0, 0, 0, 0, 0 ); void name( void )
  201. #define MESSAGE_FUNC_NV_INT( name, scriptname, p1 ) _MessageFuncCommon( name, scriptname, 1, vgui::DATATYPE_INT, #p1, 0, 0 ); void name( int p1 )
  202. #define MESSAGE_FUNC_NV_INT_INT( name, scriptname, p1, p2 ) _MessageFuncCommon( name, scriptname, 2, vgui::DATATYPE_INT, #p1, vgui::DATATYPE_INT, #p2 ); void name( int p1, int p2 )
  203. // mapping, one per class
  204. struct PanelMessageMap
  205. {
  206. PanelMessageMap()
  207. {
  208. baseMap = NULL;
  209. pfnClassName = NULL;
  210. processed = false;
  211. }
  212. CUtlVector< MessageMapItem_t > entries;
  213. bool processed;
  214. PanelMessageMap *baseMap;
  215. char const *(*pfnClassName)( void );
  216. };
  217. PanelMessageMap *FindPanelMessageMap( char const *className );
  218. PanelMessageMap *FindOrAddPanelMessageMap( char const *className );
  219. ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  220. //
  221. // OBSELETE MAPPING FUNCTIONS, USE ABOVE
  222. //
  223. ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  224. // no parameters
  225. #define MAP_MESSAGE( type, name, func ) { name, (vgui::MessageFunc_t)(&type::func), 0 }
  226. // implicit single parameter (params is the data store)
  227. #define MAP_MESSAGE_PARAMS( type, name, func ) { name, (vgui::MessageFunc_t)(&type::func), 1, vgui::DATATYPE_KEYVALUES, NULL }
  228. // single parameter
  229. #define MAP_MESSAGE_PTR( type, name, func, param1 ) { name, (vgui::MessageFunc_t)(&type::func), 1, vgui::DATATYPE_PTR, param1 }
  230. #define MAP_MESSAGE_INT( type, name, func, param1 ) { name, (vgui::MessageFunc_t)(&type::func), 1, vgui::DATATYPE_INT, param1 }
  231. #define MAP_MESSAGE_BOOL( type, name, func, param1 ) { name, (vgui::MessageFunc_t)(&type::func), 1, vgui::DATATYPE_BOOL, param1 }
  232. #define MAP_MESSAGE_FLOAT( type, name, func, param1 ) { name, (vgui::MessageFunc_t)(&type::func), 1, vgui::DATATYPE_FLOAT, param1 }
  233. #define MAP_MESSAGE_PTR( type, name, func, param1 ) { name, (vgui::MessageFunc_t)(&type::func), 1, vgui::DATATYPE_PTR, param1 }
  234. #define MAP_MESSAGE_CONSTCHARPTR( type, name, func, param1) { name, (vgui::MessageFunc_t)(&type::func), 1, vgui::DATATYPE_CONSTCHARPTR, param1 }
  235. #define MAP_MESSAGE_CONSTWCHARPTR( type, name, func, param1) { name, (vgui::MessageFunc_t)(&type::func), 1, vgui::DATATYPE_CONSTWCHARPTR, param1 }
  236. // two parameters
  237. #define MAP_MESSAGE_INT_INT( type, name, func, param1, param2 ) { name, (vgui::MessageFunc_t)&type::func, 2, vgui::DATATYPE_INT, param1, vgui::DATATYPE_INT, param2 }
  238. #define MAP_MESSAGE_PTR_INT( type, name, func, param1, param2 ) { name, (vgui::MessageFunc_t)&type::func, 2, vgui::DATATYPE_PTR, param1, vgui::DATATYPE_INT, param2 }
  239. #define MAP_MESSAGE_INT_CONSTCHARPTR( type, name, func, param1, param2 ) { name, (vgui::MessageFunc_t)&type::func, 2, vgui::DATATYPE_INT, param1, vgui::DATATYPE_CONSTCHARPTR, param2 }
  240. #define MAP_MESSAGE_PTR_CONSTCHARPTR( type, name, func, param1, param2 ) { name, (vgui::MessageFunc_t)&type::func, 2, vgui::DATATYPE_PTR, param1, vgui::DATATYPE_CONSTCHARPTR, param2 }
  241. #define MAP_MESSAGE_PTR_CONSTWCHARPTR( type, name, func, param1, param2 ) { name, (vgui::MessageFunc_t)&type::func, 2, vgui::DATATYPE_PTR, param1, vgui::DATATYPE_CONSTWCHARPTR, param2 }
  242. #define MAP_MESSAGE_CONSTCHARPTR_CONSTCHARPTR( type, name, func, param1, param2 ) { name, (vgui::MessageFunc_t)&type::func, 2, vgui::DATATYPE_CONSTCHARPTR, param1, vgui::DATATYPE_CONSTCHARPTR, param2 }
  243. // if more parameters are needed, just use MAP_MESSAGE_PARAMS() and pass the keyvalue set into the function
  244. //-----------------------------------------------------------------------------
  245. // Purpose: stores the list of objects in the hierarchy
  246. // used to iterate through an object's message maps
  247. //-----------------------------------------------------------------------------
  248. struct PanelMap_t
  249. {
  250. MessageMapItem_t *dataDesc;
  251. int dataNumFields;
  252. const char *dataClassName;
  253. PanelMap_t *baseMap;
  254. int processed;
  255. };
  256. // for use in class declarations
  257. // declares the static variables and functions needed for the data description iteration
  258. #define DECLARE_PANELMAP() \
  259. static vgui::PanelMap_t m_PanelMap; \
  260. static vgui::MessageMapItem_t m_MessageMap[]; \
  261. virtual vgui::PanelMap_t *GetPanelMap( void );
  262. // could embed typeid() into here as well?
  263. #define IMPLEMENT_PANELMAP( derivedClass, baseClass ) \
  264. vgui::PanelMap_t derivedClass::m_PanelMap = { derivedClass::m_MessageMap, ARRAYSIZE(derivedClass::m_MessageMap), #derivedClass, &baseClass::m_PanelMap }; \
  265. vgui::PanelMap_t *derivedClass::GetPanelMap( void ) { return &m_PanelMap; }
  266. typedef vgui::Panel *( *PANELCREATEFUNC )( void );
  267. //-----------------------------------------------------------------------------
  268. // Purpose: Used by DECLARE_BUILD_FACTORY macro to create a linked list of
  269. // instancing functions
  270. //-----------------------------------------------------------------------------
  271. class CBuildFactoryHelper
  272. {
  273. public:
  274. // Static list of helpers
  275. static CBuildFactoryHelper *m_sHelpers;
  276. public:
  277. // Construction
  278. CBuildFactoryHelper( char const *className, PANELCREATEFUNC func );
  279. // Accessors
  280. CBuildFactoryHelper *GetNext( void );
  281. char const *GetClassName() const;
  282. vgui::Panel *CreatePanel();
  283. static vgui::Panel *InstancePanel( char const *className );
  284. static void GetFactoryNames( CUtlVector< char const * >& list );
  285. private:
  286. static bool HasFactory( char const *className );
  287. // Next factory in list
  288. CBuildFactoryHelper *m_pNext;
  289. int m_Type;
  290. PANELCREATEFUNC m_CreateFunc;
  291. char const *m_pClassName;
  292. };
  293. // This is the macro which implements creation of each type of panel
  294. // It creates a function which instances an object of the specified type
  295. // It them hooks that function up to the helper list so that the CHud objects can create
  296. // the elements by name, with no header file dependency, etc.
  297. #define DECLARE_BUILD_FACTORY( className ) \
  298. static vgui::Panel *Create_##className( void ) \
  299. { \
  300. return new className( NULL, NULL ); \
  301. }; \
  302. static vgui::CBuildFactoryHelper g_##className##_Helper( #className, Create_##className );\
  303. className *g_##className##LinkerHack = NULL;
  304. #define DECLARE_BUILD_FACTORY_DEFAULT_TEXT( className, defaultText ) \
  305. static vgui::Panel *Create_##className( void ) \
  306. { \
  307. return new className( NULL, NULL, #defaultText ); \
  308. }; \
  309. static vgui::CBuildFactoryHelper g_##className##_Helper( #className, Create_##className );\
  310. className *g_##className##LinkerHack = NULL;
  311. // This one allows passing in a special function with calls new panel( xxx ) with arbitrary default parameters
  312. #define DECLARE_BUILD_FACTORY_CUSTOM( className, createFunc ) \
  313. static vgui::CBuildFactoryHelper g_##className##_Helper( #className, createFunc );\
  314. className *g_##className##LinkerHack = NULL;
  315. #define DECLARE_BUILD_FACTORY_CUSTOM_ALIAS( className, factoryName, createFunc ) \
  316. static vgui::CBuildFactoryHelper g_##factoryName##_Helper( #factoryName, createFunc );\
  317. className *g_##factoryName##LinkerHack = NULL;
  318. } // namespace vgui
  319. #endif // MESSAGEMAP_H