diff --git a/src/game/shared/lbaseentity_shared.cpp b/src/game/shared/lbaseentity_shared.cpp index 90652f0e3a..ebbf5cad20 100644 --- a/src/game/shared/lbaseentity_shared.cpp +++ b/src/game/shared/lbaseentity_shared.cpp @@ -2767,6 +2767,111 @@ LUA_BINDING_BEGIN( Entity, WorldToEntitySpace, "class", "Convert world to entity } LUA_BINDING_END() +// Experiments around NetworkVars +#include +enum NetworkVarTypes +{ + NETWORKVAR_TYPE_BOOL, + NETWORKVAR_TYPE_INT, + NETWORKVAR_TYPE_FLOAT, + NETWORKVAR_TYPE_VECTOR, + NETWORKVAR_TYPE_STRING, + NETWORKVAR_TYPE_EHANDLE, +}; +#pragma warning( disable : 4189 ) +LUA_BINDING_BEGIN( Entity, SetupNetworkVariable, "class", "Creates a network variable on the entity and adds Set/Get methods for it to the entity." ) +{ + lua_CBaseEntity *entity = LUA_BINDING_ARGUMENT( luaL_checkentity, 1, "entity" ); + NetworkVarTypes networkVarType = LUA_BINDING_ARGUMENT_ENUM( NetworkVarTypes, 2, "type" ); + int slot = LUA_BINDING_ARGUMENT( luaL_checknumber, 3, "slot" ); + const char *variableName = LUA_BINDING_ARGUMENT( luaL_checkstring, 4, "variableName" ); + + // lua_run player.GetByID(2):SetupNetworkVariable(2, "Test") + + // That should've added: + // lua_run player.GetByID(2):SetTest(1337) + // lua_run print(player.GetByID(2):GetTest()) -- 1337 + + // TODO: Use SendPropVirtualArray with a max size of 32 to send the network variable + // Have a SendPropVirtualArray for each type of network variable, except string + // which will have 4 SendPropString + // + // https://developer.valvesoftware.com/wiki/Networking_Entities + // + ////////////////////////////////////////////////////////////////// + // On the server we will have something like this: + // + //void SendProxy_LuaVarFloatElement( const SendProp *pProp, const void *pStruct, const void *pVarData, DVariant *pOut, int iElement, int objectID ) + //{ + // CBaseEntity *entity = ( CBaseEntity * )pStruct; + // Assert( entity ); + + // pOut->m_Float = // entity->GetLuaVarFloat( iElement ); // Somehow get the float that is in the iElement slot + //} + + //int SendProxy_LuaVarFloatCount( const void *pStruct, int objectID ) + //{ + // CBaseEntity *entity = ( CBaseEntity * )pStruct; + // Assert( entity ); + + // // return entity->GetLuaVarFloatCount(); // Somehow get the count of floats + //} + + //IMPLEMENT_SERVERCLASS_ST( CBaseEntity, DT_BaseEntityLuaVariables ) + //SendPropVirtualArray( + // SendProxy_LuaVarFloatCount, + // 32, // max elements (ever) + // SendPropFloat( "lua_var_float", 0, 0, 0, SendProxy_LuaVarFloatElement ), + // "lua_var_floats" ) + //END_SEND_TABLE() + + ////////////////////////////////////////////////////////////////// + // On the client we will receive it like this: + // + //void RecvProxy_LuaVarFloatElement( const CRecvProxyData *pData, void *pStruct, void *pOut ) + //{ + // C_BaseEntity *entity = ( C_BaseEntity * )pStruct; + // Assert( entity ); + + // // entity->m_LuaVarFloats[ pData->m_iElement ] = pData->m_Value.m_Float; // Somehow set the float that is in the iElement slot + //} + + //void RecvProxy_LuaVarFloatCount( void *pStruct, int objectID, int currentArrayLength ) + //{ + // C_BaseEntity *entity = ( C_BaseEntity * )pStruct; + // Assert( entity ); + + // if ( entity->m_LuaVarFloats.Count() != currentArrayLength ) + // pPanel->m_LuaVarFloats.SetSize( currentArrayLength ); + //} + + //IMPLEMENT_CLIENTCLASS_DT( C_BaseEntity, DT_BaseEntityLuaVariables, CBaseEntity ) + // RecvPropVirtualArray( + // RecvProxy_LuaVarFloatCount, + // 32, // max elements (ever) + // RecvPropFloat( "lua_var_float", 0, 0, RecvProxy_LuaVarFloatElement ), + // "lua_var_floats" ) + //END_RECV_TABLE() + + // TODO: Using macros the above would be repeated for the other types of network variables too. + // TODO: The SetLuaVarFloat method (and similar) would call callbacks set by NetworkVarNotify (or a hook and we implement that in Lua) + + switch ( networkVarType ) + { + case NETWORKVAR_TYPE_FLOAT: + + // TODO: entity->RegisterLuaVarFloat( variableName, slot ); // TODO: auto increment slot + + break; + } + + return 0; +} +LUA_BINDING_END() +#pragma warning(default: 4189) + +// End of NetworkVars experiments + LUA_BINDING_BEGIN( Entity, IsValid, "class", "Check if entity is valid." ) { lua_CBaseEntity *pEntity = LUA_BINDING_ARGUMENT( lua_toentity, 1, "entity" ); diff --git a/src/public/networkvar.h b/src/public/networkvar.h index 142b35e9e3..71a033ad1d 100644 --- a/src/public/networkvar.h +++ b/src/public/networkvar.h @@ -1,6 +1,6 @@ //========= Copyright Valve Corporation, All rights reserved. ============// // -// Purpose: +// Purpose: // //=============================================================================// @@ -10,772 +10,883 @@ #pragma once #endif - #include "tier0/dbg.h" #include "convar.h" #if defined( CLIENT_DLL ) || defined( GAME_DLL ) - #include "basehandle.h" +#include "basehandle.h" #endif +#pragma warning( disable : 4284 ) // warning C4284: return type for 'CNetworkVarT::operator ->' is 'int *' (ie; not a UDT or reference to a UDT. Will produce errors if applied using infix notation) -#pragma warning( disable : 4284 ) // warning C4284: return type for 'CNetworkVarT::operator ->' is 'int *' (ie; not a UDT or reference to a UDT. Will produce errors if applied using infix notation) - -#define MyOffsetOf( type, var ) ( (int)&((type*)0)->var ) +#define MyOffsetOf( type, var ) ( ( int )&( ( type * )0 )->var ) #ifdef _DEBUG - extern bool g_bUseNetworkVars; - #define CHECK_USENETWORKVARS if(g_bUseNetworkVars) +extern bool g_bUseNetworkVars; +#define CHECK_USENETWORKVARS if ( g_bUseNetworkVars ) #else - #define CHECK_USENETWORKVARS // don't check for g_bUseNetworkVars +#define CHECK_USENETWORKVARS // don't check for g_bUseNetworkVars #endif - - inline int InternalCheckDeclareClass( const char *pClassName, const char *pClassNameMatch, void *pTestPtr, void *pBasePtr ) { - // This makes sure that casting from ThisClass to BaseClass works right. You'll get a compiler error if it doesn't - // work at all, and you'll get a runtime error if you use multiple inheritance. - Assert( pTestPtr == pBasePtr ); - - // This is triggered by IMPLEMENT_SERVER_CLASS. It does DLLClassName::CheckDeclareClass( #DLLClassName ). - // If they didn't do a DECLARE_CLASS in DLLClassName, then it'll be calling its base class's version - // and the class names won't match. - Assert( (void*)pClassName == (void*)pClassNameMatch ); - return 0; + // This makes sure that casting from ThisClass to BaseClass works right. You'll get a compiler error if it doesn't + // work at all, and you'll get a runtime error if you use multiple inheritance. + Assert( pTestPtr == pBasePtr ); + + // This is triggered by IMPLEMENT_SERVER_CLASS. It does DLLClassName::CheckDeclareClass( #DLLClassName ). + // If they didn't do a DECLARE_CLASS in DLLClassName, then it'll be calling its base class's version + // and the class names won't match. + Assert( ( void * )pClassName == ( void * )pClassNameMatch ); + return 0; } - -template +template < typename T > inline int CheckDeclareClass_Access( T *, const char *pShouldBe ) { - return T::CheckDeclareClass( pShouldBe ); + return T::CheckDeclareClass( pShouldBe ); } #ifndef _STATIC_LINKED #ifdef _MSC_VER -#if defined(_DEBUG) && (_MSC_VER > 1200 ) - #define VALIDATE_DECLARE_CLASS 1 +#if defined( _DEBUG ) && ( _MSC_VER > 1200 ) +#define VALIDATE_DECLARE_CLASS 1 #endif #endif #endif -#ifdef VALIDATE_DECLARE_CLASS - - #define DECLARE_CLASS( className, baseClassName ) \ - typedef baseClassName BaseClass; \ - typedef className ThisClass; \ - template friend int CheckDeclareClass_Access(T *, const char *pShouldBe); \ - static int CheckDeclareClass( const char *pShouldBe ) \ - { \ - InternalCheckDeclareClass( pShouldBe, #className, (ThisClass*)0xFFFFF, (BaseClass*)(ThisClass*)0xFFFFF ); \ - return CheckDeclareClass_Access( (BaseClass *)NULL, #baseClassName ); \ - } - - // Use this macro when you have a base class, but it's part of a library that doesn't use network vars - // or any of the things that use ThisClass or BaseClass. - #define DECLARE_CLASS_GAMEROOT( className, baseClassName ) \ - typedef baseClassName BaseClass; \ - typedef className ThisClass; \ - template friend int CheckDeclareClass_Access(T *, const char *pShouldBe); \ - static int CheckDeclareClass( const char *pShouldBe ) \ - { \ - return InternalCheckDeclareClass( pShouldBe, #className, (ThisClass*)0xFFFFF, (BaseClass*)(ThisClass*)0xFFFFF ); \ - } - - // Deprecated macro formerly used to work around VC++98 bug - #define DECLARE_CLASS_NOFRIEND( className, baseClassName ) \ - DECLARE_CLASS( className, baseClassName ) - - #define DECLARE_CLASS_NOBASE( className ) \ - typedef className ThisClass; \ - template friend int CheckDeclareClass_Access(T *, const char *pShouldBe); \ - static int CheckDeclareClass( const char *pShouldBe ) \ - { \ - return InternalCheckDeclareClass( pShouldBe, #className, 0, 0 ); \ - } +#ifdef VALIDATE_DECLARE_CLASS + +#define DECLARE_CLASS( className, baseClassName ) \ + typedef baseClassName BaseClass; \ + typedef className ThisClass; \ + template < typename T > \ + friend int CheckDeclareClass_Access( T *, const char *pShouldBe ); \ + static int CheckDeclareClass( const char *pShouldBe ) \ + { \ + InternalCheckDeclareClass( pShouldBe, #className, ( ThisClass * )0xFFFFF, ( BaseClass * )( ThisClass * )0xFFFFF ); \ + return CheckDeclareClass_Access( ( BaseClass * )NULL, #baseClassName ); \ + } + +// Use this macro when you have a base class, but it's part of a library that doesn't use network vars +// or any of the things that use ThisClass or BaseClass. +#define DECLARE_CLASS_GAMEROOT( className, baseClassName ) \ + typedef baseClassName BaseClass; \ + typedef className ThisClass; \ + template < typename T > \ + friend int CheckDeclareClass_Access( T *, const char *pShouldBe ); \ + static int CheckDeclareClass( const char *pShouldBe ) \ + { \ + return InternalCheckDeclareClass( pShouldBe, #className, ( ThisClass * )0xFFFFF, ( BaseClass * )( ThisClass * )0xFFFFF ); \ + } + +// Deprecated macro formerly used to work around VC++98 bug +#define DECLARE_CLASS_NOFRIEND( className, baseClassName ) \ + DECLARE_CLASS( className, baseClassName ) + +#define DECLARE_CLASS_NOBASE( className ) \ + typedef className ThisClass; \ + template < typename T > \ + friend int CheckDeclareClass_Access( T *, const char *pShouldBe ); \ + static int CheckDeclareClass( const char *pShouldBe ) \ + { \ + return InternalCheckDeclareClass( pShouldBe, #className, 0, 0 ); \ + } #else - #define DECLARE_CLASS( className, baseClassName ) \ - typedef baseClassName BaseClass; \ - typedef className ThisClass; +#define DECLARE_CLASS( className, baseClassName ) \ + typedef baseClassName BaseClass; \ + typedef className ThisClass; - #define DECLARE_CLASS_GAMEROOT( className, baseClassName ) DECLARE_CLASS( className, baseClassName ) - #define DECLARE_CLASS_NOFRIEND( className, baseClassName ) DECLARE_CLASS( className, baseClassName ) +#define DECLARE_CLASS_GAMEROOT( className, baseClassName ) DECLARE_CLASS( className, baseClassName ) +#define DECLARE_CLASS_NOFRIEND( className, baseClassName ) DECLARE_CLASS( className, baseClassName ) - #define DECLARE_CLASS_NOBASE( className ) typedef className ThisClass; +#define DECLARE_CLASS_NOBASE( className ) typedef className ThisClass; #endif - - - // All classes that contain CNetworkVars need a NetworkStateChanged() function. If the class is not an entity, // it needs to forward the call to the entity it's in. These macros can help. - - // These macros setup an entity pointer in your class. Use IMPLEMENT_NETWORKVAR_CHAIN before you do - // anything inside the class itself. - class CBaseEntity; - class CAutoInitEntPtr - { - public: - CAutoInitEntPtr() - { - m_pEnt = NULL; - } - CBaseEntity *m_pEnt; - }; - - //TODO: Currently, these don't get the benefit of tracking changes to individual vars. - // Would be nice if they did. - #define DECLARE_NETWORKVAR_CHAIN() \ - CAutoInitEntPtr __m_pChainEntity; \ - void NetworkStateChanged() { CHECK_USENETWORKVARS __m_pChainEntity.m_pEnt->NetworkStateChanged(); } \ - void NetworkStateChanged( void *pVar ) { CHECK_USENETWORKVARS __m_pChainEntity.m_pEnt->NetworkStateChanged(); } - - #define IMPLEMENT_NETWORKVAR_CHAIN( varName ) \ - (varName)->__m_pChainEntity.m_pEnt = this; +// These macros setup an entity pointer in your class. Use IMPLEMENT_NETWORKVAR_CHAIN before you do +// anything inside the class itself. +class CBaseEntity; +class CAutoInitEntPtr +{ + public: + CAutoInitEntPtr() + { + m_pEnt = NULL; + } + CBaseEntity *m_pEnt; +}; +// TODO: Currently, these don't get the benefit of tracking changes to individual vars. +// Would be nice if they did. +#define DECLARE_NETWORKVAR_CHAIN() \ + CAutoInitEntPtr __m_pChainEntity; \ + void NetworkStateChanged() \ + { \ + CHECK_USENETWORKVARS __m_pChainEntity.m_pEnt->NetworkStateChanged(); \ + } \ + void NetworkStateChanged( void *pVar ) \ + { \ + CHECK_USENETWORKVARS __m_pChainEntity.m_pEnt->NetworkStateChanged(); \ + } + +#define IMPLEMENT_NETWORKVAR_CHAIN( varName ) \ + ( varName )->__m_pChainEntity.m_pEnt = this; // Use this macro when you want to embed a structure inside your entity and have CNetworkVars in it. -template< class T > +template < class T > static inline void DispatchNetworkStateChanged( T *pObj ) { - CHECK_USENETWORKVARS pObj->NetworkStateChanged(); + CHECK_USENETWORKVARS pObj->NetworkStateChanged(); } -template< class T > +template < class T > static inline void DispatchNetworkStateChanged( T *pObj, void *pVar ) { - CHECK_USENETWORKVARS pObj->NetworkStateChanged( pVar ); + CHECK_USENETWORKVARS pObj->NetworkStateChanged( pVar ); } - -#define DECLARE_EMBEDDED_NETWORKVAR() \ - template friend int ServerClassInit(T *); \ - template friend int ClientClassInit(T *); \ - virtual void NetworkStateChanged() {} virtual void NetworkStateChanged( void *pProp ) {} +#define DECLARE_EMBEDDED_NETWORKVAR() \ + template < typename T > \ + friend int ServerClassInit( T * ); \ + template < typename T > \ + friend int ClientClassInit( T * ); \ + virtual void NetworkStateChanged() {} \ + virtual void NetworkStateChanged( void *pProp ) {} // NOTE: Assignment operator is disabled because it doesn't call copy constructors of scalar types within the aggregate, so they are not marked changed -#define CNetworkVarEmbedded( type, name ) \ - class NetworkVar_##name; \ - friend class NetworkVar_##name; \ - static inline int GetOffset_##name() { return MyOffsetOf(ThisClass,name); } \ - typedef ThisClass ThisClass_##name; \ - class NetworkVar_##name : public type \ - { \ - template< class T > NetworkVar_##name& operator=( const T &val ) { *((type*)this) = val; return *this; } \ - public: \ - void CopyFrom( const type &src ) { *((type *)this) = src; NetworkStateChanged(); } \ - virtual void NetworkStateChanged() \ - { \ - DispatchNetworkStateChanged( (ThisClass_##name*)( ((char*)this) - GetOffset_##name() ) ); \ - } \ - virtual void NetworkStateChanged( void *pVar ) \ - { \ - DispatchNetworkStateChanged( (ThisClass_##name*)( ((char*)this) - GetOffset_##name() ), pVar ); \ - } \ - }; \ - NetworkVar_##name name; - -template -FORCEINLINE void NetworkVarConstruct( T &x ) { x = T(0); } -FORCEINLINE void NetworkVarConstruct( color32_s &x ) { x.r = x.g = x.b = x.a = 0; } - -template< class Type, class Changer > +#define CNetworkVarEmbedded( type, name ) \ + class NetworkVar_##name; \ + friend class NetworkVar_##name; \ + static inline int GetOffset_##name() \ + { \ + return MyOffsetOf( ThisClass, name ); \ + } \ + typedef ThisClass ThisClass_##name; \ + class NetworkVar_##name : public type \ + { \ + template < class T > \ + NetworkVar_##name &operator=( const T &val ) \ + { \ + *( ( type * )this ) = val; \ + return *this; \ + } \ + \ + public: \ + void CopyFrom( const type &src ) \ + { \ + *( ( type * )this ) = src; \ + NetworkStateChanged(); \ + } \ + virtual void NetworkStateChanged() \ + { \ + DispatchNetworkStateChanged( ( ThisClass_##name * )( ( ( char * )this ) - GetOffset_##name() ) ); \ + } \ + virtual void NetworkStateChanged( void *pVar ) \ + { \ + DispatchNetworkStateChanged( ( ThisClass_##name * )( ( ( char * )this ) - GetOffset_##name() ), pVar ); \ + } \ + }; \ + NetworkVar_##name name; + +template < typename T > +FORCEINLINE void NetworkVarConstruct( T &x ) +{ + x = T( 0 ); +} +FORCEINLINE void NetworkVarConstruct( color32_s &x ) +{ + x.r = x.g = x.b = x.a = 0; +} + +template < class Type, class Changer > class CNetworkVarBase { -public: - inline CNetworkVarBase() - { - NetworkVarConstruct( m_Value ); - } - - template< class C > - const Type& operator=( const C &val ) - { - return Set( ( const Type )val ); - } - - template< class C > - const Type& operator=( const CNetworkVarBase< C, Changer > &val ) - { - return Set( ( const Type )val.m_Value ); - } - - const Type& Set( const Type &val ) - { - if ( memcmp( &m_Value, &val, sizeof(Type) ) ) - { - NetworkStateChanged(); - m_Value = val; - } - return m_Value; - } - - Type& GetForModify() - { - NetworkStateChanged(); - return m_Value; - } - - template< class C > - const Type& operator+=( const C &val ) - { - return Set( m_Value + ( const Type )val ); - } - - template< class C > - const Type& operator-=( const C &val ) - { - return Set( m_Value - ( const Type )val ); - } - - template< class C > - const Type& operator/=( const C &val ) - { - return Set( m_Value / ( const Type )val ); - } - - template< class C > - const Type& operator*=( const C &val ) - { - return Set( m_Value * ( const Type )val ); - } - - template< class C > - const Type& operator^=( const C &val ) - { - return Set( m_Value ^ ( const Type )val ); - } - - template< class C > - const Type& operator|=( const C &val ) - { - return Set( m_Value | ( const Type )val ); - } - - const Type& operator++() - { - return (*this += 1); - } - - Type operator--() - { - return (*this -= 1); - } - - Type operator++( int ) // postfix version.. - { - Type val = m_Value; - (*this += 1); - return val; - } - - Type operator--( int ) // postfix version.. - { - Type val = m_Value; - (*this -= 1); - return val; - } - - // For some reason the compiler only generates type conversion warnings for this operator when used like - // CNetworkVarBase = 0x1 - // (it warns about converting from an int to an unsigned char). - template< class C > - const Type& operator&=( const C &val ) - { - return Set( m_Value & ( const Type )val ); - } - - operator const Type&() const - { - return m_Value; - } - - const Type& Get() const - { - return m_Value; - } - - const Type* operator->() const - { - return &m_Value; - } - - Type m_Value; - -protected: - inline void NetworkStateChanged() - { - Changer::NetworkStateChanged( this ); - } + public: + inline CNetworkVarBase() + { + NetworkVarConstruct( m_Value ); + } + + template < class C > + const Type &operator=( const C &val ) + { + return Set( ( const Type )val ); + } + + template < class C > + const Type &operator=( const CNetworkVarBase< C, Changer > &val ) + { + return Set( ( const Type )val.m_Value ); + } + + const Type &Set( const Type &val ) + { + if ( memcmp( &m_Value, &val, sizeof( Type ) ) ) + { + NetworkStateChanged(); + m_Value = val; + } + return m_Value; + } + + Type &GetForModify() + { + NetworkStateChanged(); + return m_Value; + } + + template < class C > + const Type &operator+=( const C &val ) + { + return Set( m_Value + ( const Type )val ); + } + + template < class C > + const Type &operator-=( const C &val ) + { + return Set( m_Value - ( const Type )val ); + } + + template < class C > + const Type &operator/=( const C &val ) + { + return Set( m_Value / ( const Type )val ); + } + + template < class C > + const Type &operator*=( const C &val ) + { + return Set( m_Value * ( const Type )val ); + } + + template < class C > + const Type &operator^=( const C &val ) + { + return Set( m_Value ^ ( const Type )val ); + } + + template < class C > + const Type &operator|=( const C &val ) + { + return Set( m_Value | ( const Type )val ); + } + + const Type &operator++() + { + return ( *this += 1 ); + } + + Type operator--() + { + return ( *this -= 1 ); + } + + Type operator++( int ) // postfix version.. + { + Type val = m_Value; + ( *this += 1 ); + return val; + } + + Type operator--( int ) // postfix version.. + { + Type val = m_Value; + ( *this -= 1 ); + return val; + } + + // For some reason the compiler only generates type conversion warnings for this operator when used like + // CNetworkVarBase = 0x1 + // (it warns about converting from an int to an unsigned char). + template < class C > + const Type &operator&=( const C &val ) + { + return Set( m_Value & ( const Type )val ); + } + + operator const Type &() const + { + return m_Value; + } + + const Type &Get() const + { + return m_Value; + } + + const Type *operator->() const + { + return &m_Value; + } + + Type m_Value; + + protected: + inline void NetworkStateChanged() + { + Changer::NetworkStateChanged( this ); + } }; - -template< class Type, class Changer > +template < class Type, class Changer > class CNetworkColor32Base : public CNetworkVarBase< Type, Changer > { -public: - 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 this->Set( val ); - } - - const Type& operator=( const CNetworkColor32Base &val ) - { - return CNetworkVarBase::Set( val.m_Value ); - } - - inline byte GetR() const { return CNetworkColor32Base::m_Value.r; } - inline byte GetG() const { return CNetworkColor32Base::m_Value.g; } - inline byte GetB() const { return CNetworkColor32Base::m_Value.b; } - inline byte GetA() const { return CNetworkColor32Base::m_Value.a; } - inline void SetR( byte val ) { SetVal( CNetworkColor32Base::m_Value.r, val ); } - inline void SetG( byte val ) { SetVal( CNetworkColor32Base::m_Value.g, val ); } - inline void SetB( byte val ) { SetVal( CNetworkColor32Base::m_Value.b, val ); } - inline void SetA( byte val ) { SetVal( CNetworkColor32Base::m_Value.a, val ); } - -protected: - inline void SetVal( byte &out, const byte &in ) - { - if ( out != in ) - { - CNetworkVarBase< Type, Changer >::NetworkStateChanged(); - out = in; - } - } + public: + 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 this->Set( val ); + } + + const Type &operator=( const CNetworkColor32Base< Type, Changer > &val ) + { + return CNetworkVarBase< Type, Changer >::Set( val.m_Value ); + } + + inline byte GetR() const + { + return CNetworkColor32Base< Type, Changer >::m_Value.r; + } + inline byte GetG() const + { + return CNetworkColor32Base< Type, Changer >::m_Value.g; + } + inline byte GetB() const + { + return CNetworkColor32Base< Type, Changer >::m_Value.b; + } + inline byte GetA() const + { + return CNetworkColor32Base< Type, Changer >::m_Value.a; + } + inline void SetR( byte val ) + { + SetVal( CNetworkColor32Base< Type, Changer >::m_Value.r, val ); + } + inline void SetG( byte val ) + { + SetVal( CNetworkColor32Base< Type, Changer >::m_Value.g, val ); + } + inline void SetB( byte val ) + { + SetVal( CNetworkColor32Base< Type, Changer >::m_Value.b, val ); + } + inline void SetA( byte val ) + { + SetVal( CNetworkColor32Base< Type, Changer >::m_Value.a, val ); + } + + protected: + inline void SetVal( byte &out, const byte &in ) + { + if ( out != in ) + { + CNetworkVarBase< Type, Changer >::NetworkStateChanged(); + out = in; + } + } }; - // Network vector wrapper. -template< class Type, class Changer > +template < class Type, class Changer > class CNetworkVectorBase : public CNetworkVarBase< Type, Changer > { -public: - 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 CNetworkVarBase< Type, Changer >::Set( val ); - } - - const Type& operator=( const CNetworkVectorBase &val ) - { - return CNetworkVarBase::Set( val.m_Value ); - } - - inline float GetX() const { return CNetworkVectorBase::m_Value.x; } - inline float GetY() const { return CNetworkVectorBase::m_Value.y; } - inline float GetZ() const { return CNetworkVectorBase::m_Value.z; } - inline float operator[]( int i ) const { return CNetworkVectorBase::m_Value[i]; } - - inline void SetX( float val ) { DetectChange( CNetworkVectorBase::m_Value.x, val ); } - inline void SetY( float val ) { DetectChange( CNetworkVectorBase::m_Value.y, val ); } - inline void SetZ( float val ) { DetectChange( CNetworkVectorBase::m_Value.z, val ); } - inline void Set( int i, float val ) { DetectChange( CNetworkVectorBase::m_Value[i], val ); } - - bool operator==( const Type &val ) const - { - return CNetworkVectorBase::m_Value == (Type)val; - } - - bool operator!=( const Type &val ) const - { - return CNetworkVectorBase::m_Value != (Type)val; - } - - const Type operator+( const Type &val ) const - { - return CNetworkVectorBase::m_Value + val; - } - - const Type operator-( const Type &val ) const - { - return CNetworkVectorBase::m_Value - val; - } - - const Type operator*( const Type &val ) const - { - return CNetworkVectorBase::m_Value * val; - } - - const Type& operator*=( float val ) - { - return CNetworkVarBase< Type, Changer >::Set( CNetworkVectorBase::m_Value * val ); - } - - const Type operator*( float val ) const - { - return CNetworkVectorBase::m_Value * val; - } - - const Type operator/( const Type &val ) const - { - return CNetworkVectorBase::m_Value / val; - } - -private: - inline void DetectChange( float &out, float in ) - { - if ( out != in ) - { - CNetworkVectorBase::NetworkStateChanged(); - out = in; - } - } + public: + 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 CNetworkVarBase< Type, Changer >::Set( val ); + } + + const Type &operator=( const CNetworkVectorBase< Type, Changer > &val ) + { + return CNetworkVarBase< Type, Changer >::Set( val.m_Value ); + } + + inline float GetX() const + { + return CNetworkVectorBase< Type, Changer >::m_Value.x; + } + inline float GetY() const + { + return CNetworkVectorBase< Type, Changer >::m_Value.y; + } + inline float GetZ() const + { + return CNetworkVectorBase< Type, Changer >::m_Value.z; + } + inline float operator[]( int i ) const + { + return CNetworkVectorBase< Type, Changer >::m_Value[i]; + } + + inline void SetX( float val ) + { + DetectChange( CNetworkVectorBase< Type, Changer >::m_Value.x, val ); + } + inline void SetY( float val ) + { + DetectChange( CNetworkVectorBase< Type, Changer >::m_Value.y, val ); + } + inline void SetZ( float val ) + { + DetectChange( CNetworkVectorBase< Type, Changer >::m_Value.z, val ); + } + inline void Set( int i, float val ) + { + DetectChange( CNetworkVectorBase< Type, Changer >::m_Value[i], val ); + } + + bool operator==( const Type &val ) const + { + return CNetworkVectorBase< Type, Changer >::m_Value == ( Type )val; + } + + bool operator!=( const Type &val ) const + { + return CNetworkVectorBase< Type, Changer >::m_Value != ( Type )val; + } + + const Type operator+( const Type &val ) const + { + return CNetworkVectorBase< Type, Changer >::m_Value + val; + } + + const Type operator-( const Type &val ) const + { + return CNetworkVectorBase< Type, Changer >::m_Value - val; + } + + const Type operator*( const Type &val ) const + { + return CNetworkVectorBase< Type, Changer >::m_Value * val; + } + + const Type &operator*=( float val ) + { + return CNetworkVarBase< Type, Changer >::Set( CNetworkVectorBase< Type, Changer >::m_Value * val ); + } + + const Type operator*( float val ) const + { + return CNetworkVectorBase< Type, Changer >::m_Value * val; + } + + const Type operator/( const Type &val ) const + { + return CNetworkVectorBase< Type, Changer >::m_Value / val; + } + + private: + inline void DetectChange( float &out, float in ) + { + if ( out != in ) + { + CNetworkVectorBase< Type, Changer >::NetworkStateChanged(); + out = in; + } + } }; - // Network vector wrapper. -template< class Type, class Changer > +template < class Type, class Changer > class CNetworkQuaternionBase : public CNetworkVarBase< Type, Changer > { -public: - inline void Init( float ix=0, float iy=0, float iz=0, float iw = 0 ) - { - SetX( ix ); - SetY( iy ); - SetZ( iz ); - SetW( iw ); - } - - const Type& operator=( const Type &val ) - { - return CNetworkVarBase< Type, Changer >::Set( val ); - } - - const Type& operator=( const CNetworkQuaternionBase &val ) - { - return CNetworkVarBase::Set( val.m_Value ); - } - - inline float GetX() const { return CNetworkQuaternionBase::m_Value.x; } - inline float GetY() const { return CNetworkQuaternionBase::m_Value.y; } - inline float GetZ() const { return CNetworkQuaternionBase::m_Value.z; } - inline float GetW() const { return CNetworkQuaternionBase::m_Value.w; } - inline float operator[]( int i ) const { return CNetworkQuaternionBase::m_Value[i]; } - - inline void SetX( float val ) { DetectChange( CNetworkQuaternionBase::m_Value.x, val ); } - inline void SetY( float val ) { DetectChange( CNetworkQuaternionBase::m_Value.y, val ); } - inline void SetZ( float val ) { DetectChange( CNetworkQuaternionBase::m_Value.z, val ); } - inline void SetW( float val ) { DetectChange( CNetworkQuaternionBase::m_Value.w, val ); } - inline void Set( int i, float val ) { DetectChange( CNetworkQuaternionBase::m_Value[i], val ); } - - bool operator==( const Type &val ) const - { - return CNetworkQuaternionBase::m_Value == (Type)val; - } - - bool operator!=( const Type &val ) const - { - return CNetworkQuaternionBase::m_Value != (Type)val; - } - - const Type operator+( const Type &val ) const - { - return CNetworkQuaternionBase::m_Value + val; - } - - const Type operator-( const Type &val ) const - { - return CNetworkQuaternionBase::m_Value - val; - } - - const Type operator*( const Type &val ) const - { - return CNetworkQuaternionBase::m_Value * val; - } - - const Type& operator*=( float val ) - { - return CNetworkQuaternionBase< Type, Changer >::Set( CNetworkQuaternionBase::m_Value * val ); - } - - const Type operator*( float val ) const - { - return CNetworkQuaternionBase::m_Value * val; - } - - const Type operator/( const Type &val ) const - { - return CNetworkQuaternionBase::m_Value / val; - } - -private: - inline void DetectChange( float &out, float in ) - { - if ( out != in ) - { - CNetworkQuaternionBase::NetworkStateChanged(); - out = in; - } - } + public: + inline void Init( float ix = 0, float iy = 0, float iz = 0, float iw = 0 ) + { + SetX( ix ); + SetY( iy ); + SetZ( iz ); + SetW( iw ); + } + + const Type &operator=( const Type &val ) + { + return CNetworkVarBase< Type, Changer >::Set( val ); + } + + const Type &operator=( const CNetworkQuaternionBase< Type, Changer > &val ) + { + return CNetworkVarBase< Type, Changer >::Set( val.m_Value ); + } + + inline float GetX() const + { + return CNetworkQuaternionBase< Type, Changer >::m_Value.x; + } + inline float GetY() const + { + return CNetworkQuaternionBase< Type, Changer >::m_Value.y; + } + inline float GetZ() const + { + return CNetworkQuaternionBase< Type, Changer >::m_Value.z; + } + inline float GetW() const + { + return CNetworkQuaternionBase< Type, Changer >::m_Value.w; + } + inline float operator[]( int i ) const + { + return CNetworkQuaternionBase< Type, Changer >::m_Value[i]; + } + + inline void SetX( float val ) + { + DetectChange( CNetworkQuaternionBase< Type, Changer >::m_Value.x, val ); + } + inline void SetY( float val ) + { + DetectChange( CNetworkQuaternionBase< Type, Changer >::m_Value.y, val ); + } + inline void SetZ( float val ) + { + DetectChange( CNetworkQuaternionBase< Type, Changer >::m_Value.z, val ); + } + inline void SetW( float val ) + { + DetectChange( CNetworkQuaternionBase< Type, Changer >::m_Value.w, val ); + } + inline void Set( int i, float val ) + { + DetectChange( CNetworkQuaternionBase< Type, Changer >::m_Value[i], val ); + } + + bool operator==( const Type &val ) const + { + return CNetworkQuaternionBase< Type, Changer >::m_Value == ( Type )val; + } + + bool operator!=( const Type &val ) const + { + return CNetworkQuaternionBase< Type, Changer >::m_Value != ( Type )val; + } + + const Type operator+( const Type &val ) const + { + return CNetworkQuaternionBase< Type, Changer >::m_Value + val; + } + + const Type operator-( const Type &val ) const + { + return CNetworkQuaternionBase< Type, Changer >::m_Value - val; + } + + const Type operator*( const Type &val ) const + { + return CNetworkQuaternionBase< Type, Changer >::m_Value * val; + } + + const Type &operator*=( float val ) + { + return CNetworkQuaternionBase< Type, Changer >::Set( CNetworkQuaternionBase< Type, Changer >::m_Value * val ); + } + + const Type operator*( float val ) const + { + return CNetworkQuaternionBase< Type, Changer >::m_Value * val; + } + + const Type operator/( const Type &val ) const + { + return CNetworkQuaternionBase< Type, Changer >::m_Value / val; + } + + private: + inline void DetectChange( float &out, float in ) + { + if ( out != in ) + { + CNetworkQuaternionBase< Type, Changer >::NetworkStateChanged(); + out = in; + } + } }; - // Network ehandle wrapper. #if defined( CLIENT_DLL ) || defined( GAME_DLL ) - inline void NetworkVarConstruct( CBaseHandle &x ) {} - - template< class Type, class Changer > - class CNetworkHandleBase : public CNetworkVarBase< CBaseHandle, Changer > - { - public: - const Type* operator=( const Type *val ) - { - return Set( val ); - } - - const Type& operator=( const CNetworkHandleBase &val ) - { - const CBaseHandle &handle = CNetworkVarBase::Set( val.m_Value ); - return *(const Type*)handle.Get(); - } - - bool operator !() const - { - return !CNetworkHandleBase::m_Value.Get(); - } - - operator Type*() const - { - return static_cast< Type* >( CNetworkHandleBase::m_Value.Get() ); - } - - const Type* Set( const Type *val ) - { - if ( CNetworkHandleBase::m_Value != val ) - { - this->NetworkStateChanged(); - CNetworkHandleBase::m_Value = val; - } - return val; - } - - Type* Get() const - { - return static_cast< Type* >( CNetworkHandleBase::m_Value.Get() ); - } - - Type* operator->() const - { - return static_cast< Type* >( CNetworkHandleBase::m_Value.Get() ); - } - - bool operator==( const Type *val ) const - { - return CNetworkHandleBase::m_Value == val; - } - - bool operator!=( const Type *val ) const - { - return CNetworkHandleBase::m_Value != val; - } - }; - - - - #define CNetworkHandle( type, name ) CNetworkHandleInternal( type, name, NetworkStateChanged ) - - #define CNetworkHandleInternal( type, name, stateChangedFn ) \ - NETWORK_VAR_START( type, name ) \ - NETWORK_VAR_END( type, name, CNetworkHandleBase, stateChangedFn ) -#endif +inline void NetworkVarConstruct( CBaseHandle &x ) {} +template < class Type, class Changer > +class CNetworkHandleBase : public CNetworkVarBase< CBaseHandle, Changer > +{ + public: + const Type *operator=( const Type *val ) + { + return Set( val ); + } + + const Type &operator=( const CNetworkHandleBase< Type, Changer > &val ) + { + const CBaseHandle &handle = CNetworkVarBase< CBaseHandle, Changer >::Set( val.m_Value ); + return *( const Type * )handle.Get(); + } + + bool operator!() const + { + return !CNetworkHandleBase< Type, Changer >::m_Value.Get(); + } + + operator Type *() const + { + return static_cast< Type * >( CNetworkHandleBase< Type, Changer >::m_Value.Get() ); + } + + const Type *Set( const Type *val ) + { + if ( CNetworkHandleBase< Type, Changer >::m_Value != val ) + { + this->NetworkStateChanged(); + CNetworkHandleBase< Type, Changer >::m_Value = val; + } + return val; + } + + Type *Get() const + { + return static_cast< Type * >( CNetworkHandleBase< Type, Changer >::m_Value.Get() ); + } + + Type *operator->() const + { + return static_cast< Type * >( CNetworkHandleBase< Type, Changer >::m_Value.Get() ); + } + + bool operator==( const Type *val ) const + { + return CNetworkHandleBase< Type, Changer >::m_Value == val; + } + + bool operator!=( const Type *val ) const + { + return CNetworkHandleBase< Type, Changer >::m_Value != val; + } +}; -// Use this macro to define a network variable. -#define CNetworkVar( type, name ) \ - NETWORK_VAR_START( type, name ) \ - NETWORK_VAR_END( type, name, CNetworkVarBase, NetworkStateChanged ) +#define CNetworkHandle( type, name ) CNetworkHandleInternal( type, name, NetworkStateChanged ) + +#define CNetworkHandleInternal( type, name, stateChangedFn ) \ + NETWORK_VAR_START( type, name ) \ + NETWORK_VAR_END( type, name, CNetworkHandleBase, stateChangedFn ) +#endif +// Use this macro to define a network variable. +#define CNetworkVar( type, name ) \ + NETWORK_VAR_START( type, name ) \ + NETWORK_VAR_END( type, name, CNetworkVarBase, NetworkStateChanged ) // Use this macro when you have a base class with a variable, and it doesn't have that variable in a SendTable, // but a derived class does. Then, the entity is only flagged as changed when the variable is changed in // an entity that wants to transmit the variable. - #define CNetworkVarForDerived( type, name ) \ - virtual void NetworkStateChanged_##name() {} \ - virtual void NetworkStateChanged_##name( void *pVar ) {} \ - NETWORK_VAR_START( type, name ) \ - NETWORK_VAR_END( type, name, CNetworkVarBase, NetworkStateChanged_##name ) - - #define CNetworkVectorForDerived( name ) \ - virtual void NetworkStateChanged_##name() {} \ - virtual void NetworkStateChanged_##name( void *pVar ) {} \ - CNetworkVectorInternal( Vector, name, NetworkStateChanged_##name ) - - #define CNetworkHandleForDerived( type, name ) \ - virtual void NetworkStateChanged_##name() {} \ - virtual void NetworkStateChanged_##name( void *pVar ) {} \ - CNetworkHandleInternal( type, name, NetworkStateChanged_##name ) - - #define CNetworkArrayForDerived( type, name, count ) \ - virtual void NetworkStateChanged_##name() {} \ - virtual void NetworkStateChanged_##name( void *pVar ) {} \ - CNetworkArrayInternal( type, name, count, NetworkStateChanged_##name ) - - #define IMPLEMENT_NETWORK_VAR_FOR_DERIVED( name ) \ - virtual void NetworkStateChanged_##name() { CHECK_USENETWORKVARS NetworkStateChanged(); } \ - virtual void NetworkStateChanged_##name( void *pVar ) { CHECK_USENETWORKVARS NetworkStateChanged( pVar ); } - +#define CNetworkVarForDerived( type, name ) \ + virtual void NetworkStateChanged_##name() {} \ + virtual void NetworkStateChanged_##name( void *pVar ) {} \ + NETWORK_VAR_START( type, name ) \ + NETWORK_VAR_END( type, name, CNetworkVarBase, NetworkStateChanged_##name ) + +#define CNetworkVectorForDerived( name ) \ + virtual void NetworkStateChanged_##name() {} \ + virtual void NetworkStateChanged_##name( void *pVar ) {} \ + CNetworkVectorInternal( Vector, name, NetworkStateChanged_##name ) + +#define CNetworkHandleForDerived( type, name ) \ + virtual void NetworkStateChanged_##name() {} \ + virtual void NetworkStateChanged_##name( void *pVar ) {} \ + CNetworkHandleInternal( type, name, NetworkStateChanged_##name ) + +#define CNetworkArrayForDerived( type, name, count ) \ + virtual void NetworkStateChanged_##name() {} \ + virtual void NetworkStateChanged_##name( void *pVar ) {} \ + CNetworkArrayInternal( type, name, count, NetworkStateChanged_##name ) + +#define IMPLEMENT_NETWORK_VAR_FOR_DERIVED( name ) \ + virtual void NetworkStateChanged_##name() \ + { \ + CHECK_USENETWORKVARS NetworkStateChanged(); \ + } \ + virtual void NetworkStateChanged_##name( void *pVar ) \ + { \ + CHECK_USENETWORKVARS NetworkStateChanged( pVar ); \ + } // This virtualizes the change detection on the variable, but it is ON by default. // Use this when you have a base class in which MOST of its derived classes use this variable // in their SendTables, but there are a couple that don't (and they // can use DISABLE_NETWORK_VAR_FOR_DERIVED). - #define CNetworkVarForDerived_OnByDefault( type, name ) \ - virtual void NetworkStateChanged_##name() { CHECK_USENETWORKVARS NetworkStateChanged(); } \ - virtual void NetworkStateChanged_##name( void *pVar ) { CHECK_USENETWORKVARS NetworkStateChanged( pVar ); } \ - NETWORK_VAR_START( type, name ) \ - NETWORK_VAR_END( type, name, CNetworkVarBase, NetworkStateChanged_##name ) - - #define DISABLE_NETWORK_VAR_FOR_DERIVED( name ) \ - virtual void NetworkStateChanged_##name() {} \ - virtual void NetworkStateChanged_##name( void *pVar ) {} - - +#define CNetworkVarForDerived_OnByDefault( type, name ) \ + virtual void NetworkStateChanged_##name() \ + { \ + CHECK_USENETWORKVARS NetworkStateChanged(); \ + } \ + virtual void NetworkStateChanged_##name( void *pVar ) \ + { \ + CHECK_USENETWORKVARS NetworkStateChanged( pVar ); \ + } \ + NETWORK_VAR_START( type, name ) \ + NETWORK_VAR_END( type, name, CNetworkVarBase, NetworkStateChanged_##name ) + +#define DISABLE_NETWORK_VAR_FOR_DERIVED( name ) \ + virtual void NetworkStateChanged_##name() {} \ + virtual void NetworkStateChanged_##name( void *pVar ) {} // Vectors + some convenient helper functions. #define CNetworkVector( name ) CNetworkVectorInternal( Vector, name, NetworkStateChanged ) #define CNetworkQAngle( name ) CNetworkVectorInternal( QAngle, name, NetworkStateChanged ) #define CNetworkVectorInternal( type, name, stateChangedFn ) \ - NETWORK_VAR_START( type, name ) \ - NETWORK_VAR_END( type, name, CNetworkVectorBase, stateChangedFn ) + NETWORK_VAR_START( type, name ) \ + NETWORK_VAR_END( type, name, CNetworkVectorBase, stateChangedFn ) -#define CNetworkQuaternion( name ) \ - NETWORK_VAR_START( Quaternion, name ) \ - NETWORK_VAR_END( Quaternion, name, CNetworkQuaternionBase, NetworkStateChanged ) +#define CNetworkQuaternion( name ) \ + NETWORK_VAR_START( Quaternion, name ) \ + NETWORK_VAR_END( Quaternion, name, CNetworkQuaternionBase, NetworkStateChanged ) // Helper for color32's. Contains GetR(), SetR(), etc.. functions. -#define CNetworkColor32( name ) \ - NETWORK_VAR_START( color32, name ) \ - NETWORK_VAR_END( color32, name, CNetworkColor32Base, NetworkStateChanged ) - - -#define CNetworkString( name, length ) \ - class NetworkVar_##name; \ - friend class NetworkVar_##name; \ - typedef ThisClass MakeANetworkVar_##name; \ - class NetworkVar_##name \ - { \ - public: \ - NetworkVar_##name() { m_Value[0] = '\0'; } \ - operator const char*() const { return m_Value; } \ - const char* Get() const { return m_Value; } \ - char* GetForModify() \ - { \ - NetworkStateChanged(); \ - return m_Value; \ - } \ - protected: \ - inline void NetworkStateChanged() \ - { \ - CHECK_USENETWORKVARS ((ThisClass*)(((char*)this) - MyOffsetOf(ThisClass,name)))->NetworkStateChanged(); \ - } \ - private: \ - char m_Value[length]; \ - }; \ - NetworkVar_##name name; - - - +#define CNetworkColor32( name ) \ + NETWORK_VAR_START( color32, name ) \ + NETWORK_VAR_END( color32, name, CNetworkColor32Base, NetworkStateChanged ) + +#define CNetworkString( name, length ) \ + class NetworkVar_##name; \ + friend class NetworkVar_##name; \ + typedef ThisClass MakeANetworkVar_##name; \ + class NetworkVar_##name \ + { \ + public: \ + NetworkVar_##name() \ + { \ + m_Value[0] = '\0'; \ + } \ + operator const char *() const \ + { \ + return m_Value; \ + } \ + const char *Get() const \ + { \ + return m_Value; \ + } \ + char *GetForModify() \ + { \ + NetworkStateChanged(); \ + return m_Value; \ + } \ + \ + protected: \ + inline void NetworkStateChanged() \ + { \ + CHECK_USENETWORKVARS( ( ThisClass * )( ( ( char * )this ) - MyOffsetOf( ThisClass, name ) ) )->NetworkStateChanged(); \ + } \ + \ + private: \ + char m_Value[length]; \ + }; \ + NetworkVar_##name name; // Use this to define networked arrays. // You can access elements for reading with operator[], and you can set elements with the Set() function. -#define CNetworkArrayInternal( type, name, count, stateChangedFn ) \ - class NetworkVar_##name; \ - friend class NetworkVar_##name; \ - typedef ThisClass MakeANetworkVar_##name; \ - class NetworkVar_##name \ - { \ - public: \ - inline NetworkVar_##name() \ - { \ - for ( int i = 0 ; i < count ; ++i ) \ - NetworkVarConstruct( m_Value[i] ); \ - } \ - template friend int ServerClassInit(T *); \ - const type& operator[]( int i ) const \ - { \ - return Get( i ); \ - } \ - \ - const type& Get( int i ) const \ - { \ - Assert( i >= 0 && i < count ); \ - return m_Value[i]; \ - } \ - \ - type& GetForModify( int i ) \ - { \ - Assert( i >= 0 && i < count ); \ - NetworkStateChanged( i ); \ - return m_Value[i]; \ - } \ - \ - void Set( int i, const type &val ) \ - { \ - Assert( i >= 0 && i < count ); \ - if( memcmp( &m_Value[i], &val, sizeof(type) ) ) \ - { \ - NetworkStateChanged( i ); \ - m_Value[i] = val; \ - } \ - } \ - const type* Base() const { return m_Value; } \ - int Count() const { return count; } \ - protected: \ - inline void NetworkStateChanged( int index ) \ - { \ - CHECK_USENETWORKVARS ((ThisClass*)(((char*)this) - MyOffsetOf(ThisClass,name)))->stateChangedFn( &m_Value[index] ); \ - } \ - type m_Value[count]; \ - }; \ - NetworkVar_##name name; - - -#define CNetworkArray( type, name, count ) CNetworkArrayInternal( type, name, count, NetworkStateChanged ) - +#define CNetworkArrayInternal( type, name, count, stateChangedFn ) \ + class NetworkVar_##name; \ + friend class NetworkVar_##name; \ + typedef ThisClass MakeANetworkVar_##name; \ + class NetworkVar_##name \ + { \ + public: \ + inline NetworkVar_##name() \ + { \ + for ( int i = 0; i < count; ++i ) \ + NetworkVarConstruct( m_Value[i] ); \ + } \ + template < typename T > \ + friend int ServerClassInit( T * ); \ + const type &operator[]( int i ) const \ + { \ + return Get( i ); \ + } \ + \ + const type &Get( int i ) const \ + { \ + Assert( i >= 0 && i < count ); \ + return m_Value[i]; \ + } \ + \ + type &GetForModify( int i ) \ + { \ + Assert( i >= 0 && i < count ); \ + NetworkStateChanged( i ); \ + return m_Value[i]; \ + } \ + \ + void Set( int i, const type &val ) \ + { \ + Assert( i >= 0 && i < count ); \ + if ( memcmp( &m_Value[i], &val, sizeof( type ) ) ) \ + { \ + NetworkStateChanged( i ); \ + m_Value[i] = val; \ + } \ + } \ + const type *Base() const \ + { \ + return m_Value; \ + } \ + int Count() const \ + { \ + return count; \ + } \ + \ + protected: \ + inline void NetworkStateChanged( int index ) \ + { \ + CHECK_USENETWORKVARS( ( ThisClass * )( ( ( char * )this ) - MyOffsetOf( ThisClass, name ) ) )->stateChangedFn( &m_Value[index] ); \ + } \ + type m_Value[count]; \ + }; \ + NetworkVar_##name name; + +#define CNetworkArray( type, name, count ) CNetworkArrayInternal( type, name, count, NetworkStateChanged ) // Internal macros used in definitions of network vars. -#define NETWORK_VAR_START( type, name ) \ - class NetworkVar_##name; \ - friend class NetworkVar_##name; \ - typedef ThisClass MakeANetworkVar_##name; \ - class NetworkVar_##name \ - { \ - public: \ - template friend int ServerClassInit(T *); - - -#define NETWORK_VAR_END( type, name, base, stateChangedFn ) \ - public: \ - static inline void NetworkStateChanged( void *ptr ) \ - { \ - CHECK_USENETWORKVARS ((ThisClass*)(((char*)ptr) - MyOffsetOf(ThisClass,name)))->stateChangedFn( ptr ); \ - } \ - }; \ - base< type, NetworkVar_##name > name; - - - -#endif // NETWORKVAR_H +#define NETWORK_VAR_START( type, name ) \ + class NetworkVar_##name; \ + friend class NetworkVar_##name; \ + typedef ThisClass MakeANetworkVar_##name; \ + class NetworkVar_##name \ + { \ + public: \ + template < typename T > \ + friend int ServerClassInit( T * ); + +#define NETWORK_VAR_END( type, name, base, stateChangedFn ) \ + public: \ + static inline void NetworkStateChanged( void *ptr ) \ + { \ + CHECK_USENETWORKVARS( ( ThisClass * )( ( ( char * )ptr ) - MyOffsetOf( ThisClass, name ) ) )->stateChangedFn( ptr ); \ + } \ + } \ + ; \ + base< type, NetworkVar_##name > name; + +#endif // NETWORKVAR_H