258 lines
7.9 KiB
C++
258 lines
7.9 KiB
C++
//========= Copyright Valve Corporation, All rights reserved. ============//
|
|
//
|
|
// Purpose:
|
|
//
|
|
// $NoKeywords: $
|
|
//
|
|
//=============================================================================//
|
|
|
|
#ifndef DATATABLE_COMMON_H
|
|
#define DATATABLE_COMMON_H
|
|
|
|
#ifdef _WIN32
|
|
#pragma once
|
|
#endif
|
|
|
|
#include <stddef.h>
|
|
#include "tier0/basetypes.h"
|
|
#include "tier0/dbg.h"
|
|
#include "tier1/strtools.h"
|
|
|
|
#ifdef LINUX
|
|
#undef offsetof
|
|
#define offsetof(s, m) (size_t) & (((s *)0)->m)
|
|
#endif
|
|
|
|
// Max number of properties in a datatable and its children.
|
|
#define MAX_DATATABLES 1024 // must be a power of 2.
|
|
#define MAX_DATATABLE_PROPS 4096
|
|
|
|
#define MAX_ARRAY_ELEMENTS \
|
|
2048 // a network array should have more that 1024 elements
|
|
|
|
#define HIGH_DEFAULT -121121.121121f
|
|
|
|
#define BITS_FULLRES -1 // Use the full resolution of the type being encoded.
|
|
#define BITS_WORLDCOORD -2 // Encode as a world coordinate.
|
|
|
|
#define DT_MAX_STRING_BITS 9
|
|
#define DT_MAX_STRING_BUFFERSIZE \
|
|
(1 << DT_MAX_STRING_BITS) // Maximum length of a string that can be sent.
|
|
|
|
#define STRINGBUFSIZE(className, varName) sizeof(((className *)0)->varName)
|
|
|
|
// Gets the size of a variable in a class.
|
|
#define PROPSIZEOF(className, varName) sizeof(((className *)0)->varName)
|
|
|
|
// SendProp::m_Flags.
|
|
#define SPROP_UNSIGNED (1 << 0) // Unsigned integer data.
|
|
|
|
#define SPROP_COORD \
|
|
(1 << 1) // If this is set, the float/vector is treated like a world
|
|
// coordinate. Note that the bit count is ignored in this case.
|
|
|
|
#define SPROP_NOSCALE \
|
|
(1 << 2) // For floating point, don't scale into range, just take value as
|
|
// is.
|
|
|
|
#define SPROP_ROUNDDOWN \
|
|
(1 << 3) // For floating point, limit high value to range minus one bit
|
|
// unit
|
|
|
|
#define SPROP_ROUNDUP \
|
|
(1 << 4) // For floating point, limit low value to range minus one bit unit
|
|
|
|
#define SPROP_NORMAL \
|
|
(1 << 5) // If this is set, the vector is treated like a normal (only valid
|
|
// for vectors)
|
|
|
|
#define SPROP_EXCLUDE \
|
|
(1 << 6) // This is an exclude prop (not excludED, but it points at another
|
|
// prop to be excluded).
|
|
|
|
#define SPROP_XYZE (1 << 7) // Use XYZ/Exponent encoding for vectors.
|
|
|
|
#define SPROP_INSIDEARRAY \
|
|
(1 << 8) // This tells us that the property is inside an array, so it
|
|
// shouldn't be put into the flattened property list. Its array
|
|
// will point at it when it needs to.
|
|
|
|
#define SPROP_PROXY_ALWAYS_YES \
|
|
(1 << 9) // Set for datatable props using one of the default datatable
|
|
// proxies like SendProxy_DataTableToDataTable that always send
|
|
// the data to all clients.
|
|
|
|
#define SPROP_CHANGES_OFTEN \
|
|
(1 << 10) // this is an often changed field, moved to head of sendtable so
|
|
// it gets a small index
|
|
|
|
#define SPROP_IS_A_VECTOR_ELEM \
|
|
(1 << 11) // Set automatically if SPROP_VECTORELEM is used.
|
|
|
|
#define SPROP_COLLAPSIBLE \
|
|
(1 << 12) // Set automatically if it's a datatable with an offset of 0 that
|
|
// doesn't change the pointer (ie: for all automatically-chained
|
|
// base classes). In this case, it can get rid of this
|
|
// SendPropDataTable altogether and spare the trouble of walking
|
|
// the hierarchy more than necessary.
|
|
|
|
#define SPROP_COORD_MP \
|
|
(1 << 13) // Like SPROP_COORD, but special handling for multiplayer games
|
|
#define SPROP_COORD_MP_LOWPRECISION \
|
|
(1 \
|
|
<< 14) // Like SPROP_COORD, but special handling for multiplayer games
|
|
// where the fractional component only gets a 3 bits instead of 5
|
|
#define SPROP_COORD_MP_INTEGRAL \
|
|
(1 << 15) // SPROP_COORD_MP, but coordinates are rounded to integral
|
|
// boundaries
|
|
|
|
#define SPROP_VARINT \
|
|
SPROP_NORMAL // reuse existing flag so we don't break demo. note you want
|
|
// to include SPROP_UNSIGNED if needed, its more efficient
|
|
|
|
#define SPROP_NUMFLAGBITS_NETWORKED 16
|
|
|
|
// This is server side only, it's used to mark properties whose SendProxy_*
|
|
// functions encode against gpGlobals->tickcount (the only ones that currently
|
|
// do this are
|
|
// m_flAnimTime and m_flSimulationTime. MODs shouldn't need to mess with this
|
|
// probably
|
|
#define SPROP_ENCODED_AGAINST_TICKCOUNT (1 << 16)
|
|
|
|
// See SPROP_NUMFLAGBITS_NETWORKED for the ones which are networked
|
|
#define SPROP_NUMFLAGBITS 17
|
|
|
|
// Used by the SendProp and RecvProp functions to disable debug checks on type
|
|
// sizes.
|
|
#define SIZEOF_IGNORE -1
|
|
|
|
// Use this to extern send and receive datatables, and reference them.
|
|
#define EXTERN_SEND_TABLE(tableName) \
|
|
namespace tableName { \
|
|
extern SendTable g_SendTable; \
|
|
}
|
|
#define EXTERN_RECV_TABLE(tableName) \
|
|
namespace tableName { \
|
|
extern RecvTable g_RecvTable; \
|
|
}
|
|
|
|
#define REFERENCE_SEND_TABLE(tableName) tableName::g_SendTable
|
|
#define REFERENCE_RECV_TABLE(tableName) tableName::g_RecvTable
|
|
|
|
class SendProp;
|
|
|
|
// The day we do this, we break all mods until they recompile.
|
|
//#define SUPPORTS_INT64
|
|
|
|
typedef enum {
|
|
DPT_Int = 0,
|
|
DPT_Float,
|
|
DPT_Vector,
|
|
DPT_VectorXY, // Only encodes the XY of a vector, ignores Z
|
|
DPT_String,
|
|
DPT_Array, // An array of the base types (can't be of datatables).
|
|
DPT_DataTable,
|
|
#if 0 // We can't ship this since it changes the size of DTVariant to be 20
|
|
// bytes instead of 16 and that breaks MODs!!!
|
|
DPT_Quaternion,
|
|
#endif
|
|
|
|
#ifdef SUPPORTS_INT64
|
|
DPT_Int64,
|
|
#endif
|
|
|
|
DPT_NUMSendPropTypes
|
|
|
|
} SendPropType;
|
|
|
|
class DVariant {
|
|
public:
|
|
DVariant() { m_Type = DPT_Float; }
|
|
DVariant(float val) {
|
|
m_Type = DPT_Float;
|
|
m_Float = val;
|
|
}
|
|
|
|
const char *ToString() {
|
|
static char text[128];
|
|
|
|
switch (m_Type) {
|
|
case DPT_Int:
|
|
Q_snprintf(text, sizeof(text), "%i", m_Int);
|
|
break;
|
|
case DPT_Float:
|
|
Q_snprintf(text, sizeof(text), "%.3f", m_Float);
|
|
break;
|
|
case DPT_Vector:
|
|
Q_snprintf(text, sizeof(text), "(%.3f,%.3f,%.3f)", m_Vector[0],
|
|
m_Vector[1], m_Vector[2]);
|
|
break;
|
|
case DPT_VectorXY:
|
|
Q_snprintf(text, sizeof(text), "(%.3f,%.3f)", m_Vector[0],
|
|
m_Vector[1]);
|
|
break;
|
|
#if 0 // We can't ship this since it changes the size of DTVariant to be 20
|
|
// bytes instead of 16 and that breaks MODs!!!
|
|
case DPT_Quaternion :
|
|
Q_snprintf( text, sizeof(text), "(%.3f,%.3f,%.3f %.3f)",
|
|
m_Vector[0], m_Vector[1], m_Vector[2], m_Vector[3] );
|
|
break;
|
|
#endif
|
|
case DPT_String:
|
|
if (m_pString)
|
|
return m_pString;
|
|
else
|
|
return "NULL";
|
|
break;
|
|
case DPT_Array:
|
|
Q_snprintf(text, sizeof(text), "Array");
|
|
break;
|
|
case DPT_DataTable:
|
|
Q_snprintf(text, sizeof(text), "DataTable");
|
|
break;
|
|
#ifdef SUPPORTS_INT64
|
|
case DPT_Int64:
|
|
Q_snprintf(text, sizeof(text), "%I64d", m_Int64);
|
|
break;
|
|
#endif
|
|
default:
|
|
Q_snprintf(text, sizeof(text), "DVariant type %i unknown",
|
|
m_Type);
|
|
break;
|
|
}
|
|
|
|
return text;
|
|
}
|
|
|
|
union {
|
|
float m_Float;
|
|
int m_Int;
|
|
const char *m_pString;
|
|
void *m_pData; // For DataTables.
|
|
#if 0 // We can't ship this since it changes the size of DTVariant to be 20
|
|
// bytes instead of 16 and that breaks MODs!!!
|
|
float m_Vector[4];
|
|
#else
|
|
float m_Vector[3];
|
|
#endif
|
|
|
|
#ifdef SUPPORTS_INT64
|
|
int64 m_Int64;
|
|
#endif
|
|
};
|
|
SendPropType m_Type;
|
|
};
|
|
|
|
// This can be used to set the # of bits used to transmit a number between 0 and
|
|
// nMaxElements-1.
|
|
inline int NumBitsForCount(int nMaxElements) {
|
|
int nBits = 0;
|
|
while (nMaxElements > 0) {
|
|
++nBits;
|
|
nMaxElements >>= 1;
|
|
}
|
|
return nBits;
|
|
}
|
|
|
|
#endif // DATATABLE_COMMON_H
|