2025-05-17 14:18:30 -04:00
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
2010-07-22 01:46:14 -05:00
//
// Purpose:
//
//=============================================================================//
# ifndef SHAREDVAR_H
# define SHAREDVAR_H
# ifdef _WIN32
# pragma once
# endif
# include "convar.h"
# include "ispsharedmemory.h"
# include "basehandle.h"
# include "isaverestore.h"
# pragma warning( disable : 4284 ) // warning C4284: return type for 'CNetworkVarT<int>::operator ->' is 'int *' (ie; not a UDT or reference to a UDT. Will produce errors if applied using infix notation)
# if defined( GAME_DLL )
static int Server_EHandleToInt ( const EHANDLE & hIn )
{
if ( hIn . Get ( ) )
{
int iSerialNum = hIn . GetSerialNumber ( ) & ( 1 < < NUM_NETWORKED_EHANDLE_SERIAL_NUMBER_BITS ) - 1 ;
return ( hIn . GetEntryIndex ( ) | ( iSerialNum < < MAX_EDICT_BITS ) ) ;
}
else
{
return INVALID_NETWORKED_EHANDLE_VALUE ;
}
}
# endif
# if defined( CLIENT_DLL )
static EHANDLE Client_IntToEHandle ( int iIn )
{
if ( iIn = = INVALID_NETWORKED_EHANDLE_VALUE )
{
return INVALID_EHANDLE_INDEX ;
}
else
{
int iEntity = iIn & ( ( 1 < < MAX_EDICT_BITS ) - 1 ) ;
int iSerialNum = iIn > > MAX_EDICT_BITS ;
EHANDLE hOut ;
hOut . Init ( iEntity , iSerialNum ) ;
return hOut ;
}
}
# endif
class CSharedVarSaveDataOps ;
// Templated save/restore functions for shared vars (add specializations as needed)
template < class Type >
static void SharedVar_Save ( ISave * pSave , Type * pValue , int iCount = 1 )
{
int iNumBytes = sizeof ( Type ) * iCount ;
pSave - > WriteInt ( & iNumBytes ) ;
pSave - > WriteData ( ( char * ) ( ( void * ) ( pValue ) ) , iNumBytes ) ;
}
template < class Type >
static void SharedVar_Restore ( IRestore * pRestore , Type * pValue )
{
int iNumBytes = pRestore - > ReadInt ( ) ;
pRestore - > ReadData ( ( char * ) ( ( void * ) ( pValue ) ) , iNumBytes , 0 ) ;
}
template < class Type >
static bool SharedVar_IsEmpty ( Type * pValue , int iCount = 1 )
{
char * pChar = ( char * ) ( ( void * ) ( pValue ) ) ;
int iNumBytes = sizeof ( Type ) * iCount ;
for ( int i = 0 ; i < iNumBytes ; + + i )
{
if ( pChar [ i ] ! = NULL )
{
return false ;
}
}
return true ;
}
template < class Type >
static void SharedVar_MakeEmpty ( Type * pValue , int iCount = 1 )
{
memset ( pValue , 0 , sizeof ( Type ) * iCount ) ;
}
// EHANDLE Save/Restore specializations
template < >
TEMPLATE_STATIC void SharedVar_Save < EHANDLE > ( ISave * pSave , EHANDLE * pValue , int iCount )
{
pSave - > WriteInt ( & iCount ) ;
pSave - > WriteEHandle ( pValue , iCount ) ;
}
template < >
TEMPLATE_STATIC void SharedVar_Restore < EHANDLE > ( IRestore * pRestore , EHANDLE * pValue )
{
int iCount = pRestore - > ReadInt ( ) ;
pRestore - > ReadEHandle ( pValue , iCount ) ;
}
// UtlVector Save/Restore specializations
template < class Type > void SharedVar_SaveUtlVector ( ISave * pSave , CUtlVector < Type > * pValue , int iCount = 1 )
{
Assert ( iCount = = 1 ) ;
int iNumBytes = sizeof ( Type ) * pValue - > Count ( ) ;
pSave - > WriteInt ( & iNumBytes ) ;
pSave - > WriteData ( ( char * ) ( ( void * ) ( pValue - > Base ( ) ) ) , iNumBytes ) ;
}
template < class Type > void SharedVar_RestoreUtlVector ( IRestore * pRestore , CUtlVector < Type > * pValue )
{
int iNumBytes = pRestore - > ReadInt ( ) ;
pValue - > SetCount ( iNumBytes / sizeof ( Type ) ) ;
pRestore - > ReadData ( ( char * ) ( ( void * ) ( pValue - > Base ( ) ) ) , iNumBytes , 0 ) ;
}
template < class Type >
static bool SharedVar_IsEmptyUtlVector ( CUtlVector < Type > * pValue , int iCount = 1 )
{
Assert ( iCount = = 1 ) ;
return ( pValue - > Count ( ) = = 0 ) ;
}
template < class Type >
static void SharedVar_MakeEmptyUtlVector ( CUtlVector < Type > * pValue , int iCount = 1 )
{
Assert ( iCount = = 1 ) ;
pValue - > SetCount ( 0 ) ;
}
abstract_class ISharedVarBase
{
private :
virtual void _Save ( ISave * pSave ) = 0 ;
virtual void _Restore ( IRestore * pRestore ) = 0 ;
virtual bool _IsEmpty ( void ) = 0 ;
virtual void _MakeEmpty ( void ) = 0 ;
public :
friend class CSharedVarSaveDataOps ;
} ;
template < class Type , class Changer >
class CSharedVarBase : public ISharedVarBase
{
public :
CSharedVarBase ( void )
{
m_pSharedMemory = NULL ;
m_pValue = NULL ;
}
~ CSharedVarBase ( void )
{
m_pSharedMemory - > Release ( ) ;
m_pSharedMemory = NULL ;
m_pValue = NULL ;
}
void Initialize ( char * pchName , int iEntNum )
{
Assert ( ! m_pSharedMemory & & ! m_pValue ) ;
m_pSharedMemory = engine - > GetSinglePlayerSharedMemorySpace ( pchName , iEntNum ) ;
m_pSharedMemory - > Init ( sizeof ( Type ) ) ;
m_pValue = ( Type * ) m_pSharedMemory - > Base ( ) ;
}
# if defined( GAME_DLL )
// Data can only be set on the server
template < class C >
const Type & operator = ( const C & val )
{
return Set ( static_cast < const Type > ( val ) ) ;
}
template < class C >
const Type & operator = ( const CNetworkVarBase < C , Changer > & val )
{
return Set ( static_cast < const Type > ( * val . m_pValue ) ) ;
}
const Type & Set ( const Type & val )
{
* m_pValue = val ;
return * m_pValue ;
}
template < class C >
const Type & operator + = ( const C & val )
{
return Set ( * m_pValue + static_cast < const Type > ( val ) ) ;
}
template < class C >
const Type & operator - = ( const C & val )
{
return Set ( * m_pValue - static_cast < const Type > ( val ) ) ;
}
template < class C >
const Type & operator / = ( const C & val )
{
return Set ( * m_pValue / static_cast < const Type > ( val ) ) ;
}
template < class C >
const Type & operator * = ( const C & val )
{
return Set ( * m_pValue * static_cast < const Type > ( val ) ) ;
}
template < class C >
const Type & operator ^ = ( const C & val )
{
return Set ( * m_pValue ^ static_cast < const Type > ( val ) ) ;
}
template < class C >
const Type & operator | = ( const C & val )
{
return Set ( * m_pValue | static_cast < const Type > ( val ) ) ;
}
const Type & operator + + ( )
{
return ( * this + = 1 ) ;
}
Type operator - - ( )
{
return ( * this - = 1 ) ;
}
Type operator + + ( int ) // postfix version..
{
Type val = * m_pValue ;
( * this + = 1 ) ;
return val ;
}
Type operator - - ( int ) // postfix version..
{
Type val = * m_pValue ;
( * this - = 1 ) ;
return val ;
}
// For some reason the compiler only generates type conversion warnings for this operator when used like
// CNetworkVarBase<unsigned char> = 0x1
// (it warns about converting from an int to an unsigned char).
template < class C >
const Type & operator & = ( const C & val )
{
return Set ( * m_pValue & static_cast < const Type > ( val ) ) ;
}
operator Type & ( )
{
return * m_pValue ;
}
Type & GetForModify ( )
{
return * m_pValue ;
}
Type * operator - > ( )
{
return m_pValue ;
}
# endif
operator const Type & ( ) const
{
return * m_pValue ;
}
const Type & Get ( ) const
{
return * m_pValue ;
}
const Type * operator - > ( ) const
{
return m_pValue ;
}
private :
virtual void _Save ( ISave * pSave ) { SharedVar_Save < Type > ( pSave , m_pValue ) ; }
virtual void _Restore ( IRestore * pRestore ) { SharedVar_Restore < Type > ( pRestore , m_pValue ) ; }
virtual bool _IsEmpty ( void ) { return SharedVar_IsEmpty < Type > ( m_pValue ) ; }
virtual void _MakeEmpty ( void ) { SharedVar_MakeEmpty < Type > ( m_pValue ) ; }
public :
ISPSharedMemory * m_pSharedMemory ;
Type * m_pValue ;
} ;
// Shared color wrapper.
template < class Type , class Changer >
class CSharedColor32Base : public CSharedVarBase < Type , Changer >
{
public :
# if defined( GAME_DLL )
// Data can only be set on the server
inline void Init ( byte rVal , byte gVal , byte bVal )
{
SetR ( rVal ) ;
SetG ( gVal ) ;
SetB ( bVal ) ;
}
inline void Init ( byte rVal , byte gVal , byte bVal , byte aVal )
{
SetR ( rVal ) ;
SetG ( gVal ) ;
SetB ( bVal ) ;
SetA ( aVal ) ;
}
const Type & operator = ( const Type & val )
{
return Set ( val ) ;
}
const Type & operator = ( const CSharedColor32Base < Type , Changer > & val )
{
return CSharedVarBase < Type , Changer > : : Set ( * val . m_pValue ) ;
}
inline void SetR ( byte val ) { SetVal ( CSharedColor32Base < Type , Changer > : : m_pValue - > r , val ) ; }
inline void SetG ( byte val ) { SetVal ( CSharedColor32Base < Type , Changer > : : m_pValue - > g , val ) ; }
inline void SetB ( byte val ) { SetVal ( CSharedColor32Base < Type , Changer > : : m_pValue - > b , val ) ; }
inline void SetA ( byte val ) { SetVal ( CSharedColor32Base < Type , Changer > : : m_pValue - > a , val ) ; }
# endif
inline byte GetR ( ) const { return CSharedColor32Base < Type , Changer > : : m_pValue - > r ; }
inline byte GetG ( ) const { return CSharedColor32Base < Type , Changer > : : m_pValue - > g ; }
inline byte GetB ( ) const { return CSharedColor32Base < Type , Changer > : : m_pValue - > b ; }
inline byte GetA ( ) const { return CSharedColor32Base < Type , Changer > : : m_pValue - > a ; }
# if defined( GAME_DLL )
// Data can only be set on the server
private :
inline void SetVal ( byte & out , const byte & in )
{
out = in ;
}
# endif
} ;
// Shared vector wrapper.
template < class Type , class Changer >
class CSharedVectorBase : public CSharedVarBase < Type , Changer >
{
public :
# if defined( GAME_DLL )
// Data can only be set on the server
inline void Init ( float ix = 0 , float iy = 0 , float iz = 0 )
{
SetX ( ix ) ;
SetY ( iy ) ;
SetZ ( iz ) ;
}
const Type & operator = ( const Type & val )
{
return CSharedVarBase < Type , Changer > : : Set ( val ) ;
}
const Type & operator = ( const CSharedVectorBase < Type , Changer > & val )
{
return CSharedVarBase < Type , Changer > : : Set ( * val . m_pValue ) ;
}
inline void SetX ( float val ) { SetVal ( CSharedVectorBase < Type , Changer > : : m_pValue - > x , val ) ; }
inline void SetY ( float val ) { SetVal ( CSharedVectorBase < Type , Changer > : : m_pValue - > y , val ) ; }
inline void SetZ ( float val ) { SetVal ( CSharedVectorBase < Type , Changer > : : m_pValue - > z , val ) ; }
inline void Set ( int i , float val ) { SetVal ( ( * CSharedVectorBase < Type , Changer > : : m_pValue ) [ i ] , val ) ; }
inline float & operator [ ] ( int i ) { return ( * CSharedVectorBase < Type , Changer > : : m_pValue ) [ i ] ; }
const Type & operator * = ( float val )
{
return CSharedVarBase < Type , Changer > : : Set ( ( * CSharedVectorBase < Type , Changer > : : m_pValue ) * val ) ;
}
# endif
inline float GetX ( ) const { return CSharedVectorBase < Type , Changer > : : m_pValue - > x ; }
inline float GetY ( ) const { return CSharedVectorBase < Type , Changer > : : m_pValue - > y ; }
inline float GetZ ( ) const { return CSharedVectorBase < Type , Changer > : : m_pValue - > z ; }
inline const float & operator [ ] ( int i ) const { return ( * CSharedVectorBase < Type , Changer > : : m_pValue ) [ i ] ; }
bool operator = = ( const Type & val ) const
{
return ( * CSharedVectorBase < Type , Changer > : : m_pValue ) = = ( Type ) val ;
}
bool operator ! = ( const Type & val ) const
{
return ( * CSharedVectorBase < Type , Changer > : : m_pValue ) ! = ( Type ) val ;
}
const Type operator + ( const Type & val ) const
{
return ( * CSharedVectorBase < Type , Changer > : : m_pValue ) + val ;
}
const Type operator - ( const Type & val ) const
{
return ( * CSharedVectorBase < Type , Changer > : : m_pValue ) - val ;
}
const Type operator * ( const Type & val ) const
{
return ( * CSharedVectorBase < Type , Changer > : : m_pValue ) * val ;
}
const Type operator * ( float val ) const
{
return ( * CSharedVectorBase < Type , Changer > : : m_pValue ) * val ;
}
const Type operator / ( const Type & val ) const
{
return ( * CSharedVectorBase < Type , Changer > : : m_pValue ) / val ;
}
# if defined( GAME_DLL )
// Data can only be set on the server
private :
inline void SetVal ( float & out , float in )
{
out = in ;
}
# endif
} ;
// Shared quaternion wrapper.
template < class Type , class Changer >
class CSharedQuaternionBase : public CSharedVarBase < Type , Changer >
{
public :
# if defined( GAME_DLL )
// Data can only be set on the server
inline void Init ( float ix = 0 , float iy = 0 , float iz = 0 , float iw = 0 )
{
SetX ( ix ) ;
SetY ( iy ) ;
SetZ ( iz ) ;
SetZ ( iw ) ;
}
const Type & operator = ( const Type & val )
{
return CSharedVarBase < Type , Changer > : : Set ( val ) ;
}
const Type & operator = ( const CSharedQuaternionBase < Type , Changer > & val )
{
return CSharedVarBase < Type , Changer > : : Set ( * val . m_pValue ) ;
}
const Type & operator * = ( float val )
{
return CSharedVarBase < Type , Changer > : : Set ( ( * CSharedQuaternionBase < Type , Changer > : : m_pValue ) * val ) ;
}
inline void SetX ( float val ) { SetVar ( CSharedQuaternionBase < Type , Changer > : : m_pValue - > x , val ) ; }
inline void SetY ( float val ) { SetVar ( CSharedQuaternionBase < Type , Changer > : : m_pValue - > y , val ) ; }
inline void SetZ ( float val ) { SetVar ( CSharedQuaternionBase < Type , Changer > : : m_pValue - > z , val ) ; }
inline void SetW ( float val ) { SetVar ( CSharedQuaternionBase < Type , Changer > : : m_pValue - > w , val ) ; }
inline void Set ( int i , float val ) { SetVar ( ( * CSharedQuaternionBase < Type , Changer > : : m_pValue ) [ i ] , val ) ; }
inline float & operator [ ] ( int i ) { return ( * CSharedQuaternionBase < Type , Changer > : : m_pValue ) [ i ] ; }
# endif
inline float GetX ( ) const { return CSharedQuaternionBase < Type , Changer > : : m_pValue - > x ; }
inline float GetY ( ) const { return CSharedQuaternionBase < Type , Changer > : : m_pValue - > y ; }
inline float GetZ ( ) const { return CSharedQuaternionBase < Type , Changer > : : m_pValue - > z ; }
inline float GetW ( ) const { return CSharedQuaternionBase < Type , Changer > : : m_pValue - > w ; }
inline const float & operator [ ] ( int i ) const { return ( * CSharedQuaternionBase < Type , Changer > : : m_pValue ) [ i ] ; }
bool operator = = ( const Type & val ) const
{
return ( * CSharedQuaternionBase < Type , Changer > : : m_pValue ) = = ( Type ) val ;
}
bool operator ! = ( const Type & val ) const
{
return ( * CSharedQuaternionBase < Type , Changer > : : m_pValue ) ! = ( Type ) val ;
}
const Type operator + ( const Type & val ) const
{
return ( * CSharedQuaternionBase < Type , Changer > : : m_pValue ) + val ;
}
const Type operator - ( const Type & val ) const
{
return ( * CSharedQuaternionBase < Type , Changer > : : m_pValue ) - val ;
}
const Type operator * ( const Type & val ) const
{
return ( * CSharedQuaternionBase < Type , Changer > : : m_pValue ) * val ;
}
const Type operator * ( float val ) const
{
return ( * CSharedQuaternionBase < Type , Changer > : : m_pValue ) * val ;
}
const Type operator / ( const Type & val ) const
{
return ( * CSharedQuaternionBase < Type , Changer > : : m_pValue ) / val ;
}
# if defined( GAME_DLL )
// Data can only be set on the server
private :
inline void SetVar ( float & out , float in )
{
out = in ;
}
# endif
} ;
// Prevent Shared Vars from using handle templates without the handle wrapper
template < class Type , class Changer >
class CSharedVarBase < CHandle < Type > , Changer > : public ISharedVarBase
{
public :
CSharedVarBase ( void )
{
m_pSharedMemory = NULL ;
m_pValue = NULL ;
}
~ CSharedVarBase ( void )
{
m_pSharedMemory - > Release ( ) ;
m_pSharedMemory = NULL ;
m_pValue = NULL ;
}
protected :
virtual void Shared_Handle_Vars_Must_Use_CSharedHandle_Or_CSharedHandleArray ( ) = 0 ;
public :
ISPSharedMemory * m_pSharedMemory ;
CHandle < Type > * m_pValue ;
} ;
// Prevent Shared Vars from using handle templates without the handle wrapper
template < class Changer >
class CSharedVarBase < CBaseHandle , Changer > : public ISharedVarBase
{
public :
CSharedVarBase ( void )
{
m_pSharedMemory = NULL ;
m_pValue = NULL ;
}
~ CSharedVarBase ( void )
{
m_pSharedMemory - > Release ( ) ;
m_pSharedMemory = NULL ;
m_pValue = NULL ;
}
protected :
virtual void Shared_Handle_Vars_Must_Use_CSharedHandle_Or_CSharedHandleArray ( ) = 0 ;
public :
ISPSharedMemory * m_pSharedMemory ;
CBaseHandle * m_pValue ;
} ;
// Shared handle wrapper.
template < class Type , class Changer >
class CSharedHandleBase : public CSharedVarBase < EHANDLE , Changer >
{
public :
virtual void Shared_Handle_Vars_Must_Use_CSharedHandle_Or_CSharedHandleArray ( ) { }
void Initialize ( char * pchName , int iEntNum )
{
Assert ( ! this - > m_pSharedMemory & & ! this - > m_pValue ) ;
this - > m_pSharedMemory = engine - > GetSinglePlayerSharedMemorySpace ( pchName , iEntNum ) ;
this - > m_pSharedMemory - > Init ( sizeof ( EHANDLE ) + sizeof ( int ) ) ; // Also allocate memory for the int that converts to a Client handle
this - > m_pValue = ( EHANDLE * ) this - > m_pSharedMemory - > Base ( ) ;
m_piClientIndex = ( int * ) ( ( void * ) ( this - > m_pValue + 1 ) ) ;
}
bool operator ! ( ) const
{
return ! GetHandle_Internal ( ) - > Get ( ) ;
}
# if defined( GAME_DLL )
// Data can only be set on the server
const Type * operator = ( const Type * val )
{
return Set ( val ) ;
}
const Type & operator = ( const CSharedHandleBase < Type , Changer > & val )
{
const EHANDLE & handle = CSharedVarBase < EHANDLE , Changer > : : Set ( * val . m_pValue ) ;
return * ( const Type * ) handle . Get ( ) ;
}
const Type * Set ( const Type * val )
{
( * CSharedHandleBase < Type , Changer > : : m_pValue ) = val ;
// Store the int that we'll need to translate to the EHandle on the client
* m_piClientIndex = Server_EHandleToInt ( * CSharedHandleBase < Type , Changer > : : m_pValue ) ;
return val ;
}
# endif
operator const Type * ( ) const
{
return Get_Internal ( ) ;
}
const Type * Get ( ) const
{
return Get_Internal ( ) ;
}
const Type * operator - > ( ) const
{
return Get_Internal ( ) ;
}
bool operator = = ( const Type * val ) const
{
return Get_Internal ( ) = = val ;
}
bool operator ! = ( const Type * val ) const
{
return Get_Internal ( ) ! = val ;
}
private :
EHANDLE GetHandle_Internal ( ) const
{
# if defined( GAME_DLL )
// Server can get the handle directly
return ( * CSharedHandleBase < Type , Changer > : : m_pValue ) ;
# else
// Client needs to get the handle translated from the stroed int
EHANDLE hClient = Client_IntToEHandle ( * m_piClientIndex ) ;
return hClient ;
# endif
}
Type * Get_Internal ( ) const
{
return static_cast < Type * > ( GetHandle_Internal ( ) . Get ( ) ) ;
}
void UpdateClientIndex ( void )
{
* m_piClientIndex = Server_EHandleToInt ( * ( CSharedHandleBase < Type , Changer > : : m_pValue ) ) ;
}
virtual void _Save ( ISave * pSave )
{
SharedVar_Save < EHANDLE > ( pSave , this - > m_pValue ) ;
}
virtual void _Restore ( IRestore * pRestore )
{
SharedVar_Restore < EHANDLE > ( pRestore , this - > m_pValue ) ;
UpdateClientIndex ( ) ;
}
virtual bool _IsEmpty ( void )
{
return SharedVar_IsEmpty < EHANDLE > ( this - > m_pValue ) ;
}
virtual void _MakeEmpty ( void )
{
SharedVar_MakeEmpty < EHANDLE > ( this - > m_pValue ) ;
}
public :
int * m_piClientIndex ; // Pointer to ints for Client handle translations
} ;
// Shared array wrapper.
template < class Type , class Changer >
class CSharedArrayBase : public CSharedVarBase < Type , Changer >
{
public :
CSharedArrayBase ( void )
{
m_iCount = 0 ;
}
void Initialize ( char * pchName , int iEntNum , int iCount )
{
Assert ( ! this - > m_pSharedMemory & & ! ( CSharedArrayBase < Type , Changer > : : m_pValue ) & & iCount > 0 ) ;
m_iCount = iCount ;
this - > m_pSharedMemory = engine - > GetSinglePlayerSharedMemorySpace ( pchName , iEntNum ) ;
this - > m_pSharedMemory - > Init ( sizeof ( Type ) * m_iCount ) ;
CSharedArrayBase < Type , Changer > : : m_pValue = ( Type * ) this - > m_pSharedMemory - > Base ( ) ;
}
const int & Count ( ) const
{
return m_iCount ;
}
const Type * Get ( ) const
{
return CSharedArrayBase < Type , Changer > : : m_pValue ;
}
const Type & Get ( int i ) const
{
Assert ( i > = 0 & & i < m_iCount ) ;
return CSharedArrayBase < Type , Changer > : : m_pValue [ i ] ;
}
const Type & operator [ ] ( int i ) const
{
return Get ( i ) ;
}
# if defined( GAME_DLL )
// Data can only be set on the server
Type & operator [ ] ( int i )
{
return GetForModify ( i ) ;
}
Type & GetForModify ( int i )
{
Assert ( i > = 0 & & i < m_iCount ) ;
return CSharedArrayBase < Type , Changer > : : m_pValue [ i ] ;
}
void Set ( int i , const Type & val )
{
Assert ( i > = 0 & & i < m_iCount ) ;
CSharedArrayBase < Type , Changer > : : m_pValue [ i ] = val ;
}
# endif
private :
virtual void _Save ( ISave * pSave )
{
SharedVar_Save < Type > ( pSave , CSharedArrayBase < Type , Changer > : : m_pValue , m_iCount ) ;
}
virtual void _Restore ( IRestore * pRestore )
{
SharedVar_Restore < Type > ( pRestore , CSharedArrayBase < Type , Changer > : : m_pValue ) ;
}
virtual bool _IsEmpty ( void )
{
return SharedVar_IsEmpty < Type > ( CSharedArrayBase < Type , Changer > : : m_pValue , m_iCount ) ;
}
virtual void _MakeEmpty ( void )
{
SharedVar_MakeEmpty < Type > ( CSharedArrayBase < Type , Changer > : : m_pValue , m_iCount ) ;
}
public :
int m_iCount ;
} ;
// Shared handle array wrapper.
template < class Type , class Changer >
class CSharedHandleArrayBase : public CSharedArrayBase < EHANDLE , Changer >
{
public :
virtual void Shared_Handle_Vars_Must_Use_CSharedHandle_Or_CSharedHandleArray ( ) { }
void Initialize ( char * pchName , int iEntNum , int iCount )
{
Assert ( ! this - > m_pSharedMemory & & ! ( CSharedHandleArrayBase < Type , Changer > : : m_pValue ) & & iCount > 0 ) ;
this - > m_iCount = iCount ;
this - > m_pSharedMemory = engine - > GetSinglePlayerSharedMemorySpace ( pchName , iEntNum ) ;
this - > m_pSharedMemory - > Init ( sizeof ( EHANDLE ) * this - > m_iCount + sizeof ( int ) * this - > m_iCount ) ; // Also allocate memory for the ints that convert to Client handles
this - > m_pValue = ( EHANDLE * ) this - > m_pSharedMemory - > Base ( ) ;
m_piClientIndex = ( int * ) ( ( void * ) ( CSharedHandleArrayBase < Type , Changer > : : m_pValue + this - > m_iCount ) ) ;
}
const int & Count ( ) const
{
return this - > m_iCount ;
}
const Type & Get ( int i ) const
{
Assert ( i > = 0 & & i < this - > m_iCount ) ;
return Get_Internal ( i ) ;
}
const Type * operator [ ] ( int i ) const
{
return Get_Internal ( i ) ;
}
# if defined( GAME_DLL )
// Data can only be set on the server
const Type * Set ( int i , const Type * val )
{
Assert ( i > = 0 & & i < this - > m_iCount ) ;
CSharedHandleArrayBase < Type , Changer > : : m_pValue [ i ] = val ;
// Store the int that we'll need to translate to the EHandle on the client
m_piClientIndex [ i ] = Server_EHandleToInt ( CSharedHandleArrayBase < Type , Changer > : : m_pValue [ i ] ) ;
return val ;
}
# endif
private :
EHANDLE GetHandle_Internal ( int i ) const
{
# if defined( GAME_DLL )
// Server can get the handle directly
return CSharedHandleArrayBase < Type , Changer > : : m_pValue [ i ] ;
# else
// Client needs to get the handle translated from the stroed int
EHANDLE hClient = Client_IntToEHandle ( m_piClientIndex [ i ] ) ;
return hClient ;
# endif
}
Type * Get_Internal ( int i ) const
{
return static_cast < Type * > ( GetHandle_Internal ( i ) . Get ( ) ) ;
}
private :
void UpdateClientIndices ( void )
{
for ( int i = 0 ; i < this - > m_iConcept ; + + i )
{
m_piClientIndex [ i ] = Server_EHandleToInt ( CSharedHandleBase < Type , Changer > : : m_pValue [ i ] ) ;
}
}
virtual void _Restore ( IRestore * pRestore )
{
SharedVar_Restore < EHANDLE > ( pRestore , CSharedHandleArrayBase < Type , Changer > : : m_pValue ) ;
UpdateClientIndices ( ) ;
}
public :
int * m_piClientIndex ; // Pointer to ints for Client handle translations
} ;
// Prevent Shared Vars from using UtlVector templates without the UtlVector wrapper
template < class Type , class Changer >
class CSharedVarBase < CUtlVector < Type > , Changer > : public ISharedVarBase
{
public :
CSharedVarBase ( void )
{
m_pSharedMemory = NULL ;
m_pValue = NULL ;
}
~ CSharedVarBase ( void )
{
m_pSharedMemory - > Release ( ) ;
m_pSharedMemory = NULL ;
m_pValue = NULL ;
}
protected :
virtual void Shared_CUtlVector_Vars_Must_Use_CSharedUtlVector ( ) = 0 ;
public :
ISPSharedMemory * m_pSharedMemory ;
CUtlVector < Type > * m_pValue ;
} ;
// Shared UtlVector wrapper.
template < class Type , class Changer >
class CSharedUtlVectorBase : public CSharedVarBase < CUtlVector < Type > , Changer >
{
public :
void Initialize ( char * pchName , int iEntNum )
{
Assert ( ! this - > m_pSharedMemory & & ! ( CSharedUtlVectorBase < Type , Changer > : : m_pValue ) ) ;
this - > m_pSharedMemory = engine - > GetSinglePlayerSharedMemorySpace ( pchName , iEntNum ) ;
this - > m_pSharedMemory - > Init ( sizeof ( CUtlVector < Type > ) ) ;
CSharedUtlVectorBase < Type , Changer > : : m_pValue = ( CUtlVector < Type > * ) this - > m_pSharedMemory - > Base ( ) ;
}
# if defined( GAME_DLL )
// Data can only be set on the server
operator CUtlVector < Type > & ( )
{
return * CSharedUtlVectorBase < Type , Changer > : : m_pValue ;
}
CUtlVector < Type > & GetForModify ( )
{
return * CSharedUtlVectorBase < Type , Changer > : : m_pValue ;
}
CUtlVector < Type > * operator - > ( )
{
return CSharedUtlVectorBase < Type , Changer > : : m_pValue ;
}
Type & operator [ ] ( int i )
{
return GetForModify ( i ) ;
}
Type & GetForModify ( int i )
{
Assert ( i > = 0 & & i < ( CSharedUtlVectorBase < Type , Changer > : : m_pValue ) - > Count ( ) ) ;
return ( * CSharedUtlVectorBase < Type , Changer > : : m_pValue ) [ i ] ;
}
void Set ( int i , const Type & val )
{
Assert ( i > = 0 & & i < ( CSharedUtlVectorBase < Type , Changer > : : m_pValue ) - > Count ( ) ) ;
( * CSharedUtlVectorBase < Type , Changer > : : m_pValue ) [ i ] = val ;
}
# endif
operator const CUtlVector < Type > & ( ) const
{
return * CSharedUtlVectorBase < Type , Changer > : : m_pValue ;
}
const CUtlVector < Type > & Get ( ) const
{
return * CSharedUtlVectorBase < Type , Changer > : : m_pValue ;
}
const CUtlVector < Type > * operator - > ( ) const
{
return CSharedUtlVectorBase < Type , Changer > : : m_pValue ;
}
const Type & operator [ ] ( int i ) const
{
return Get ( i ) ;
}
const Type & Get ( int i ) const
{
Assert ( i > = 0 & & i < ( CSharedUtlVectorBase < Type , Changer > : : m_pValue ) - > Count ( ) ) ;
return ( * CSharedUtlVectorBase < Type , Changer > : : m_pValue ) [ i ] ;
}
const int Count ( ) const
{
return CSharedUtlVectorBase < Type , Changer > : : m_pValue - > Count ( ) ;
}
protected :
virtual void Shared_CUtlVector_Vars_Must_Use_CSharedUtlVector ( ) { }
private :
virtual void _Save ( ISave * pSave )
{
SharedVar_SaveUtlVector < Type > ( pSave , CSharedUtlVectorBase < Type , Changer > : : m_pValue , 1 ) ;
}
virtual void _Restore ( IRestore * pRestore )
{
SharedVar_RestoreUtlVector < Type > ( pRestore , CSharedUtlVectorBase < Type , Changer > : : m_pValue ) ;
}
virtual bool _IsEmpty ( void )
{
return SharedVar_IsEmptyUtlVector < Type > ( CSharedUtlVectorBase < Type , Changer > : : m_pValue , 1 ) ;
}
virtual void _MakeEmpty ( void )
{
SharedVar_MakeEmptyUtlVector < Type > ( CSharedUtlVectorBase < Type , Changer > : : m_pValue , 1 ) ;
}
} ;
// Use this macro to define a network variable.
# define CSharedVar( type, name ) \
SHARED_VAR_START ( type , name ) \
SHARED_VAR_END ( type , name , CSharedVarBase )
// Helper for color32's. Contains GetR(), SetR(), etc.. functions.
# define CSharedColor32( name ) \
SHARED_VAR_START ( color32 , name ) \
SHARED_VAR_END ( color32 , name , CSharedColor32Base )
// Vectors + some convenient helper functions.
# define CSharedVector( name ) CSharedVectorInternal( Vector, name )
# define CSharedQAngle( name ) CSharedVectorInternal( QAngle, name )
# define CSharedVectorInternal( type, name ) \
SHARED_VAR_START ( type , name ) \
SHARED_VAR_END ( type , name , CSharedVectorBase )
# define CSharedQuaternion( name ) \
SHARED_VAR_START ( Quaternion , name ) \
SHARED_VAR_END ( Quaternion , name , CSharedQuaternionBase )
# define CSharedHandle( handletype, name ) \
SHARED_VAR_START ( handletype , name ) \
SHARED_VAR_END ( handletype , name , CSharedHandleBase )
# define CSharedArray( type, name, count ) \
SHARED_VAR_START ( type , name ) \
SHARED_VAR_END ( type , name , CSharedArrayBase ) \
enum { m_SharedArray_count_ # # name = count } ;
# define CSharedString( name, length ) \
CSharedArray ( char , name , length )
# define CSharedHandleArray( handletype, name, count ) \
SHARED_VAR_START ( handletype , name ) \
SHARED_VAR_END ( handletype , name , CSharedHandleArrayBase ) \
enum { m_SharedArray_count_ # # name = count } ;
# define CSharedUtlVector( utlvectortype, name ) \
SHARED_VAR_START ( utlvectortype , name ) \
SHARED_VAR_END ( utlvectortype , name , CSharedUtlVectorBase ) \
// Internal macros used in definitions of network vars.
# define SHARED_VAR_START( type, name ) \
class SharedVar_ # # name ; \
friend class SharedVar_ # # name ; \
typedef ThisClass MakeASharedVar_ # # name ; \
class SharedVar_ # # name \
{ \
public : \
template < typename T > friend int ServerClassInit ( T * ) ;
# define SHARED_VAR_END( type, name, base ) \
} ; \
base < type , SharedVar_ # # name > name ;
# define DECLARE_SHAREDCLASS() \
virtual void InitSharedVars ( void ) ;
# define IMPLEMENT_SHAREDCLASS_DT( type ) \
void type : : InitSharedVars ( void ) \
{ \
BaseClass : : InitSharedVars ( ) ;
# define END_SHARED_TABLE() \
}
# define SharedProp( var ) \
var . Initialize ( " SharedVar_ " # var , entindex ( ) ) ;
# define SharedPropArray( var ) \
var . Initialize ( " SharedVar_ " # var , entindex ( ) , m_SharedArray_count_ # # var ) ;
// Save/Restore handling
class CSharedVarSaveDataOps : public CDefSaveRestoreOps
{
// saves the entire array of variables
virtual void Save ( const SaveRestoreFieldInfo_t & fieldInfo , ISave * pSave )
{
ISharedVarBase * pSharedVar = ( ISharedVarBase * ) fieldInfo . pField ;
pSharedVar - > _Save ( pSave ) ;
}
// restores a single instance of the variable
virtual void Restore ( const SaveRestoreFieldInfo_t & fieldInfo , IRestore * pRestore )
{
ISharedVarBase * pSharedVar = ( ISharedVarBase * ) fieldInfo . pField ;
pSharedVar - > _Restore ( pRestore ) ;
}
virtual bool IsEmpty ( const SaveRestoreFieldInfo_t & fieldInfo )
{
ISharedVarBase * pSharedVar = ( ISharedVarBase * ) fieldInfo . pField ;
return pSharedVar - > _IsEmpty ( ) ;
}
virtual void MakeEmpty ( const SaveRestoreFieldInfo_t & fieldInfo )
{
ISharedVarBase * pSharedVar = ( ISharedVarBase * ) fieldInfo . pField ;
return pSharedVar - > _MakeEmpty ( ) ;
}
} ;
static CSharedVarSaveDataOps g_SharedVarSaveDataOps ;
# define DEFINE_SHARED_FIELD(name) \
{ FIELD_CUSTOM , # name , offsetof ( classNameTypedef , name ) , 1 , FTYPEDESC_SAVE , NULL , & g_SharedVarSaveDataOps , NULL }
# endif // SHAREDVAR_H