485 lines
24 KiB
C++
485 lines
24 KiB
C++
//========= 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 unsigned int 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)
|
|
|
|
// 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
|