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.
382 lines
17 KiB
382 lines
17 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
// $NoKeywords: $ |
|
//=============================================================================// |
|
|
|
#ifndef MESSAGEMAP_H |
|
#define MESSAGEMAP_H |
|
|
|
#ifdef _WIN32 |
|
#pragma once |
|
#endif |
|
|
|
#include "tier1/utlvector.h" |
|
|
|
// more flexible than default pointers to members code required for casting member function pointers |
|
//#pragma pointers_to_members( full_generality, virtual_inheritance ) |
|
|
|
namespace vgui |
|
{ |
|
|
|
////////////// MESSAGEMAP DEFINITIONS ////////////// |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: parameter data type enumeration |
|
// used internal but the shortcut macros require this to be exposed |
|
//----------------------------------------------------------------------------- |
|
enum DataType_t |
|
{ |
|
DATATYPE_VOID, |
|
DATATYPE_CONSTCHARPTR, |
|
DATATYPE_INT, |
|
DATATYPE_FLOAT, |
|
DATATYPE_PTR, |
|
DATATYPE_BOOL, |
|
DATATYPE_KEYVALUES, |
|
DATATYPE_CONSTWCHARPTR, |
|
DATATYPE_UINT64, |
|
DATATYPE_HANDLE, // It's an int, really |
|
}; |
|
|
|
#ifdef WIN32 |
|
class __virtual_inheritance Panel; |
|
#else |
|
class Panel; |
|
#endif |
|
typedef uintp VPANEL; |
|
|
|
typedef void (Panel::*MessageFunc_t)(void); |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Single item in a message map |
|
// Contains the information to map a string message name with parameters |
|
// to a function call |
|
//----------------------------------------------------------------------------- |
|
#pragma warning(disable:4121) |
|
struct MessageMapItem_t |
|
{ |
|
const char *name; |
|
// VC6 aligns this to 16-bytes. Since some of the code has been compiled with VC6, |
|
// we need to enforce the alignment on later compilers to remain compatible. |
|
ALIGN16 MessageFunc_t func; |
|
|
|
int numParams; |
|
|
|
DataType_t firstParamType; |
|
const char *firstParamName; |
|
|
|
DataType_t secondParamType; |
|
const char *secondParamName; |
|
|
|
int nameSymbol; |
|
int firstParamSymbol; |
|
int secondParamSymbol; |
|
}; |
|
|
|
#define DECLARE_PANELMESSAGEMAP( className ) \ |
|
static void AddToMap( char const *scriptname, vgui::MessageFunc_t function, int paramCount, int p1type, const char *p1name, int p2type, const char *p2name ) \ |
|
{ \ |
|
vgui::PanelMessageMap *map = vgui::FindOrAddPanelMessageMap( GetPanelClassName() ); \ |
|
\ |
|
vgui::MessageMapItem_t entry; \ |
|
entry.name = scriptname; \ |
|
entry.func = function; \ |
|
entry.numParams = paramCount; \ |
|
entry.firstParamType = (vgui::DataType_t)p1type; \ |
|
entry.firstParamName = p1name; \ |
|
entry.secondParamType = (vgui::DataType_t)p2type; \ |
|
entry.secondParamName = p2name; \ |
|
entry.nameSymbol = 0; \ |
|
entry.firstParamSymbol = 0; \ |
|
entry.secondParamSymbol = 0; \ |
|
\ |
|
map->entries.AddToTail( entry ); \ |
|
} \ |
|
\ |
|
static void ChainToMap( void ) \ |
|
{ \ |
|
static bool chained = false; \ |
|
if ( chained ) \ |
|
return; \ |
|
chained = true; \ |
|
vgui::PanelMessageMap *map = vgui::FindOrAddPanelMessageMap( GetPanelClassName() ); \ |
|
map->pfnClassName = &GetPanelClassName; \ |
|
if ( map && GetPanelBaseClassName() && GetPanelBaseClassName()[0] ) \ |
|
{ \ |
|
map->baseMap = vgui::FindOrAddPanelMessageMap( GetPanelBaseClassName() ); \ |
|
} \ |
|
} \ |
|
\ |
|
class className##_RegisterMap; \ |
|
friend class className##_RegisterMap; \ |
|
class className##_RegisterMap \ |
|
{ \ |
|
public: \ |
|
className##_RegisterMap() \ |
|
{ \ |
|
className::ChainToMap(); \ |
|
} \ |
|
}; \ |
|
className##_RegisterMap m_RegisterClass; \ |
|
\ |
|
virtual vgui::PanelMessageMap *GetMessageMap() \ |
|
{ \ |
|
static vgui::PanelMessageMap *s_pMap = vgui::FindOrAddPanelMessageMap( GetPanelClassName() ); \ |
|
return s_pMap; \ |
|
} |
|
|
|
#if !defined( _XBOX ) |
|
#define VGUI_USEKEYBINDINGMAPS 1 |
|
#endif |
|
|
|
#if defined( VGUI_USEKEYBINDINGMAPS ) |
|
|
|
#define DECLARE_CLASS_SIMPLE( className, baseClassName ) \ |
|
typedef baseClassName BaseClass; \ |
|
typedef className ThisClass; \ |
|
public: \ |
|
DECLARE_PANELMESSAGEMAP( className ); \ |
|
DECLARE_PANELANIMATION( className ); \ |
|
DECLARE_KEYBINDINGMAP( className ); \ |
|
static char const *GetPanelClassName() { return #className; } \ |
|
static char const *GetPanelBaseClassName() { return #baseClassName; } |
|
|
|
#define DECLARE_CLASS_SIMPLE_NOBASE( className ) \ |
|
typedef className ThisClass; \ |
|
public: \ |
|
DECLARE_PANELMESSAGEMAP( className ); \ |
|
DECLARE_PANELANIMATION( className ); \ |
|
DECLARE_KEYBINDINGMAP( className ); \ |
|
static char const *GetPanelClassName() { return #className; } \ |
|
static char const *GetPanelBaseClassName() { return NULL; } |
|
|
|
#else // no keybinding maps |
|
|
|
#define DECLARE_CLASS_SIMPLE( className, baseClassName ) \ |
|
typedef baseClassName BaseClass; \ |
|
typedef className ThisClass; \ |
|
public: \ |
|
DECLARE_PANELMESSAGEMAP( className ); \ |
|
DECLARE_PANELANIMATION( className ); \ |
|
static char const *GetPanelClassName() { return #className; } \ |
|
static char const *GetPanelBaseClassName() { return #baseClassName; } |
|
|
|
#define DECLARE_CLASS_SIMPLE_NOBASE( className ) \ |
|
typedef className ThisClass; \ |
|
public: \ |
|
DECLARE_PANELMESSAGEMAP( className ); \ |
|
DECLARE_PANELANIMATION( className ); \ |
|
static char const *GetPanelClassName() { return #className; } \ |
|
static char const *GetPanelBaseClassName() { return NULL; } |
|
|
|
#endif // !VGUI_USEKEYBINDINGMAPS |
|
|
|
#define _MessageFuncCommon( name, scriptname, paramCount, p1type, p1name, p2type, p2name ) \ |
|
class PanelMessageFunc_##name; \ |
|
friend class PanelMessageFunc_##name; \ |
|
class PanelMessageFunc_##name \ |
|
{ \ |
|
public: \ |
|
static void InitVar() \ |
|
{ \ |
|
static bool bAdded = false; \ |
|
if ( !bAdded ) \ |
|
{ \ |
|
bAdded = true; \ |
|
AddToMap( scriptname, (vgui::MessageFunc_t)&ThisClass::name, paramCount, p1type, p1name, p2type, p2name ); \ |
|
} \ |
|
} \ |
|
PanelMessageFunc_##name() \ |
|
{ \ |
|
PanelMessageFunc_##name::InitVar(); \ |
|
} \ |
|
}; \ |
|
PanelMessageFunc_##name m_##name##_register; \ |
|
|
|
// Use this macro to define a message mapped function |
|
// must end with a semicolon ';', or with a function |
|
// no parameter |
|
#define MESSAGE_FUNC( name, scriptname ) _MessageFuncCommon( name, scriptname, 0, 0, 0, 0, 0 ); virtual void name( void ) |
|
|
|
// one parameter |
|
#define MESSAGE_FUNC_INT( name, scriptname, p1 ) _MessageFuncCommon( name, scriptname, 1, vgui::DATATYPE_INT, #p1, 0, 0 ); virtual void name( int p1 ) |
|
#define MESSAGE_FUNC_UINT64( name, scriptname, p1 ) _MessageFuncCommon( name, scriptname, 1, vgui::DATATYPE_UINT64, #p1, 0, 0 ); virtual void name( uint64 p1 ) |
|
#define MESSAGE_FUNC_PTR( name, scriptname, p1 ) _MessageFuncCommon( name, scriptname, 1, vgui::DATATYPE_PTR, #p1, 0, 0 ); virtual void name( vgui::Panel *p1 ) |
|
#define MESSAGE_FUNC_HANDLE( name, scriptname, p1 ) _MessageFuncCommon( name, scriptname, 1, vgui::DATATYPE_HANDLE, #p1, 0, 0 ); virtual void name( vgui::VPANEL p1 ) |
|
#define MESSAGE_FUNC_ENUM( name, scriptname, t1, p1 ) _MessageFuncCommon( name, scriptname, 1, vgui::DATATYPE_INT, #p1, 0, 0 ); virtual void name( t1 p1 ) |
|
#define MESSAGE_FUNC_FLOAT( name, scriptname, p1 ) _MessageFuncCommon( name, scriptname, 1, vgui::DATATYPE_FLOAT, #p1, 0, 0 ); virtual void name( float p1 ) |
|
#define MESSAGE_FUNC_CHARPTR( name, scriptname, p1 ) _MessageFuncCommon( name, scriptname, 1, vgui::DATATYPE_CONSTCHARPTR, #p1, 0, 0 ); virtual void name( const char *p1 ) |
|
#define MESSAGE_FUNC_WCHARPTR( name, scriptname, p1 ) _MessageFuncCommon( name, scriptname, 1, vgui::DATATYPE_CONSTWCHARPTR, #p1, 0, 0 ); virtual void name( const wchar_t *p1 ) |
|
|
|
// two parameters |
|
#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 ) |
|
#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 ) |
|
#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 ) |
|
#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 ) |
|
#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 ) |
|
#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 ) |
|
#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 ) |
|
#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 ) |
|
#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 ) |
|
#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 ) |
|
#define MESSAGE_FUNC_HANDLE_HANDLE( name, scriptname, p1, p2 ) _MessageFuncCommon( name, scriptname, 2, vgui::DATATYPE_HANDLE, #p1, vgui::DATATYPE_HANDLE, #p2 ); virtual void name( vgui::VPANEL p1, vgui::VPANEL p2 ) |
|
|
|
// unlimited parameters (passed in the whole KeyValues) |
|
#define MESSAGE_FUNC_PARAMS( name, scriptname, p1 ) _MessageFuncCommon( name, scriptname, 1, vgui::DATATYPE_KEYVALUES, NULL, 0, 0 ); virtual void name( KeyValues *p1 ) |
|
|
|
// no-virtual function version |
|
#define MESSAGE_FUNC_NV( name, scriptname ) _MessageFuncCommon( name, scriptname, 0, 0, 0, 0, 0 ); void name( void ) |
|
#define MESSAGE_FUNC_NV_INT( name, scriptname, p1 ) _MessageFuncCommon( name, scriptname, 1, vgui::DATATYPE_INT, #p1, 0, 0 ); void name( int p1 ) |
|
#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 ) |
|
|
|
|
|
// mapping, one per class |
|
struct PanelMessageMap |
|
{ |
|
PanelMessageMap() |
|
{ |
|
baseMap = NULL; |
|
pfnClassName = NULL; |
|
processed = false; |
|
} |
|
|
|
CUtlVector< MessageMapItem_t > entries; |
|
bool processed; |
|
PanelMessageMap *baseMap; |
|
char const *(*pfnClassName)( void ); |
|
}; |
|
|
|
PanelMessageMap *FindPanelMessageMap( char const *className ); |
|
PanelMessageMap *FindOrAddPanelMessageMap( char const *className ); |
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
// |
|
// OBSELETE MAPPING FUNCTIONS, USE ABOVE |
|
// |
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
// no parameters |
|
#define MAP_MESSAGE( type, name, func ) { name, (vgui::MessageFunc_t)(&type::func), 0 } |
|
|
|
// implicit single parameter (params is the data store) |
|
#define MAP_MESSAGE_PARAMS( type, name, func ) { name, (vgui::MessageFunc_t)(&type::func), 1, vgui::DATATYPE_KEYVALUES, NULL } |
|
|
|
// single parameter |
|
#define MAP_MESSAGE_PTR( type, name, func, param1 ) { name, (vgui::MessageFunc_t)(&type::func), 1, vgui::DATATYPE_PTR, param1 } |
|
#define MAP_MESSAGE_INT( type, name, func, param1 ) { name, (vgui::MessageFunc_t)(&type::func), 1, vgui::DATATYPE_INT, param1 } |
|
#define MAP_MESSAGE_BOOL( type, name, func, param1 ) { name, (vgui::MessageFunc_t)(&type::func), 1, vgui::DATATYPE_BOOL, param1 } |
|
#define MAP_MESSAGE_FLOAT( type, name, func, param1 ) { name, (vgui::MessageFunc_t)(&type::func), 1, vgui::DATATYPE_FLOAT, param1 } |
|
#define MAP_MESSAGE_PTR( type, name, func, param1 ) { name, (vgui::MessageFunc_t)(&type::func), 1, vgui::DATATYPE_PTR, param1 } |
|
#define MAP_MESSAGE_CONSTCHARPTR( type, name, func, param1) { name, (vgui::MessageFunc_t)(&type::func), 1, vgui::DATATYPE_CONSTCHARPTR, param1 } |
|
#define MAP_MESSAGE_CONSTWCHARPTR( type, name, func, param1) { name, (vgui::MessageFunc_t)(&type::func), 1, vgui::DATATYPE_CONSTWCHARPTR, param1 } |
|
|
|
// two parameters |
|
#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 } |
|
#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 } |
|
#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 } |
|
#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 } |
|
#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 } |
|
#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 } |
|
|
|
// if more parameters are needed, just use MAP_MESSAGE_PARAMS() and pass the keyvalue set into the function |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: stores the list of objects in the hierarchy |
|
// used to iterate through an object's message maps |
|
//----------------------------------------------------------------------------- |
|
struct PanelMap_t |
|
{ |
|
MessageMapItem_t *dataDesc; |
|
int dataNumFields; |
|
const char *dataClassName; |
|
PanelMap_t *baseMap; |
|
int processed; |
|
}; |
|
|
|
// for use in class declarations |
|
// declares the static variables and functions needed for the data description iteration |
|
#define DECLARE_PANELMAP() \ |
|
static vgui::PanelMap_t m_PanelMap; \ |
|
static vgui::MessageMapItem_t m_MessageMap[]; \ |
|
virtual vgui::PanelMap_t *GetPanelMap( void ); |
|
|
|
// could embed typeid() into here as well? |
|
#define IMPLEMENT_PANELMAP( derivedClass, baseClass ) \ |
|
vgui::PanelMap_t derivedClass::m_PanelMap = { derivedClass::m_MessageMap, ARRAYSIZE(derivedClass::m_MessageMap), #derivedClass, &baseClass::m_PanelMap }; \ |
|
vgui::PanelMap_t *derivedClass::GetPanelMap( void ) { return &m_PanelMap; } |
|
|
|
typedef vgui::Panel *( *PANELCREATEFUNC )( void ); |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Used by DECLARE_BUILD_FACTORY macro to create a linked list of |
|
// instancing functions |
|
//----------------------------------------------------------------------------- |
|
class CBuildFactoryHelper |
|
{ |
|
public: |
|
// Static list of helpers |
|
static CBuildFactoryHelper *m_sHelpers; |
|
|
|
public: |
|
// Construction |
|
CBuildFactoryHelper( char const *className, PANELCREATEFUNC func ); |
|
|
|
// Accessors |
|
CBuildFactoryHelper *GetNext( void ); |
|
|
|
char const *GetClassName() const; |
|
|
|
vgui::Panel *CreatePanel(); |
|
|
|
static vgui::Panel *InstancePanel( char const *className ); |
|
static void GetFactoryNames( CUtlVector< char const * >& list ); |
|
private: |
|
|
|
static bool HasFactory( char const *className ); |
|
|
|
// Next factory in list |
|
CBuildFactoryHelper *m_pNext; |
|
|
|
int m_Type; |
|
PANELCREATEFUNC m_CreateFunc; |
|
char const *m_pClassName; |
|
}; |
|
|
|
// This is the macro which implements creation of each type of panel |
|
// It creates a function which instances an object of the specified type |
|
// It them hooks that function up to the helper list so that the CHud objects can create |
|
// the elements by name, with no header file dependency, etc. |
|
#define DECLARE_BUILD_FACTORY( className ) \ |
|
static vgui::Panel *Create_##className( void ) \ |
|
{ \ |
|
return new className( NULL, NULL ); \ |
|
}; \ |
|
static vgui::CBuildFactoryHelper g_##className##_Helper( #className, Create_##className );\ |
|
className *g_##className##LinkerHack = NULL; |
|
|
|
#define DECLARE_BUILD_FACTORY_DEFAULT_TEXT( className, defaultText ) \ |
|
static vgui::Panel *Create_##className( void ) \ |
|
{ \ |
|
return new className( NULL, NULL, #defaultText ); \ |
|
}; \ |
|
static vgui::CBuildFactoryHelper g_##className##_Helper( #className, Create_##className );\ |
|
className *g_##className##LinkerHack = NULL; |
|
|
|
// This one allows passing in a special function with calls new panel( xxx ) with arbitrary default parameters |
|
#define DECLARE_BUILD_FACTORY_CUSTOM( className, createFunc ) \ |
|
static vgui::CBuildFactoryHelper g_##className##_Helper( #className, createFunc );\ |
|
className *g_##className##LinkerHack = NULL; |
|
|
|
#define DECLARE_BUILD_FACTORY_CUSTOM_ALIAS( className, factoryName, createFunc ) \ |
|
static vgui::CBuildFactoryHelper g_##factoryName##_Helper( #factoryName, createFunc );\ |
|
className *g_##factoryName##LinkerHack = NULL; |
|
|
|
} // namespace vgui |
|
|
|
|
|
#endif // MESSAGEMAP_H
|
|
|