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.

390 lines
17 KiB

  1. //========= Copyright 1996-2005, 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. #include "dmxloader/dmxelement.h"
  14. // more flexible than default pointers to members code required for casting member function pointers
  15. #pragma pointers_to_members( full_generality, virtual_inheritance )
  16. namespace vgui
  17. {
  18. ////////////// MESSAGEMAP DEFINITIONS //////////////
  19. #ifndef ARRAYSIZE
  20. #define ARRAYSIZE(p) (sizeof(p)/sizeof(p[0]))
  21. #endif
  22. //-----------------------------------------------------------------------------
  23. // Purpose: parameter data type enumeration
  24. // used internal but the shortcut macros require this to be exposed
  25. //-----------------------------------------------------------------------------
  26. enum DataType_t
  27. {
  28. DATATYPE_VOID,
  29. DATATYPE_CONSTCHARPTR,
  30. DATATYPE_INT,
  31. DATATYPE_FLOAT,
  32. DATATYPE_PTR,
  33. DATATYPE_BOOL,
  34. DATATYPE_KEYVALUES,
  35. DATATYPE_CONSTWCHARPTR,
  36. DATATYPE_UINT64,
  37. DATATYPE_HANDLE, // It's an int, really
  38. };
  39. class Panel;
  40. typedef uintp 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. #define VGUI_USEKEYBINDINGMAPS 1
  115. #if defined( VGUI_USEKEYBINDINGMAPS )
  116. #define DECLARE_CLASS_SIMPLE( className, baseClassName ) \
  117. typedef baseClassName BaseClass; \
  118. typedef className ThisClass; \
  119. public: \
  120. DECLARE_PANELMESSAGEMAP( className ); \
  121. DECLARE_PANELANIMATION( className ); \
  122. DECLARE_KEYBINDINGMAP( className ); \
  123. static char const *GetPanelClassName() { return #className; } \
  124. static char const *GetPanelBaseClassName() { return #baseClassName; }
  125. #define DECLARE_CLASS_SIMPLE_NOBASE( className ) \
  126. typedef className ThisClass; \
  127. public: \
  128. DECLARE_PANELMESSAGEMAP( className ); \
  129. DECLARE_PANELANIMATION( className ); \
  130. DECLARE_KEYBINDINGMAP( className ); \
  131. static char const *GetPanelClassName() { return #className; } \
  132. static char const *GetPanelBaseClassName() { return NULL; }
  133. #else // no keybinding maps
  134. #define DECLARE_CLASS_SIMPLE( className, baseClassName ) \
  135. typedef baseClassName BaseClass; \
  136. typedef className ThisClass; \
  137. public: \
  138. DECLARE_PANELMESSAGEMAP( className ); \
  139. DECLARE_PANELANIMATION( className ); \
  140. static char const *GetPanelClassName() { return #className; } \
  141. static char const *GetPanelBaseClassName() { return #baseClassName; }
  142. #define DECLARE_CLASS_SIMPLE_NOBASE( className ) \
  143. typedef className ThisClass; \
  144. public: \
  145. DECLARE_PANELMESSAGEMAP( className ); \
  146. DECLARE_PANELANIMATION( className ); \
  147. static char const *GetPanelClassName() { return #className; } \
  148. static char const *GetPanelBaseClassName() { return NULL; }
  149. #endif // !VGUI_USEKEYBINDINGMAPS
  150. #define _MessageFuncCommon( name, scriptname, paramCount, p1type, p1name, p2type, p2name ) \
  151. class PanelMessageFunc_##name; \
  152. friend class PanelMessageFunc_##name; \
  153. class PanelMessageFunc_##name \
  154. { \
  155. public: \
  156. static void InitVar() \
  157. { \
  158. static bool bAdded = false; \
  159. if ( !bAdded ) \
  160. { \
  161. bAdded = true; \
  162. AddToMap( scriptname, (vgui::MessageFunc_t)&ThisClass::name, paramCount, p1type, p1name, p2type, p2name ); \
  163. } \
  164. } \
  165. PanelMessageFunc_##name() \
  166. { \
  167. PanelMessageFunc_##name::InitVar(); \
  168. } \
  169. }; \
  170. PanelMessageFunc_##name m_##name##_register; \
  171. // Use this macro to define a message mapped function
  172. // must end with a semicolon ';', or with a function
  173. // no parameter
  174. #define MESSAGE_FUNC( name, scriptname ) _MessageFuncCommon( name, scriptname, 0, 0, 0, 0, 0 ); virtual void name( void )
  175. // one parameter
  176. #define MESSAGE_FUNC_INT( name, scriptname, p1 ) _MessageFuncCommon( name, scriptname, 1, vgui::DATATYPE_INT, #p1, 0, 0 ); virtual void name( int p1 )
  177. #define MESSAGE_FUNC_UINT64( name, scriptname, p1 ) _MessageFuncCommon( name, scriptname, 1, vgui::DATATYPE_UINT64, #p1, 0, 0 ); virtual void name( uint64 p1 )
  178. #define MESSAGE_FUNC_PTR( name, scriptname, p1 ) _MessageFuncCommon( name, scriptname, 1, vgui::DATATYPE_PTR, #p1, 0, 0 ); virtual void name( vgui::Panel *p1 )
  179. #define MESSAGE_FUNC_HANDLE( name, scriptname, p1 ) _MessageFuncCommon( name, scriptname, 1, vgui::DATATYPE_HANDLE, #p1, 0, 0 ); virtual void name( vgui::VPANEL p1 )
  180. #define MESSAGE_FUNC_FLOAT( name, scriptname, p1 ) _MessageFuncCommon( name, scriptname, 1, vgui::DATATYPE_FLOAT, #p1, 0, 0 ); virtual void name( float p1 )
  181. #define MESSAGE_FUNC_CHARPTR( name, scriptname, p1 ) _MessageFuncCommon( name, scriptname, 1, vgui::DATATYPE_CONSTCHARPTR, #p1, 0, 0 ); virtual void name( const char *p1 )
  182. #define MESSAGE_FUNC_WCHARPTR( name, scriptname, p1 ) _MessageFuncCommon( name, scriptname, 1, vgui::DATATYPE_CONSTWCHARPTR, #p1, 0, 0 ); virtual void name( const wchar_t *p1 )
  183. // two parameters
  184. #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 )
  185. #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 )
  186. #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 )
  187. #define MESSAGE_FUNC_ENUM_ENUM( name, scriptname, t1, p1, t2, p2 ) _MessageFuncCommon( name, scriptname, 2, vgui::DATATYPE_PTR, #p1, vgui::DATATYPE_PTR, #p2 ); virtual void name( t1 p1, t2 p2 )
  188. #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 )
  189. #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 )
  190. #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 )
  191. #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 )
  192. #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 )
  193. #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 )
  194. // unlimited parameters (passed in the whole KeyValues)
  195. #define MESSAGE_FUNC_PARAMS( name, scriptname, p1 ) _MessageFuncCommon( name, scriptname, 1, vgui::DATATYPE_KEYVALUES, NULL, 0, 0 ); virtual void name( KeyValues *p1 )
  196. // no-virtual function version
  197. #define MESSAGE_FUNC_NV( name, scriptname ) _MessageFuncCommon( name, scriptname, 0, 0, 0, 0, 0 ); void name( void )
  198. #define MESSAGE_FUNC_NV_INT( name, scriptname, p1 ) _MessageFuncCommon( name, scriptname, 1, vgui::DATATYPE_INT, #p1, 0, 0 ); void name( int p1 )
  199. #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 )
  200. // mapping, one per class
  201. struct PanelMessageMap
  202. {
  203. PanelMessageMap()
  204. {
  205. baseMap = NULL;
  206. pfnClassName = NULL;
  207. processed = false;
  208. }
  209. CUtlVector< MessageMapItem_t > entries;
  210. bool processed;
  211. PanelMessageMap *baseMap;
  212. char const *(*pfnClassName)( void );
  213. };
  214. PanelMessageMap *FindPanelMessageMap( char const *className );
  215. PanelMessageMap *FindOrAddPanelMessageMap( char const *className );
  216. ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  217. //
  218. // OBSELETE MAPPING FUNCTIONS, USE ABOVE
  219. //
  220. ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  221. // no parameters
  222. #define MAP_MESSAGE( type, name, func ) { name, (vgui::MessageFunc_t)(&type::func), 0 }
  223. // implicit single parameter (params is the data store)
  224. #define MAP_MESSAGE_PARAMS( type, name, func ) { name, (vgui::MessageFunc_t)(&type::func), 1, vgui::DATATYPE_KEYVALUES, NULL }
  225. // single parameter
  226. #define MAP_MESSAGE_PTR( type, name, func, param1 ) { name, (vgui::MessageFunc_t)(&type::func), 1, vgui::DATATYPE_PTR, param1 }
  227. #define MAP_MESSAGE_INT( type, name, func, param1 ) { name, (vgui::MessageFunc_t)(&type::func), 1, vgui::DATATYPE_INT, param1 }
  228. #define MAP_MESSAGE_BOOL( type, name, func, param1 ) { name, (vgui::MessageFunc_t)(&type::func), 1, vgui::DATATYPE_BOOL, param1 }
  229. #define MAP_MESSAGE_FLOAT( type, name, func, param1 ) { name, (vgui::MessageFunc_t)(&type::func), 1, vgui::DATATYPE_FLOAT, param1 }
  230. #define MAP_MESSAGE_PTR( type, name, func, param1 ) { name, (vgui::MessageFunc_t)(&type::func), 1, vgui::DATATYPE_PTR, param1 }
  231. #define MAP_MESSAGE_CONSTCHARPTR( type, name, func, param1) { name, (vgui::MessageFunc_t)(&type::func), 1, vgui::DATATYPE_CONSTCHARPTR, param1 }
  232. #define MAP_MESSAGE_CONSTWCHARPTR( type, name, func, param1) { name, (vgui::MessageFunc_t)(&type::func), 1, vgui::DATATYPE_CONSTWCHARPTR, param1 }
  233. // two parameters
  234. #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 }
  235. #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 }
  236. #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 }
  237. #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 }
  238. #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 }
  239. #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 }
  240. // if more parameters are needed, just use MAP_MESSAGE_PARAMS() and pass the keyvalue set into the function
  241. //-----------------------------------------------------------------------------
  242. // Purpose: stores the list of objects in the hierarchy
  243. // used to iterate through an object's message maps
  244. //-----------------------------------------------------------------------------
  245. struct PanelMap_t
  246. {
  247. MessageMapItem_t *dataDesc;
  248. int dataNumFields;
  249. const char *dataClassName;
  250. PanelMap_t *baseMap;
  251. int processed;
  252. };
  253. // for use in class declarations
  254. // declares the static variables and functions needed for the data description iteration
  255. #define DECLARE_PANELMAP() \
  256. static vgui::PanelMap_t m_PanelMap; \
  257. static vgui::MessageMapItem_t m_MessageMap[]; \
  258. virtual vgui::PanelMap_t *GetPanelMap( void );
  259. // could embed typeid() into here as well?
  260. #define IMPLEMENT_PANELMAP( derivedClass, baseClass ) \
  261. vgui::PanelMap_t derivedClass::m_PanelMap = { derivedClass::m_MessageMap, ARRAYSIZE(derivedClass::m_MessageMap), #derivedClass, &baseClass::m_PanelMap }; \
  262. vgui::PanelMap_t *derivedClass::GetPanelMap( void ) { return &m_PanelMap; }
  263. typedef vgui::Panel *( *PANELCREATEFUNC )( void );
  264. //-----------------------------------------------------------------------------
  265. // Purpose: Used by DECLARE_BUILD_FACTORY macro to create a linked list of
  266. // instancing functions
  267. //-----------------------------------------------------------------------------
  268. class CBuildFactoryHelper
  269. {
  270. public:
  271. // Static list of helpers
  272. static CBuildFactoryHelper *m_sHelpers;
  273. public:
  274. // Construction
  275. CBuildFactoryHelper( char const *className, PANELCREATEFUNC func );
  276. // Accessors
  277. CBuildFactoryHelper *GetNext( void );
  278. char const *GetClassName() const;
  279. vgui::Panel *CreatePanel();
  280. static vgui::Panel *InstancePanel( char const *className );
  281. static void GetFactoryNames( CUtlVector< char const * >& list );
  282. static CDmxElement *CreatePanelDmxElement( vgui::Panel *pPanel );
  283. static Panel* UnserializeDmxElementPanel( CDmxElement *pElement );
  284. // DMX serializer fxns
  285. static bool Serialize( CUtlBuffer &buf, vgui::Panel *pPanel );
  286. static bool Unserialize( Panel **ppPanel, CUtlBuffer &buf, const char *pFileName = NULL );
  287. private:
  288. static bool HasFactory( char const *className );
  289. // Next factory in list
  290. CBuildFactoryHelper *m_pNext;
  291. int m_Type;
  292. PANELCREATEFUNC m_CreateFunc;
  293. char const *m_pClassName;
  294. };
  295. // This is the macro which implements creation of each type of panel
  296. // It creates a function which instances an object of the specified type
  297. // It them hooks that function up to the helper list so that the CHud objects can create
  298. // the elements by name, with no header file dependency, etc.
  299. #define DECLARE_BUILD_FACTORY( className ) \
  300. static vgui::Panel *Create_##className( void ) \
  301. { \
  302. return new className( NULL, NULL ); \
  303. }; \
  304. static vgui::CBuildFactoryHelper g_##className##_Helper( #className, Create_##className );\
  305. className *g_##className##LinkerHack = NULL;
  306. #define DECLARE_BUILD_FACTORY_DEFAULT_TEXT( className, defaultText ) \
  307. static vgui::Panel *Create_##className( void ) \
  308. { \
  309. return new className( NULL, NULL, #defaultText ); \
  310. }; \
  311. static vgui::CBuildFactoryHelper g_##className##_Helper( #className, Create_##className );\
  312. className *g_##className##LinkerHack = NULL;
  313. // This one allows passing in a special function with calls new panel( xxx ) with arbitrary default parameters
  314. #define DECLARE_BUILD_FACTORY_CUSTOM( className, createFunc ) \
  315. static vgui::CBuildFactoryHelper g_##className##_Helper( #className, createFunc );\
  316. className *g_##className##LinkerHack = NULL;
  317. #define DECLARE_BUILD_FACTORY_CUSTOM_ALIAS( className, factoryName, createFunc ) \
  318. static vgui::CBuildFactoryHelper g_##factoryName##_Helper( #factoryName, createFunc );\
  319. className *g_##factoryName##LinkerHack = NULL;
  320. } // namespace vgui
  321. #endif // MESSAGEMAP_H