//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// // // Purpose: // // $NoKeywords: $ //=============================================================================// #ifndef PREDICTABLE_ENTITY_H #define PREDICTABLE_ENTITY_H #ifdef _WIN32 #pragma once #endif // For introspection #include "tier0/platform.h" #include "predictioncopy.h" #include "shared_classnames.h" #ifndef NO_ENTITY_PREDICTION #define UsePrediction() 1 #else #define UsePrediction() 0 #endif // CLIENT DLL includes #if defined( CLIENT_DLL ) || defined( TOOL_DLL ) #include "iclassmap.h" #include "recvproxy.h" class SendTable; // Game DLL includes #else #include "sendproxy.h" #endif // !CLIENT_DLL #if defined( CLIENT_DLL ) #define DECLARE_NETWORKCLASS() \ DECLARE_CLIENTCLASS() #define DECLARE_NETWORKCLASS_NOBASE() \ DECLARE_CLIENTCLASS_NOBASE() #else #define DECLARE_NETWORKCLASS() \ DECLARE_SERVERCLASS() #define DECLARE_NETWORKCLASS_NOBASE() \ DECLARE_SERVERCLASS_NOBASE() #endif #if defined( CLIENT_DLL ) #ifndef NO_ENTITY_PREDICTION #define DECLARE_PREDICTABLE() \ public: \ static typedescription_t m_PredDesc[]; \ static datamap_t m_PredMap; \ virtual datamap_t *GetPredDescMap( void ); \ template friend datamap_t *PredMapInit(T *) #else #define DECLARE_PREDICTABLE() template friend datamap_t *PredMapInit(T *) #endif #ifndef NO_ENTITY_PREDICTION #define BEGIN_PREDICTION_DATA( className ) \ datamap_t className::m_PredMap = { 0, 0, #className, &BaseClass::m_PredMap }; \ datamap_t *className::GetPredDescMap( void ) { return &m_PredMap; } \ BEGIN_PREDICTION_DATA_GUTS( className ) #define BEGIN_PREDICTION_DATA_NO_BASE( className ) \ datamap_t className::m_PredMap = { 0, 0, #className, NULL }; \ datamap_t *className::GetPredDescMap( void ) { return &m_PredMap; } \ BEGIN_PREDICTION_DATA_GUTS( className ) #define BEGIN_PREDICTION_DATA_GUTS( className ) \ template datamap_t *PredMapInit(T *); \ template <> datamap_t *PredMapInit( className * ); \ namespace className##_PredDataDescInit \ { \ datamap_t *g_PredMapHolder = PredMapInit( (className *)NULL ); /* This can/will be used for some clean up duties later */ \ } \ \ template <> datamap_t *PredMapInit( className * ) \ { \ typedef className classNameTypedef; \ static typedescription_t predDesc[] = \ { \ { FIELD_VOID,0,0,0,0,0,0,0,0}, /* so you can define "empty" tables */ #define END_PREDICTION_DATA() \ }; \ \ if ( sizeof( predDesc ) > sizeof( predDesc[0] ) ) \ { \ classNameTypedef::m_PredMap.dataNumFields = ARRAYSIZE( predDesc ) - 1; \ classNameTypedef::m_PredMap.dataDesc = &predDesc[1]; \ } \ else \ { \ classNameTypedef::m_PredMap.dataNumFields = 1; \ classNameTypedef::m_PredMap.dataDesc = predDesc; \ } \ return &classNameTypedef::m_PredMap; \ } #else #define BEGIN_PREDICTION_DATA( className ) \ template <> inline datamap_t *PredMapInit( className * ) \ { \ if ( 0 ) \ { \ typedef className classNameTypedef; \ typedescription_t predDesc[] = \ { \ { FIELD_VOID,0,0,0,0,0,0,0,0}, #define BEGIN_PREDICTION_DATA_NO_BASE( className ) BEGIN_PREDICTION_DATA( className ) #define END_PREDICTION_DATA() \ }; \ predDesc[0].flags = 0; /* avoid compiler warning of unused data */ \ } \ } #endif #else // nothing, only client has a prediction system #define DECLARE_PREDICTABLE() #define BEGIN_PREDICTION_DATA( className ) #define END_PREDICTION_DATA() #endif #if defined( CLIENT_DLL ) // On the client .dll this creates a mapping between a classname and // a client side class. Probably could be templatized at some point. #define LINK_ENTITY_TO_CLASS( localName, className ) \ static C_BaseEntity *C##className##Factory( void ) \ { \ return static_cast< C_BaseEntity * >( new className ); \ }; \ class C##localName##Foo \ { \ public: \ C##localName##Foo( void ) \ { \ GetClassMap().Add( #localName, #className, sizeof( className ), \ &C##className##Factory ); \ __g_##className##ClientClass.m_pMapClassname = #localName; \ } \ }; \ static C##localName##Foo g_C##localName##Foo; #define LINK_ENTITY_TO_CLASS_CLIENTONLY( localName, className ) \ static C_BaseEntity *C##className##Factory( void ) \ { \ return static_cast< C_BaseEntity * >( new className ); \ }; \ class C##localName##Foo \ { \ public: \ C##localName##Foo( void ) \ { \ GetClassMap().Add( #localName, #className, sizeof( className ), \ &C##className##Factory ); \ } \ }; \ static C##localName##Foo g_C##localName##Foo; #define BEGIN_NETWORK_TABLE( className, tableName ) BEGIN_RECV_TABLE( className, tableName ) #define BEGIN_NETWORK_TABLE_NOBASE( className, tableName ) BEGIN_RECV_TABLE_NOBASE( className, tableName ) #define END_NETWORK_TABLE END_RECV_TABLE #define LINK_ENTITY_TO_CLASS_ALIASED( localName, className ) LINK_ENTITY_TO_CLASS(localName, C_##className ) #define IMPLEMENT_NETWORKCLASS_ALIASED(className, dataTable) \ IMPLEMENT_CLIENTCLASS( C_##className, dataTable, C##className ) #define IMPLEMENT_NETWORKCLASS(className, dataTable) \ IMPLEMENT_CLIENTCLASS(className, dataTable, className) #define IMPLEMENT_NETWORKCLASS_DT(className, dataTable) \ IMPLEMENT_CLIENTCLASS_DT(className, dataTable, className) #define LINK_ENTITY_TO_CLASS_SIMPLE_DERIVED( classNameDerived, classNameBase, dataTableName, entity_name ) \ class C_##classNameDerived : public C_##classNameBase \ { \ public: \ DECLARE_CLASS( C_##classNameDerived, C_##classNameBase ); \ DECLARE_NETWORKCLASS(); \ }; \ IMPLEMENT_NETWORKCLASS_ALIASED( classNameDerived, dataTableName ) \ BEGIN_NETWORK_TABLE( C_##classNameDerived, dataTableName ) \ END_NETWORK_TABLE() \ LINK_ENTITY_TO_CLASS_ALIASED( entity_name, classNameDerived ) #else #define BEGIN_NETWORK_TABLE( className, tableName ) BEGIN_SEND_TABLE( className, tableName ) #define BEGIN_NETWORK_TABLE_NOBASE( className, tableName ) BEGIN_SEND_TABLE_NOBASE( className, tableName ) #define END_NETWORK_TABLE END_SEND_TABLE #define LINK_ENTITY_TO_CLASS_ALIASED( localName, className ) LINK_ENTITY_TO_CLASS(localName, C##className ) #define IMPLEMENT_NETWORKCLASS_ALIASED(className, dataTable) \ IMPLEMENT_SERVERCLASS( C##className, dataTable ) #define IMPLEMENT_NETWORKCLASS(className, dataTable) \ IMPLEMENT_SERVERCLASS(className, dataTable) #define IMPLEMENT_NETWORKCLASS_DT(className, dataTable) \ IMPLEMENT_SERVERCLASS_ST(className, dataTable) #define LINK_ENTITY_TO_CLASS_SIMPLE_DERIVED( classNameDerived, classNameBase, dataTableName, entity_name ) \ class C##classNameDerived : public C##classNameBase \ { \ public: \ DECLARE_CLASS( C##classNameDerived, C##classNameBase ); \ DECLARE_NETWORKCLASS(); \ }; \ IMPLEMENT_NETWORKCLASS_ALIASED( classNameDerived, dataTableName ) \ BEGIN_NETWORK_TABLE( C##classNameDerived, dataTableName ) \ END_NETWORK_TABLE() \ LINK_ENTITY_TO_CLASS_ALIASED( entity_name, classNameDerived ) #endif #endif // PREDICTABLE_ENTITY_H