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.
180 lines
6.8 KiB
180 lines
6.8 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
// $Workfile: $ |
|
// $Date: $ |
|
// |
|
//----------------------------------------------------------------------------- |
|
// $Log: $ |
|
// |
|
// $NoKeywords: $ |
|
//=============================================================================// |
|
#if !defined( CLIENT_CLASS_H ) |
|
#define CLIENT_CLASS_H |
|
#ifdef _WIN32 |
|
#pragma once |
|
#endif |
|
|
|
#include "interface.h" |
|
#include "dt_recv.h" |
|
|
|
//----------------------------------------------------------------------------- |
|
// forward declarations |
|
//----------------------------------------------------------------------------- |
|
|
|
class Vector; |
|
class CMouthInfo; |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// represents a handle used only by the client DLL |
|
//----------------------------------------------------------------------------- |
|
|
|
#include "iclientrenderable.h" |
|
#include "iclientnetworkable.h" |
|
|
|
|
|
class ClientClass; |
|
// Linked list of all known client classes |
|
extern ClientClass *g_pClientClassHead; |
|
|
|
// The serial number that gets passed in is used for ehandles. |
|
typedef IClientNetworkable* (*CreateClientClassFn)( int entnum, int serialNum ); |
|
typedef IClientNetworkable* (*CreateEventFn)(); |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Client side class definition |
|
//----------------------------------------------------------------------------- |
|
class ClientClass |
|
{ |
|
public: |
|
ClientClass( const char *pNetworkName, CreateClientClassFn createFn, CreateEventFn createEventFn, RecvTable *pRecvTable ) |
|
{ |
|
m_pNetworkName = pNetworkName; |
|
m_pCreateFn = createFn; |
|
m_pCreateEventFn= createEventFn; |
|
m_pRecvTable = pRecvTable; |
|
|
|
// Link it in |
|
m_pNext = g_pClientClassHead; |
|
g_pClientClassHead = this; |
|
} |
|
|
|
const char* GetName() |
|
{ |
|
return m_pNetworkName; |
|
} |
|
|
|
public: |
|
CreateClientClassFn m_pCreateFn; |
|
CreateEventFn m_pCreateEventFn; // Only called for event objects. |
|
const char *m_pNetworkName; |
|
RecvTable *m_pRecvTable; |
|
ClientClass *m_pNext; |
|
int m_ClassID; // Managed by the engine. |
|
}; |
|
|
|
#define DECLARE_CLIENTCLASS() \ |
|
virtual int YouForgotToImplementOrDeclareClientClass();\ |
|
virtual ClientClass* GetClientClass();\ |
|
static RecvTable *m_pClassRecvTable; \ |
|
DECLARE_CLIENTCLASS_NOBASE() |
|
|
|
|
|
// This can be used to give all datatables access to protected and private members of the class. |
|
#define ALLOW_DATATABLES_PRIVATE_ACCESS() \ |
|
template <typename T> friend int ClientClassInit(T *); |
|
|
|
|
|
#define DECLARE_CLIENTCLASS_NOBASE ALLOW_DATATABLES_PRIVATE_ACCESS |
|
|
|
// This macro adds a ClientClass to the linked list in g_pClientClassHead (so |
|
// the list can be given to the engine). |
|
// Use this macro to expose your client class to the engine. |
|
// networkName must match the network name of a class registered on the server. |
|
#define IMPLEMENT_CLIENTCLASS(clientClassName, dataTable, serverClassName) \ |
|
INTERNAL_IMPLEMENT_CLIENTCLASS_PROLOGUE(clientClassName, dataTable, serverClassName) \ |
|
static IClientNetworkable* _##clientClassName##_CreateObject( int entnum, int serialNum ) \ |
|
{ \ |
|
clientClassName *pRet = new clientClassName; \ |
|
if ( !pRet ) \ |
|
return 0; \ |
|
pRet->Init( entnum, serialNum ); \ |
|
return pRet; \ |
|
} \ |
|
ClientClass __g_##clientClassName##ClientClass(#serverClassName, \ |
|
_##clientClassName##_CreateObject, \ |
|
NULL,\ |
|
&dataTable::g_RecvTable); |
|
|
|
// Implement a client class and provide a factory so you can allocate and delete it yourself |
|
// (or make it a singleton). |
|
#define IMPLEMENT_CLIENTCLASS_FACTORY(clientClassName, dataTable, serverClassName, factory) \ |
|
INTERNAL_IMPLEMENT_CLIENTCLASS_PROLOGUE(clientClassName, dataTable, serverClassName) \ |
|
ClientClass __g_##clientClassName##ClientClass(#serverClassName, \ |
|
factory, \ |
|
NULL,\ |
|
&dataTable::g_RecvTable); |
|
|
|
// The IMPLEMENT_CLIENTCLASS_DT macros do IMPLEMENT_CLIENT_CLASS and also do BEGIN_RECV_TABLE. |
|
#define IMPLEMENT_CLIENTCLASS_DT(clientClassName, dataTable, serverClassName)\ |
|
IMPLEMENT_CLIENTCLASS(clientClassName, dataTable, serverClassName)\ |
|
BEGIN_RECV_TABLE(clientClassName, dataTable) |
|
|
|
#define IMPLEMENT_CLIENTCLASS_DT_NOBASE(clientClassName, dataTable, serverClassName)\ |
|
IMPLEMENT_CLIENTCLASS(clientClassName, dataTable, serverClassName)\ |
|
BEGIN_RECV_TABLE_NOBASE(clientClassName, dataTable) |
|
|
|
|
|
// Using IMPLEMENT_CLIENTCLASS_EVENT means the engine thinks the entity is an event so the entity |
|
// is responsible for freeing itself. |
|
#define IMPLEMENT_CLIENTCLASS_EVENT(clientClassName, dataTable, serverClassName)\ |
|
INTERNAL_IMPLEMENT_CLIENTCLASS_PROLOGUE(clientClassName, dataTable, serverClassName)\ |
|
static clientClassName __g_##clientClassName; \ |
|
static IClientNetworkable* _##clientClassName##_CreateObject() {return &__g_##clientClassName;}\ |
|
ClientClass __g_##clientClassName##ClientClass(#serverClassName, \ |
|
NULL,\ |
|
_##clientClassName##_CreateObject, \ |
|
&dataTable::g_RecvTable); |
|
|
|
#define IMPLEMENT_CLIENTCLASS_EVENT_DT(clientClassName, dataTable, serverClassName)\ |
|
namespace dataTable {extern RecvTable g_RecvTable;}\ |
|
IMPLEMENT_CLIENTCLASS_EVENT(clientClassName, dataTable, serverClassName)\ |
|
BEGIN_RECV_TABLE(clientClassName, dataTable) |
|
|
|
|
|
// Register a client event singleton but specify a pointer to give to the engine rather than |
|
// have a global instance. This is useful if you're using Initializers and your object's constructor |
|
// uses some other global object (so you must use Initializers so you're constructed afterwards). |
|
#define IMPLEMENT_CLIENTCLASS_EVENT_POINTER(clientClassName, dataTable, serverClassName, ptr)\ |
|
INTERNAL_IMPLEMENT_CLIENTCLASS_PROLOGUE(clientClassName, dataTable, serverClassName)\ |
|
static IClientNetworkable* _##clientClassName##_CreateObject() {return ptr;}\ |
|
ClientClass __g_##clientClassName##ClientClass(#serverClassName, \ |
|
NULL,\ |
|
_##clientClassName##_CreateObject, \ |
|
&dataTable::g_RecvTable); |
|
|
|
#define IMPLEMENT_CLIENTCLASS_EVENT_NONSINGLETON(clientClassName, dataTable, serverClassName)\ |
|
static IClientNetworkable* _##clientClassName##_CreateObject() \ |
|
{ \ |
|
clientClassName *p = new clientClassName; \ |
|
if ( p ) \ |
|
p->Init( -1, 0 ); \ |
|
return p; \ |
|
} \ |
|
ClientClass __g_##clientClassName##ClientClass(#serverClassName, \ |
|
NULL,\ |
|
_##clientClassName##_CreateObject, \ |
|
&dataTable::g_RecvTable); |
|
|
|
|
|
// Used internally.. |
|
#define INTERNAL_IMPLEMENT_CLIENTCLASS_PROLOGUE(clientClassName, dataTable, serverClassName) \ |
|
namespace dataTable {extern RecvTable g_RecvTable;}\ |
|
extern ClientClass __g_##clientClassName##ClientClass;\ |
|
RecvTable* clientClassName::m_pClassRecvTable = &dataTable::g_RecvTable;\ |
|
int clientClassName::YouForgotToImplementOrDeclareClientClass() {return 0;}\ |
|
ClientClass* clientClassName::GetClientClass() {return &__g_##clientClassName##ClientClass;} |
|
|
|
#endif // CLIENT_CLASS_H
|
|
|