aboutsummaryrefslogtreecommitdiff
path: root/sp/src/public/datamap.h
diff options
context:
space:
mode:
authorJoe Ludwig <[email protected]>2013-06-26 15:22:04 -0700
committerJoe Ludwig <[email protected]>2013-06-26 15:22:04 -0700
commit39ed87570bdb2f86969d4be821c94b722dc71179 (patch)
treeabc53757f75f40c80278e87650ea92808274aa59 /sp/src/public/datamap.h
downloadsource-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.tar.xz
source-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.zip
First version of the SOurce SDK 2013
Diffstat (limited to 'sp/src/public/datamap.h')
-rw-r--r--sp/src/public/datamap.h455
1 files changed, 455 insertions, 0 deletions
diff --git a/sp/src/public/datamap.h b/sp/src/public/datamap.h
new file mode 100644
index 00000000..36df2de4
--- /dev/null
+++ b/sp/src/public/datamap.h
@@ -0,0 +1,455 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#ifndef DATAMAP_H
+#define DATAMAP_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+#ifndef VECTOR_H
+#include "mathlib/vector.h"
+#endif
+
+#include "tier1/utlvector.h"
+
+#include "tier0/memdbgon.h"
+
+// SINGLE_INHERITANCE restricts the size of CBaseEntity pointers-to-member-functions to 4 bytes
+class SINGLE_INHERITANCE CBaseEntity;
+struct inputdata_t;
+
+#define INVALID_TIME (FLT_MAX * -1.0) // Special value not rebased on save/load
+
+typedef enum _fieldtypes
+{
+ FIELD_VOID = 0, // No type or value
+ FIELD_FLOAT, // Any floating point value
+ FIELD_STRING, // A string ID (return from ALLOC_STRING)
+ FIELD_VECTOR, // Any vector, QAngle, or AngularImpulse
+ FIELD_QUATERNION, // A quaternion
+ FIELD_INTEGER, // Any integer or enum
+ FIELD_BOOLEAN, // boolean, implemented as an int, I may use this as a hint for compression
+ FIELD_SHORT, // 2 byte integer
+ FIELD_CHARACTER, // a byte
+ FIELD_COLOR32, // 8-bit per channel r,g,b,a (32bit color)
+ FIELD_EMBEDDED, // an embedded object with a datadesc, recursively traverse and embedded class/structure based on an additional typedescription
+ FIELD_CUSTOM, // special type that contains function pointers to it's read/write/parse functions
+
+ FIELD_CLASSPTR, // CBaseEntity *
+ FIELD_EHANDLE, // Entity handle
+ FIELD_EDICT, // edict_t *
+
+ FIELD_POSITION_VECTOR, // A world coordinate (these are fixed up across level transitions automagically)
+ FIELD_TIME, // a floating point time (these are fixed up automatically too!)
+ FIELD_TICK, // an integer tick count( fixed up similarly to time)
+ FIELD_MODELNAME, // Engine string that is a model name (needs precache)
+ FIELD_SOUNDNAME, // Engine string that is a sound name (needs precache)
+
+ FIELD_INPUT, // a list of inputed data fields (all derived from CMultiInputVar)
+ FIELD_FUNCTION, // A class function pointer (Think, Use, etc)
+
+ FIELD_VMATRIX, // a vmatrix (output coords are NOT worldspace)
+
+ // NOTE: Use float arrays for local transformations that don't need to be fixed up.
+ FIELD_VMATRIX_WORLDSPACE,// A VMatrix that maps some local space to world space (translation is fixed up on level transitions)
+ FIELD_MATRIX3X4_WORLDSPACE, // matrix3x4_t that maps some local space to world space (translation is fixed up on level transitions)
+
+ FIELD_INTERVAL, // a start and range floating point interval ( e.g., 3.2->3.6 == 3.2 and 0.4 )
+ FIELD_MODELINDEX, // a model index
+ FIELD_MATERIALINDEX, // a material index (using the material precache string table)
+
+ FIELD_VECTOR2D, // 2 floats
+
+ FIELD_TYPECOUNT, // MUST BE LAST
+} fieldtype_t;
+
+
+//-----------------------------------------------------------------------------
+// Field sizes...
+//-----------------------------------------------------------------------------
+template <int FIELD_TYPE>
+class CDatamapFieldSizeDeducer
+{
+public:
+ enum
+ {
+ SIZE = 0
+ };
+
+ static int FieldSize( )
+ {
+ return 0;
+ }
+};
+
+#define DECLARE_FIELD_SIZE( _fieldType, _fieldSize ) \
+ template< > class CDatamapFieldSizeDeducer<_fieldType> { public: enum { SIZE = _fieldSize }; static int FieldSize() { return _fieldSize; } };
+#define FIELD_SIZE( _fieldType ) CDatamapFieldSizeDeducer<_fieldType>::SIZE
+#define FIELD_BITS( _fieldType ) (FIELD_SIZE( _fieldType ) * 8)
+
+DECLARE_FIELD_SIZE( FIELD_FLOAT, sizeof(float) )
+DECLARE_FIELD_SIZE( FIELD_STRING, sizeof(int) )
+DECLARE_FIELD_SIZE( FIELD_VECTOR, 3 * sizeof(float) )
+DECLARE_FIELD_SIZE( FIELD_VECTOR2D, 2 * sizeof(float) )
+DECLARE_FIELD_SIZE( FIELD_QUATERNION, 4 * sizeof(float))
+DECLARE_FIELD_SIZE( FIELD_INTEGER, sizeof(int))
+DECLARE_FIELD_SIZE( FIELD_BOOLEAN, sizeof(char))
+DECLARE_FIELD_SIZE( FIELD_SHORT, sizeof(short))
+DECLARE_FIELD_SIZE( FIELD_CHARACTER, sizeof(char))
+DECLARE_FIELD_SIZE( FIELD_COLOR32, sizeof(int))
+DECLARE_FIELD_SIZE( FIELD_CLASSPTR, sizeof(int))
+DECLARE_FIELD_SIZE( FIELD_EHANDLE, sizeof(int))
+DECLARE_FIELD_SIZE( FIELD_EDICT, sizeof(int))
+DECLARE_FIELD_SIZE( FIELD_POSITION_VECTOR, 3 * sizeof(float))
+DECLARE_FIELD_SIZE( FIELD_TIME, sizeof(float))
+DECLARE_FIELD_SIZE( FIELD_TICK, sizeof(int))
+DECLARE_FIELD_SIZE( FIELD_MODELNAME, sizeof(int))
+DECLARE_FIELD_SIZE( FIELD_SOUNDNAME, sizeof(int))
+DECLARE_FIELD_SIZE( FIELD_INPUT, sizeof(int))
+#ifdef POSIX
+// pointer to members under gnuc are 8bytes if you have a virtual func
+DECLARE_FIELD_SIZE( FIELD_FUNCTION, sizeof(uint64))
+#else
+DECLARE_FIELD_SIZE( FIELD_FUNCTION, sizeof(int *))
+#endif
+DECLARE_FIELD_SIZE( FIELD_VMATRIX, 16 * sizeof(float))
+DECLARE_FIELD_SIZE( FIELD_VMATRIX_WORLDSPACE, 16 * sizeof(float))
+DECLARE_FIELD_SIZE( FIELD_MATRIX3X4_WORLDSPACE, 12 * sizeof(float))
+DECLARE_FIELD_SIZE( FIELD_INTERVAL, 2 * sizeof( float) ) // NOTE: Must match interval.h definition
+DECLARE_FIELD_SIZE( FIELD_MODELINDEX, sizeof(int) )
+DECLARE_FIELD_SIZE( FIELD_MATERIALINDEX, sizeof(int) )
+
+
+#define ARRAYSIZE2D(p) (sizeof(p)/sizeof(p[0][0]))
+#define SIZE_OF_ARRAY(p) _ARRAYSIZE(p)
+
+#define _FIELD(name,fieldtype,count,flags,mapname,tolerance) { fieldtype, #name, { offsetof(classNameTypedef, name), 0 }, count, flags, mapname, NULL, NULL, NULL, sizeof( ((classNameTypedef *)0)->name ), NULL, 0, tolerance }
+#define DEFINE_FIELD_NULL { FIELD_VOID,0, {0,0},0,0,0,0,0,0}
+#define DEFINE_FIELD(name,fieldtype) _FIELD(name, fieldtype, 1, FTYPEDESC_SAVE, NULL, 0 )
+#define DEFINE_KEYFIELD(name,fieldtype, mapname) _FIELD(name, fieldtype, 1, FTYPEDESC_KEY | FTYPEDESC_SAVE, mapname, 0 )
+#define DEFINE_KEYFIELD_NOT_SAVED(name,fieldtype, mapname)_FIELD(name, fieldtype, 1, FTYPEDESC_KEY, mapname, 0 )
+#define DEFINE_AUTO_ARRAY(name,fieldtype) _FIELD(name, fieldtype, SIZE_OF_ARRAY(((classNameTypedef *)0)->name), FTYPEDESC_SAVE, NULL, 0 )
+#define DEFINE_AUTO_ARRAY_KEYFIELD(name,fieldtype,mapname) _FIELD(name, fieldtype, SIZE_OF_ARRAY(((classNameTypedef *)0)->name), FTYPEDESC_SAVE, mapname, 0 )
+#define DEFINE_ARRAY(name,fieldtype, count) _FIELD(name, fieldtype, count, FTYPEDESC_SAVE, NULL, 0 )
+#define DEFINE_ENTITY_FIELD(name,fieldtype) _FIELD(edict_t, name, fieldtype, 1, FTYPEDESC_KEY | FTYPEDESC_SAVE, #name, 0 )
+#define DEFINE_ENTITY_GLOBAL_FIELD(name,fieldtype) _FIELD(edict_t, name, fieldtype, 1, FTYPEDESC_KEY | FTYPEDESC_SAVE | FTYPEDESC_GLOBAL, #name, 0 )
+#define DEFINE_GLOBAL_FIELD(name,fieldtype) _FIELD(name, fieldtype, 1, FTYPEDESC_GLOBAL | FTYPEDESC_SAVE, NULL, 0 )
+#define DEFINE_GLOBAL_KEYFIELD(name,fieldtype, mapname) _FIELD(name, fieldtype, 1, FTYPEDESC_GLOBAL | FTYPEDESC_KEY | FTYPEDESC_SAVE, mapname, 0 )
+#define DEFINE_CUSTOM_FIELD(name,datafuncs) { FIELD_CUSTOM, #name, { offsetof(classNameTypedef, name), 0 }, 1, FTYPEDESC_SAVE, NULL, datafuncs, NULL }
+#define DEFINE_CUSTOM_KEYFIELD(name,datafuncs,mapname) { FIELD_CUSTOM, #name, { offsetof(classNameTypedef, name), 0 }, 1, FTYPEDESC_SAVE | FTYPEDESC_KEY, mapname, datafuncs, NULL }
+#define DEFINE_AUTO_ARRAY2D(name,fieldtype) _FIELD(name, fieldtype, ARRAYSIZE2D(((classNameTypedef *)0)->name), FTYPEDESC_SAVE, NULL, 0 )
+// Used by byteswap datadescs
+#define DEFINE_BITFIELD(name,fieldtype,bitcount) DEFINE_ARRAY(name,fieldtype,((bitcount+FIELD_BITS(fieldtype)-1)&~(FIELD_BITS(fieldtype)-1)) / FIELD_BITS(fieldtype) )
+#define DEFINE_INDEX(name,fieldtype) _FIELD(name, fieldtype, 1, FTYPEDESC_INDEX, NULL, 0 )
+
+#define DEFINE_EMBEDDED( name ) \
+ { FIELD_EMBEDDED, #name, { offsetof(classNameTypedef, name), 0 }, 1, FTYPEDESC_SAVE, NULL, NULL, NULL, &(((classNameTypedef *)0)->name.m_DataMap), sizeof( ((classNameTypedef *)0)->name ), NULL, 0, 0.0f }
+
+#define DEFINE_EMBEDDED_OVERRIDE( name, overridetype ) \
+ { FIELD_EMBEDDED, #name, { offsetof(classNameTypedef, name), 0 }, 1, FTYPEDESC_SAVE, NULL, NULL, NULL, &((overridetype *)0)->m_DataMap, sizeof( ((classNameTypedef *)0)->name ), NULL, 0, 0.0f }
+
+#define DEFINE_EMBEDDEDBYREF( name ) \
+ { FIELD_EMBEDDED, #name, { offsetof(classNameTypedef, name), 0 }, 1, FTYPEDESC_SAVE | FTYPEDESC_PTR, NULL, NULL, NULL, &(((classNameTypedef *)0)->name->m_DataMap), sizeof( *(((classNameTypedef *)0)->name) ), NULL, 0, 0.0f }
+
+#define DEFINE_EMBEDDED_ARRAY( name, count ) \
+ { FIELD_EMBEDDED, #name, { offsetof(classNameTypedef, name), 0 }, count, FTYPEDESC_SAVE, NULL, NULL, NULL, &(((classNameTypedef *)0)->name->m_DataMap), sizeof( ((classNameTypedef *)0)->name[0] ), NULL, 0, 0.0f }
+
+#define DEFINE_EMBEDDED_AUTO_ARRAY( name ) \
+ { FIELD_EMBEDDED, #name, { offsetof(classNameTypedef, name), 0 }, SIZE_OF_ARRAY( ((classNameTypedef *)0)->name ), FTYPEDESC_SAVE, NULL, NULL, NULL, &(((classNameTypedef *)0)->name->m_DataMap), sizeof( ((classNameTypedef *)0)->name[0] ), NULL, 0, 0.0f }
+
+#ifndef NO_ENTITY_PREDICTION
+
+#define DEFINE_PRED_TYPEDESCRIPTION( name, fieldtype ) \
+ { FIELD_EMBEDDED, #name, { offsetof(classNameTypedef, name), 0 }, 1, FTYPEDESC_SAVE, NULL, NULL, NULL, &fieldtype::m_PredMap }
+
+#define DEFINE_PRED_TYPEDESCRIPTION_PTR( name, fieldtype ) \
+ { FIELD_EMBEDDED, #name, { offsetof(classNameTypedef, name), 0 }, 1, FTYPEDESC_SAVE | FTYPEDESC_PTR, NULL, NULL, NULL, &fieldtype::m_PredMap }
+
+#else
+
+#define DEFINE_PRED_TYPEDESCRIPTION( name, fieldtype ) DEFINE_FIELD_NULL
+#define DEFINE_PRED_TYPEDESCRIPTION_PTR( name, fieldtype ) DEFINE_FIELD_NULL
+
+#endif
+
+// Extensions to datamap.h macros for predicted entities only
+#define DEFINE_PRED_FIELD(name,fieldtype, flags) _FIELD(name, fieldtype, 1, flags, NULL, 0.0f )
+#define DEFINE_PRED_ARRAY(name,fieldtype, count,flags) _FIELD(name, fieldtype, count, flags, NULL, 0.0f )
+#define DEFINE_FIELD_NAME(localname,netname,fieldtype) _FIELD(localname, fieldtype, 1, 0, #netname, 0.0f )
+// Predictable macros, which include a tolerance for floating point values...
+#define DEFINE_PRED_FIELD_TOL(name,fieldtype, flags,tolerance) _FIELD(name, fieldtype, 1, flags, NULL, tolerance )
+#define DEFINE_PRED_ARRAY_TOL(name,fieldtype, count,flags,tolerance) _FIELD(name, fieldtype, count, flags, NULL, tolerance)
+#define DEFINE_FIELD_NAME_TOL(localname,netname,fieldtolerance) _FIELD(localname, fieldtype, 1, 0, #netname, tolerance )
+
+//#define DEFINE_DATA( name, fieldextname, flags ) _FIELD(name, fieldtype, 1, flags, extname )
+
+// INPUTS
+#define DEFINE_INPUT( name, fieldtype, inputname ) { fieldtype, #name, { offsetof(classNameTypedef, name), 0 }, 1, FTYPEDESC_INPUT | FTYPEDESC_SAVE | FTYPEDESC_KEY, inputname, NULL, NULL, NULL, sizeof( ((classNameTypedef *)0)->name ) }
+#define DEFINE_INPUTFUNC( fieldtype, inputname, inputfunc ) { fieldtype, #inputfunc, { NULL, NULL }, 1, FTYPEDESC_INPUT, inputname, NULL, static_cast <inputfunc_t> (&classNameTypedef::inputfunc) }
+
+// OUTPUTS
+// the variable 'name' MUST BE derived from CBaseOutput
+// we know the output type from the variable itself, so it doesn't need to be specified here
+class ISaveRestoreOps;
+extern ISaveRestoreOps *eventFuncs;
+#define DEFINE_OUTPUT( name, outputname ) { FIELD_CUSTOM, #name, { offsetof(classNameTypedef, name), 0 }, 1, FTYPEDESC_OUTPUT | FTYPEDESC_SAVE | FTYPEDESC_KEY, outputname, eventFuncs }
+
+// replaces EXPORT table for portability and non-DLL based systems (xbox)
+#define DEFINE_FUNCTION_RAW( function, func_type ) { FIELD_VOID, nameHolder.GenerateName(#function), { NULL, NULL }, 1, FTYPEDESC_FUNCTIONTABLE, NULL, NULL, (inputfunc_t)((func_type)(&classNameTypedef::function)) }
+#define DEFINE_FUNCTION( function ) DEFINE_FUNCTION_RAW( function, inputfunc_t )
+
+
+#define FTYPEDESC_GLOBAL 0x0001 // This field is masked for global entity save/restore
+#define FTYPEDESC_SAVE 0x0002 // This field is saved to disk
+#define FTYPEDESC_KEY 0x0004 // This field can be requested and written to by string name at load time
+#define FTYPEDESC_INPUT 0x0008 // This field can be written to by string name at run time, and a function called
+#define FTYPEDESC_OUTPUT 0x0010 // This field propogates it's value to all targets whenever it changes
+#define FTYPEDESC_FUNCTIONTABLE 0x0020 // This is a table entry for a member function pointer
+#define FTYPEDESC_PTR 0x0040 // This field is a pointer, not an embedded object
+#define FTYPEDESC_OVERRIDE 0x0080 // The field is an override for one in a base class (only used by prediction system for now)
+
+// Flags used by other systems (e.g., prediction system)
+#define FTYPEDESC_INSENDTABLE 0x0100 // This field is present in a network SendTable
+#define FTYPEDESC_PRIVATE 0x0200 // The field is local to the client or server only (not referenced by prediction code and not replicated by networking)
+#define FTYPEDESC_NOERRORCHECK 0x0400 // The field is part of the prediction typedescription, but doesn't get compared when checking for errors
+
+#define FTYPEDESC_MODELINDEX 0x0800 // The field is a model index (used for debugging output)
+
+#define FTYPEDESC_INDEX 0x1000 // The field is an index into file data, used for byteswapping.
+
+// These flags apply to C_BasePlayer derived objects only
+#define FTYPEDESC_VIEW_OTHER_PLAYER 0x2000 // By default you can only view fields on the local player (yourself),
+ // but if this is set, then we allow you to see fields on other players
+#define FTYPEDESC_VIEW_OWN_TEAM 0x4000 // Only show this data if the player is on the same team as the local player
+#define FTYPEDESC_VIEW_NEVER 0x8000 // Never show this field to anyone, even the local player (unusual)
+
+#define TD_MSECTOLERANCE 0.001f // This is a FIELD_FLOAT and should only be checked to be within 0.001 of the networked info
+
+struct typedescription_t;
+
+
+class ISaveRestoreOps;
+
+//
+// Function prototype for all input handlers.
+//
+typedef void (CBaseEntity::*inputfunc_t)(inputdata_t &data);
+
+struct datamap_t;
+struct typedescription_t;
+
+enum
+{
+ TD_OFFSET_NORMAL = 0,
+ TD_OFFSET_PACKED = 1,
+
+ // Must be last
+ TD_OFFSET_COUNT,
+};
+
+struct typedescription_t
+{
+ fieldtype_t fieldType;
+ const char *fieldName;
+ int fieldOffset[ TD_OFFSET_COUNT ]; // 0 == normal, 1 == packed offset
+ unsigned short fieldSize;
+ short flags;
+ // the name of the variable in the map/fgd data, or the name of the action
+ const char *externalName;
+ // pointer to the function set for save/restoring of custom data types
+ ISaveRestoreOps *pSaveRestoreOps;
+ // for associating function with string names
+ inputfunc_t inputFunc;
+ // For embedding additional datatables inside this one
+ datamap_t *td;
+
+ // Stores the actual member variable size in bytes
+ int fieldSizeInBytes;
+
+ // FTYPEDESC_OVERRIDE point to first baseclass instance if chains_validated has occurred
+ struct typedescription_t *override_field;
+
+ // Used to track exclusion of baseclass fields
+ int override_count;
+
+ // Tolerance for field errors for float fields
+ float fieldTolerance;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: stores the list of objects in the hierarchy
+// used to iterate through an object's data descriptions
+//-----------------------------------------------------------------------------
+struct datamap_t
+{
+ typedescription_t *dataDesc;
+ int dataNumFields;
+ char const *dataClassName;
+ datamap_t *baseMap;
+
+ bool chains_validated;
+ // Have the "packed" offsets been computed
+ bool packed_offsets_computed;
+ int packed_size;
+
+#if defined( _DEBUG )
+ bool bValidityChecked;
+#endif // _DEBUG
+};
+
+
+//-----------------------------------------------------------------------------
+//
+// Macros used to implement datadescs
+//
+#define DECLARE_SIMPLE_DATADESC() \
+ static datamap_t m_DataMap; \
+ static datamap_t *GetBaseMap(); \
+ template <typename T> friend void DataMapAccess(T *, datamap_t **p); \
+ template <typename T> friend datamap_t *DataMapInit(T *);
+
+#define DECLARE_DATADESC() \
+ DECLARE_SIMPLE_DATADESC() \
+ virtual datamap_t *GetDataDescMap( void );
+
+#define BEGIN_DATADESC( className ) \
+ datamap_t className::m_DataMap = { 0, 0, #className, NULL }; \
+ datamap_t *className::GetDataDescMap( void ) { return &m_DataMap; } \
+ datamap_t *className::GetBaseMap() { datamap_t *pResult; DataMapAccess((BaseClass *)NULL, &pResult); return pResult; } \
+ BEGIN_DATADESC_GUTS( className )
+
+#define BEGIN_DATADESC_NO_BASE( className ) \
+ datamap_t className::m_DataMap = { 0, 0, #className, NULL }; \
+ datamap_t *className::GetDataDescMap( void ) { return &m_DataMap; } \
+ datamap_t *className::GetBaseMap() { return NULL; } \
+ BEGIN_DATADESC_GUTS( className )
+
+#define BEGIN_SIMPLE_DATADESC( className ) \
+ datamap_t className::m_DataMap = { 0, 0, #className, NULL }; \
+ datamap_t *className::GetBaseMap() { return NULL; } \
+ BEGIN_DATADESC_GUTS( className )
+
+#define BEGIN_SIMPLE_DATADESC_( className, BaseClass ) \
+ datamap_t className::m_DataMap = { 0, 0, #className, NULL }; \
+ datamap_t *className::GetBaseMap() { datamap_t *pResult; DataMapAccess((BaseClass *)NULL, &pResult); return pResult; } \
+ BEGIN_DATADESC_GUTS( className )
+
+#define BEGIN_DATADESC_GUTS( className ) \
+ template <typename T> datamap_t *DataMapInit(T *); \
+ template <> datamap_t *DataMapInit<className>( className * ); \
+ namespace className##_DataDescInit \
+ { \
+ datamap_t *g_DataMapHolder = DataMapInit( (className *)NULL ); /* This can/will be used for some clean up duties later */ \
+ } \
+ \
+ template <> datamap_t *DataMapInit<className>( className * ) \
+ { \
+ typedef className classNameTypedef; \
+ static CDatadescGeneratedNameHolder nameHolder(#className); \
+ className::m_DataMap.baseMap = className::GetBaseMap(); \
+ static typedescription_t dataDesc[] = \
+ { \
+ { FIELD_VOID,0, {0,0},0,0,0,0,0,0}, /* so you can define "empty" tables */
+
+#define END_DATADESC() \
+ }; \
+ \
+ if ( sizeof( dataDesc ) > sizeof( dataDesc[0] ) ) \
+ { \
+ classNameTypedef::m_DataMap.dataNumFields = SIZE_OF_ARRAY( dataDesc ) - 1; \
+ classNameTypedef::m_DataMap.dataDesc = &dataDesc[1]; \
+ } \
+ else \
+ { \
+ classNameTypedef::m_DataMap.dataNumFields = 1; \
+ classNameTypedef::m_DataMap.dataDesc = dataDesc; \
+ } \
+ return &classNameTypedef::m_DataMap; \
+ }
+
+// used for when there is no data description
+#define IMPLEMENT_NULL_SIMPLE_DATADESC( derivedClass ) \
+ BEGIN_SIMPLE_DATADESC( derivedClass ) \
+ END_DATADESC()
+
+#define IMPLEMENT_NULL_SIMPLE_DATADESC_( derivedClass, baseClass ) \
+ BEGIN_SIMPLE_DATADESC_( derivedClass, baseClass ) \
+ END_DATADESC()
+
+#define IMPLEMENT_NULL_DATADESC( derivedClass ) \
+ BEGIN_DATADESC( derivedClass ) \
+ END_DATADESC()
+
+// helps get the offset of a bitfield
+#define BEGIN_BITFIELD( name ) \
+ union \
+ { \
+ char name; \
+ struct \
+ {
+
+#define END_BITFIELD() \
+ }; \
+ };
+
+//-----------------------------------------------------------------------------
+// Forward compatability with potential seperate byteswap datadescs
+
+#define DECLARE_BYTESWAP_DATADESC() DECLARE_SIMPLE_DATADESC()
+#define BEGIN_BYTESWAP_DATADESC(name) BEGIN_SIMPLE_DATADESC(name)
+#define BEGIN_BYTESWAP_DATADESC_(name,base) BEGIN_SIMPLE_DATADESC_(name,base)
+#define END_BYTESWAP_DATADESC() END_DATADESC()
+
+//-----------------------------------------------------------------------------
+
+template <typename T>
+inline void DataMapAccess(T *ignored, datamap_t **p)
+{
+ *p = &T::m_DataMap;
+}
+
+//-----------------------------------------------------------------------------
+
+class CDatadescGeneratedNameHolder
+{
+public:
+ CDatadescGeneratedNameHolder( const char *pszBase )
+ : m_pszBase(pszBase)
+ {
+ m_nLenBase = strlen( m_pszBase );
+ }
+
+ ~CDatadescGeneratedNameHolder()
+ {
+ for ( int i = 0; i < m_Names.Count(); i++ )
+ {
+ delete m_Names[i];
+ }
+ }
+
+ const char *GenerateName( const char *pszIdentifier )
+ {
+ char *pBuf = new char[m_nLenBase + strlen(pszIdentifier) + 1];
+ strcpy( pBuf, m_pszBase );
+ strcat( pBuf, pszIdentifier );
+ m_Names.AddToTail( pBuf );
+ return pBuf;
+ }
+
+private:
+ const char *m_pszBase;
+ size_t m_nLenBase;
+ CUtlVector<char *> m_Names;
+};
+
+//-----------------------------------------------------------------------------
+
+#include "tier0/memdbgoff.h"
+
+#endif // DATAMAP_H