Counter Strike : Global Offensive Source Code
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.

1161 lines
28 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================//
  6. #ifndef SHAREDVAR_H
  7. #define SHAREDVAR_H
  8. #ifdef _WIN32
  9. #pragma once
  10. #endif
  11. #include "convar.h"
  12. #include "ispsharedmemory.h"
  13. #include "basehandle.h"
  14. #include "isaverestore.h"
  15. #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)
  16. #if defined( GAME_DLL )
  17. static int Server_EHandleToInt( const EHANDLE &hIn )
  18. {
  19. if ( hIn.Get() )
  20. {
  21. int iSerialNum = hIn.GetSerialNumber() & (1 << NUM_NETWORKED_EHANDLE_SERIAL_NUMBER_BITS) - 1;
  22. return ( hIn.GetEntryIndex() | (iSerialNum << MAX_EDICT_BITS) );
  23. }
  24. else
  25. {
  26. return INVALID_NETWORKED_EHANDLE_VALUE;
  27. }
  28. }
  29. #endif
  30. #if defined( CLIENT_DLL )
  31. static EHANDLE Client_IntToEHandle( int iIn )
  32. {
  33. if ( iIn == INVALID_NETWORKED_EHANDLE_VALUE )
  34. {
  35. return INVALID_EHANDLE;
  36. }
  37. else
  38. {
  39. int iEntity = iIn & ((1 << MAX_EDICT_BITS) - 1);
  40. int iSerialNum = iIn >> MAX_EDICT_BITS;
  41. EHANDLE hOut;
  42. hOut.Init( iEntity, iSerialNum );
  43. return hOut;
  44. }
  45. }
  46. #endif
  47. class CSharedVarSaveDataOps;
  48. // Templated save/restore functions for shared vars (add specializations as needed)
  49. template< class Type >
  50. TEMPLATE_STATIC void SharedVar_Save( ISave *pSave, Type *pValue, int iCount = 1 )
  51. {
  52. int iNumBytes = sizeof( Type ) * iCount;
  53. pSave->WriteInt( &iNumBytes );
  54. pSave->WriteData( (char*)( (void*)(pValue) ), iNumBytes );
  55. }
  56. template< class Type >
  57. TEMPLATE_STATIC void SharedVar_Restore( IRestore *pRestore, Type *pValue )
  58. {
  59. int iNumBytes = pRestore->ReadInt();
  60. pRestore->ReadData( (char*)( (void*)(pValue) ), iNumBytes, 0 );
  61. }
  62. template< class Type >
  63. TEMPLATE_STATIC bool SharedVar_IsEmpty( Type *pValue, int iCount = 1 )
  64. {
  65. char *pChar = (char*)( (void*)(pValue) );
  66. int iNumBytes = sizeof( Type ) * iCount;
  67. for ( int i = 0; i < iNumBytes; ++i )
  68. {
  69. if ( pChar[i] )
  70. {
  71. return false;
  72. }
  73. }
  74. return true;
  75. }
  76. template< class Type >
  77. TEMPLATE_STATIC void SharedVar_MakeEmpty( Type *pValue, int iCount = 1 )
  78. {
  79. memset( pValue, 0, sizeof( Type ) * iCount );
  80. }
  81. #ifdef GNUC
  82. #define SELECTOR __attribute__((weak))
  83. #else
  84. #define SELECTOR
  85. #endif
  86. // EHANDLE Save/Restore specializations
  87. template<>
  88. SELECTOR TEMPLATE_STATIC void SharedVar_Save<EHANDLE>( ISave *pSave, EHANDLE *pValue, int iCount )
  89. {
  90. pSave->WriteInt( &iCount );
  91. pSave->WriteEHandle( pValue, iCount );
  92. }
  93. template<>
  94. SELECTOR TEMPLATE_STATIC void SharedVar_Restore<EHANDLE>( IRestore *pRestore, EHANDLE *pValue )
  95. {
  96. int iCount = pRestore->ReadInt();
  97. pRestore->ReadEHandle( pValue, iCount );
  98. }
  99. // UtlVector Save/Restore specializations
  100. template< class Type > void SharedVar_SaveUtlVector( ISave *pSave, CUtlVector<Type> *pValue, int iCount = 1 )
  101. {
  102. Assert( iCount == 1 );
  103. int iNumBytes = sizeof( Type ) * pValue->Count();
  104. pSave->WriteInt( &iNumBytes );
  105. pSave->WriteData( (char*)( (void*)(pValue->Base()) ), iNumBytes );
  106. }
  107. template< class Type > void SharedVar_RestoreUtlVector( IRestore *pRestore, CUtlVector<Type> *pValue )
  108. {
  109. int iNumBytes = pRestore->ReadInt();
  110. pValue->SetCount( iNumBytes / sizeof( Type ) );
  111. pRestore->ReadData( (char*)( (void*)(pValue->Base()) ), iNumBytes, 0 );
  112. }
  113. template< class Type >
  114. TEMPLATE_STATIC bool SharedVar_IsEmptyUtlVector( CUtlVector<Type> *pValue, int iCount = 1 )
  115. {
  116. Assert( iCount == 1 );
  117. return ( pValue->Count() == 0 );
  118. }
  119. template< class Type >
  120. TEMPLATE_STATIC void SharedVar_MakeEmptyUtlVector( CUtlVector<Type> *pValue, int iCount = 1 )
  121. {
  122. Assert( iCount == 1 );
  123. pValue->SetCount( 0 );
  124. }
  125. abstract_class ISharedVarBase
  126. {
  127. private:
  128. virtual void _Save( ISave *pSave ) = 0;
  129. virtual void _Restore( IRestore *pRestore ) = 0;
  130. virtual bool _IsEmpty( void ) = 0;
  131. virtual void _MakeEmpty( void ) = 0;
  132. public:
  133. friend class CSharedVarSaveDataOps;
  134. };
  135. template< class Type, class Changer >
  136. class CSharedVarBase : public ISharedVarBase
  137. {
  138. public:
  139. CSharedVarBase( void )
  140. {
  141. m_pSharedMemory = NULL;
  142. m_pValue = NULL;
  143. }
  144. ~CSharedVarBase( void )
  145. {
  146. if ( m_pSharedMemory )
  147. {
  148. m_pSharedMemory->Release();
  149. m_pSharedMemory = NULL;
  150. }
  151. m_pValue = NULL;
  152. }
  153. void Initialize( char *pchName, int iEntNum )
  154. {
  155. Assert( !m_pSharedMemory && !m_pValue );
  156. m_pSharedMemory = engine->GetSinglePlayerSharedMemorySpace( pchName, iEntNum );
  157. m_pSharedMemory->Init( sizeof( Type ) );
  158. m_pValue = (Type*)m_pSharedMemory->Base();
  159. }
  160. #if defined( GAME_DLL )
  161. // Data can only be set on the server
  162. template< class C >
  163. const Type& operator=( const C &val )
  164. {
  165. return Set( static_cast<const Type>( val ) );
  166. }
  167. template< class C >
  168. const Type& operator=( const CNetworkVarBase< C, Changer > &val )
  169. {
  170. return Set( static_cast<const Type>( *val.m_pValue ) );
  171. }
  172. const Type& Set( const Type &val )
  173. {
  174. *m_pValue = val;
  175. return *m_pValue;
  176. }
  177. template< class C >
  178. const Type& operator+=( const C &val )
  179. {
  180. return Set( *m_pValue + static_cast<const Type>( val ) );
  181. }
  182. template< class C >
  183. const Type& operator-=( const C &val )
  184. {
  185. return Set( *m_pValue - static_cast<const Type>( val ) );
  186. }
  187. template< class C >
  188. const Type& operator/=( const C &val )
  189. {
  190. return Set( *m_pValue / static_cast<const Type>( val ) );
  191. }
  192. template< class C >
  193. const Type& operator*=( const C &val )
  194. {
  195. return Set( *m_pValue * static_cast<const Type>( val ) );
  196. }
  197. template< class C >
  198. const Type& operator^=( const C &val )
  199. {
  200. return Set( *m_pValue ^ static_cast<const Type>( val ) );
  201. }
  202. template< class C >
  203. const Type& operator|=( const C &val )
  204. {
  205. return Set( *m_pValue | static_cast<const Type>( val ) );
  206. }
  207. const Type& operator++()
  208. {
  209. return (*this += 1);
  210. }
  211. Type operator--()
  212. {
  213. return (*this -= 1);
  214. }
  215. Type operator++( int ) // postfix version..
  216. {
  217. Type val = *m_pValue;
  218. (*this += 1);
  219. return val;
  220. }
  221. Type operator--( int ) // postfix version..
  222. {
  223. Type val = *m_pValue;
  224. (*this -= 1);
  225. return val;
  226. }
  227. // For some reason the compiler only generates type conversion warnings for this operator when used like
  228. // CNetworkVarBase<unsigned char> = 0x1
  229. // (it warns about converting from an int to an unsigned char).
  230. template< class C >
  231. const Type& operator&=( const C &val )
  232. {
  233. return Set( *m_pValue & static_cast<const Type>( val ) );
  234. }
  235. operator Type&()
  236. {
  237. return *m_pValue;
  238. }
  239. Type& GetForModify()
  240. {
  241. return *m_pValue;
  242. }
  243. Type* operator->()
  244. {
  245. return m_pValue;
  246. }
  247. #endif
  248. operator const Type&() const
  249. {
  250. return *m_pValue;
  251. }
  252. const Type& Get() const
  253. {
  254. return *m_pValue;
  255. }
  256. const Type* operator->() const
  257. {
  258. return m_pValue;
  259. }
  260. private:
  261. virtual void _Save( ISave *pSave ) { SharedVar_Save<Type>( pSave, m_pValue ); }
  262. virtual void _Restore( IRestore *pRestore ) { SharedVar_Restore<Type>( pRestore, m_pValue ); }
  263. virtual bool _IsEmpty( void ) { return SharedVar_IsEmpty<Type>( m_pValue ); }
  264. virtual void _MakeEmpty( void ) { SharedVar_MakeEmpty<Type>( m_pValue ); }
  265. public:
  266. ISPSharedMemory *m_pSharedMemory;
  267. Type *m_pValue;
  268. };
  269. // Shared color wrapper.
  270. template< class Type, class Changer >
  271. class CSharedColor32Base : public CSharedVarBase< Type, Changer >
  272. {
  273. public:
  274. #if defined( GAME_DLL )
  275. // Data can only be set on the server
  276. inline void Init( byte rVal, byte gVal, byte bVal )
  277. {
  278. SetR( rVal );
  279. SetG( gVal );
  280. SetB( bVal );
  281. }
  282. inline void Init( byte rVal, byte gVal, byte bVal, byte aVal )
  283. {
  284. SetR( rVal );
  285. SetG( gVal );
  286. SetB( bVal );
  287. SetA( aVal );
  288. }
  289. const Type& operator=( const Type &val )
  290. {
  291. return Set( val );
  292. }
  293. const Type& operator=( const CSharedColor32Base<Type,Changer> &val )
  294. {
  295. return CSharedVarBase<Type,Changer>::Set( *val.m_pValue );
  296. }
  297. inline void SetR( byte val ) { SetVal( CSharedColor32Base<Type,Changer>::m_pValue->r, val ); }
  298. inline void SetG( byte val ) { SetVal( CSharedColor32Base<Type,Changer>::m_pValue->g, val ); }
  299. inline void SetB( byte val ) { SetVal( CSharedColor32Base<Type,Changer>::m_pValue->b, val ); }
  300. inline void SetA( byte val ) { SetVal( CSharedColor32Base<Type,Changer>::m_pValue->a, val ); }
  301. #endif
  302. inline byte GetR() const { return CSharedColor32Base<Type,Changer>::m_pValue->r; }
  303. inline byte GetG() const { return CSharedColor32Base<Type,Changer>::m_pValue->g; }
  304. inline byte GetB() const { return CSharedColor32Base<Type,Changer>::m_pValue->b; }
  305. inline byte GetA() const { return CSharedColor32Base<Type,Changer>::m_pValue->a; }
  306. #if defined( GAME_DLL )
  307. // Data can only be set on the server
  308. private:
  309. inline void SetVal( byte &out, const byte &in )
  310. {
  311. out = in;
  312. }
  313. #endif
  314. };
  315. // Shared vector wrapper.
  316. template< class Type, class Changer >
  317. class CSharedVectorBase : public CSharedVarBase< Type, Changer >
  318. {
  319. public:
  320. #if defined( GAME_DLL )
  321. // Data can only be set on the server
  322. inline void Init( float ix=0, float iy=0, float iz=0 )
  323. {
  324. SetX( ix );
  325. SetY( iy );
  326. SetZ( iz );
  327. }
  328. const Type& operator=( const Type &val )
  329. {
  330. return CSharedVarBase< Type, Changer >::Set( val );
  331. }
  332. const Type& operator=( const CSharedVectorBase<Type,Changer> &val )
  333. {
  334. return CSharedVarBase<Type,Changer>::Set( *val.m_pValue );
  335. }
  336. inline void SetX( float val ) { SetVal( CSharedVectorBase<Type,Changer>::m_pValue->x, val ); }
  337. inline void SetY( float val ) { SetVal( CSharedVectorBase<Type,Changer>::m_pValue->y, val ); }
  338. inline void SetZ( float val ) { SetVal( CSharedVectorBase<Type,Changer>::m_pValue->z, val ); }
  339. inline void Set( int i, float val ) { SetVal( (*CSharedVectorBase<Type,Changer>::m_pValue)[i], val ); }
  340. inline float& operator[]( int i ) { return (*CSharedVectorBase<Type,Changer>::m_pValue)[i]; }
  341. const Type& operator*=( float val )
  342. {
  343. return CSharedVarBase< Type, Changer >::Set( (*CSharedVectorBase<Type,Changer>::m_pValue) * val );
  344. }
  345. #endif
  346. inline float GetX() const { return CSharedVectorBase<Type,Changer>::m_pValue->x; }
  347. inline float GetY() const { return CSharedVectorBase<Type,Changer>::m_pValue->y; }
  348. inline float GetZ() const { return CSharedVectorBase<Type,Changer>::m_pValue->z; }
  349. inline const float& operator[]( int i ) const { return (*CSharedVectorBase<Type,Changer>::m_pValue)[i]; }
  350. bool operator==( const Type &val ) const
  351. {
  352. return (*CSharedVectorBase<Type,Changer>::m_pValue) == (Type)val;
  353. }
  354. bool operator!=( const Type &val ) const
  355. {
  356. return (*CSharedVectorBase<Type,Changer>::m_pValue) != (Type)val;
  357. }
  358. const Type operator+( const Type &val ) const
  359. {
  360. return (*CSharedVectorBase<Type,Changer>::m_pValue) + val;
  361. }
  362. const Type operator-( const Type &val ) const
  363. {
  364. return (*CSharedVectorBase<Type,Changer>::m_pValue) - val;
  365. }
  366. const Type operator*( const Type &val ) const
  367. {
  368. return (*CSharedVectorBase<Type,Changer>::m_pValue) * val;
  369. }
  370. const Type operator*( float val ) const
  371. {
  372. return (*CSharedVectorBase<Type,Changer>::m_pValue) * val;
  373. }
  374. const Type operator/( const Type &val ) const
  375. {
  376. return (*CSharedVectorBase<Type,Changer>::m_pValue) / val;
  377. }
  378. #if defined( GAME_DLL )
  379. // Data can only be set on the server
  380. private:
  381. inline void SetVal( float &out, float in )
  382. {
  383. out = in;
  384. }
  385. #endif
  386. };
  387. // Shared quaternion wrapper.
  388. template< class Type, class Changer >
  389. class CSharedQuaternionBase : public CSharedVarBase< Type, Changer >
  390. {
  391. public:
  392. #if defined( GAME_DLL )
  393. // Data can only be set on the server
  394. inline void Init( float ix=0, float iy=0, float iz=0, float iw = 0 )
  395. {
  396. SetX( ix );
  397. SetY( iy );
  398. SetZ( iz );
  399. SetZ( iw );
  400. }
  401. const Type& operator=( const Type &val )
  402. {
  403. return CSharedVarBase< Type, Changer >::Set( val );
  404. }
  405. const Type& operator=( const CSharedQuaternionBase<Type,Changer> &val )
  406. {
  407. return CSharedVarBase<Type,Changer>::Set( *val.m_pValue );
  408. }
  409. const Type& operator*=( float val )
  410. {
  411. return CSharedVarBase< Type, Changer >::Set( (*CSharedQuaternionBase<Type,Changer>::m_pValue) * val );
  412. }
  413. inline void SetX( float val ) { SetVar( CSharedQuaternionBase<Type,Changer>::m_pValue->x, val ); }
  414. inline void SetY( float val ) { SetVar( CSharedQuaternionBase<Type,Changer>::m_pValue->y, val ); }
  415. inline void SetZ( float val ) { SetVar( CSharedQuaternionBase<Type,Changer>::m_pValue->z, val ); }
  416. inline void SetW( float val ) { SetVar( CSharedQuaternionBase<Type,Changer>::m_pValue->w, val ); }
  417. inline void Set( int i, float val ) { SetVar( (*CSharedQuaternionBase<Type,Changer>::m_pValue)[i], val ); }
  418. inline float& operator[]( int i ) { return (*CSharedQuaternionBase<Type,Changer>::m_pValue)[i]; }
  419. #endif
  420. inline float GetX() const { return CSharedQuaternionBase<Type,Changer>::m_pValue->x; }
  421. inline float GetY() const { return CSharedQuaternionBase<Type,Changer>::m_pValue->y; }
  422. inline float GetZ() const { return CSharedQuaternionBase<Type,Changer>::m_pValue->z; }
  423. inline float GetW() const { return CSharedQuaternionBase<Type,Changer>::m_pValue->w; }
  424. inline const float& operator[]( int i ) const { return (*CSharedQuaternionBase<Type,Changer>::m_pValue)[i]; }
  425. bool operator==( const Type &val ) const
  426. {
  427. return (*CSharedQuaternionBase<Type,Changer>::m_pValue) == (Type)val;
  428. }
  429. bool operator!=( const Type &val ) const
  430. {
  431. return (*CSharedQuaternionBase<Type,Changer>::m_pValue) != (Type)val;
  432. }
  433. const Type operator+( const Type &val ) const
  434. {
  435. return (*CSharedQuaternionBase<Type,Changer>::m_pValue) + val;
  436. }
  437. const Type operator-( const Type &val ) const
  438. {
  439. return (*CSharedQuaternionBase<Type,Changer>::m_pValue) - val;
  440. }
  441. const Type operator*( const Type &val ) const
  442. {
  443. return (*CSharedQuaternionBase<Type,Changer>::m_pValue) * val;
  444. }
  445. const Type operator*( float val ) const
  446. {
  447. return (*CSharedQuaternionBase<Type,Changer>::m_pValue) * val;
  448. }
  449. const Type operator/( const Type &val ) const
  450. {
  451. return (*CSharedQuaternionBase<Type,Changer>::m_pValue) / val;
  452. }
  453. #if defined( GAME_DLL )
  454. // Data can only be set on the server
  455. private:
  456. inline void SetVar( float &out, float in )
  457. {
  458. out = in;
  459. }
  460. #endif
  461. };
  462. // Prevent Shared Vars from using handle templates without the handle wrapper
  463. template< class Type, class Changer >
  464. class CSharedVarBase< CHandle<Type>, Changer > : public ISharedVarBase
  465. {
  466. public:
  467. CSharedVarBase( void )
  468. {
  469. m_pSharedMemory = NULL;
  470. m_pValue = NULL;
  471. }
  472. ~CSharedVarBase( void )
  473. {
  474. if ( m_pSharedMemory )
  475. {
  476. m_pSharedMemory->Release();
  477. m_pSharedMemory = NULL;
  478. }
  479. m_pValue = NULL;
  480. }
  481. protected:
  482. virtual void Shared_Handle_Vars_Must_Use_CSharedHandle_Or_CSharedHandleArray() = 0;
  483. public:
  484. ISPSharedMemory *m_pSharedMemory;
  485. CHandle<Type> *m_pValue;
  486. };
  487. // Prevent Shared Vars from using handle templates without the handle wrapper
  488. template< class Changer >
  489. class CSharedVarBase< CBaseHandle, Changer > : public ISharedVarBase
  490. {
  491. public:
  492. CSharedVarBase( void )
  493. {
  494. m_pSharedMemory = NULL;
  495. m_pValue = NULL;
  496. }
  497. ~CSharedVarBase( void )
  498. {
  499. if ( m_pSharedMemory )
  500. {
  501. m_pSharedMemory->Release();
  502. m_pSharedMemory = NULL;
  503. }
  504. m_pValue = NULL;
  505. }
  506. protected:
  507. virtual void Shared_Handle_Vars_Must_Use_CSharedHandle_Or_CSharedHandleArray() = 0;
  508. public:
  509. ISPSharedMemory *m_pSharedMemory;
  510. CBaseHandle *m_pValue;
  511. };
  512. // Shared handle wrapper.
  513. template< class Type, class Changer >
  514. class CSharedHandleBase : public CSharedVarBase< EHANDLE, Changer >
  515. {
  516. public:
  517. virtual void Shared_Handle_Vars_Must_Use_CSharedHandle_Or_CSharedHandleArray() {}
  518. void Initialize( char *pchName, int iEntNum )
  519. {
  520. Assert( !this->m_pSharedMemory && !this->m_pValue );
  521. this->m_pSharedMemory = engine->GetSinglePlayerSharedMemorySpace( pchName, iEntNum );
  522. this->m_pSharedMemory->Init( sizeof( EHANDLE ) + sizeof( int ) ); // Also allocate memory for the int that converts to a Client handle
  523. this->m_pValue = (EHANDLE*)this->m_pSharedMemory->Base();
  524. m_piClientIndex = (int*)((void*)(this->m_pValue + 1));
  525. }
  526. bool operator !() const
  527. {
  528. return !GetHandle_Internal()->Get();
  529. }
  530. #if defined( GAME_DLL )
  531. // Data can only be set on the server
  532. const Type* operator=( const Type *val )
  533. {
  534. return Set( val );
  535. }
  536. const Type& operator=( const CSharedHandleBase<Type,Changer> &val )
  537. {
  538. const EHANDLE &handle = CSharedVarBase<EHANDLE,Changer>::Set( *val.m_pValue );
  539. return *(const Type*)handle.Get();
  540. }
  541. const Type* Set( const Type *val )
  542. {
  543. (*CSharedHandleBase<Type,Changer>::m_pValue) = val;
  544. // Store the int that we'll need to translate to the EHandle on the client
  545. *m_piClientIndex = Server_EHandleToInt( *CSharedHandleBase<Type,Changer>::m_pValue );
  546. return val;
  547. }
  548. #endif
  549. operator const Type*() const
  550. {
  551. return Get_Internal();
  552. }
  553. const Type* Get() const
  554. {
  555. return Get_Internal();
  556. }
  557. const Type* operator->() const
  558. {
  559. return Get_Internal();
  560. }
  561. bool operator==( const Type *val ) const
  562. {
  563. return Get_Internal() == val;
  564. }
  565. bool operator!=( const Type *val ) const
  566. {
  567. return Get_Internal() != val;
  568. }
  569. private:
  570. EHANDLE GetHandle_Internal() const
  571. {
  572. #if defined( GAME_DLL )
  573. // Server can get the handle directly
  574. return (*CSharedHandleBase<Type,Changer>::m_pValue);
  575. #else
  576. // Client needs to get the handle translated from the stroed int
  577. EHANDLE hClient = Client_IntToEHandle( *m_piClientIndex );
  578. return hClient;
  579. #endif
  580. }
  581. Type* Get_Internal() const
  582. {
  583. return static_cast< Type* >( GetHandle_Internal().Get() );
  584. }
  585. void UpdateClientIndex( void )
  586. {
  587. *m_piClientIndex = Server_EHandleToInt( *(CSharedHandleBase<Type,Changer>::m_pValue) );
  588. }
  589. virtual void _Save( ISave *pSave )
  590. {
  591. SharedVar_Save<EHANDLE>( pSave, this->m_pValue );
  592. }
  593. virtual void _Restore( IRestore *pRestore )
  594. {
  595. SharedVar_Restore<EHANDLE>( pRestore, this->m_pValue );
  596. UpdateClientIndex();
  597. }
  598. virtual bool _IsEmpty( void )
  599. {
  600. return SharedVar_IsEmpty<EHANDLE>( this->m_pValue );
  601. }
  602. virtual void _MakeEmpty( void )
  603. {
  604. SharedVar_MakeEmpty<EHANDLE>( this->m_pValue );
  605. }
  606. public:
  607. int *m_piClientIndex; // Pointer to ints for Client handle translations
  608. };
  609. // Shared array wrapper.
  610. template< class Type, class Changer >
  611. class CSharedArrayBase : public CSharedVarBase< Type, Changer >
  612. {
  613. public:
  614. CSharedArrayBase( void )
  615. {
  616. m_iCount = 0;
  617. }
  618. void Initialize( char *pchName, int iEntNum, int iCount )
  619. {
  620. Assert( !this->m_pSharedMemory && !(CSharedArrayBase<Type,Changer>::m_pValue) && iCount > 0 );
  621. m_iCount = iCount;
  622. this->m_pSharedMemory = engine->GetSinglePlayerSharedMemorySpace( pchName, iEntNum );
  623. this->m_pSharedMemory->Init( sizeof( Type ) * m_iCount );
  624. CSharedArrayBase<Type,Changer>::m_pValue = (Type*)this->m_pSharedMemory->Base();
  625. }
  626. const int& Count() const
  627. {
  628. return m_iCount;
  629. }
  630. const Type* Get() const
  631. {
  632. return CSharedArrayBase<Type,Changer>::m_pValue;
  633. }
  634. const Type& Get( int i ) const
  635. {
  636. Assert( i >= 0 && i < m_iCount );
  637. return CSharedArrayBase<Type,Changer>::m_pValue[i];
  638. }
  639. const Type& operator[]( int i ) const
  640. {
  641. return Get( i );
  642. }
  643. #if defined( GAME_DLL )
  644. // Data can only be set on the server
  645. Type& operator[]( int i )
  646. {
  647. return GetForModify( i );
  648. }
  649. Type& GetForModify( int i )
  650. {
  651. Assert( i >= 0 && i < m_iCount );
  652. return CSharedArrayBase<Type,Changer>::m_pValue[i];
  653. }
  654. void Set( int i, const Type &val )
  655. {
  656. Assert( i >= 0 && i < m_iCount );
  657. CSharedArrayBase<Type,Changer>::m_pValue[i] = val;
  658. }
  659. #endif
  660. private:
  661. virtual void _Save( ISave *pSave )
  662. {
  663. SharedVar_Save<Type>( pSave, CSharedArrayBase<Type,Changer>::m_pValue, m_iCount );
  664. }
  665. virtual void _Restore( IRestore *pRestore )
  666. {
  667. SharedVar_Restore<Type>( pRestore, CSharedArrayBase<Type,Changer>::m_pValue );
  668. }
  669. virtual bool _IsEmpty( void )
  670. {
  671. return SharedVar_IsEmpty<Type>( CSharedArrayBase<Type,Changer>::m_pValue, m_iCount );
  672. }
  673. virtual void _MakeEmpty( void )
  674. {
  675. SharedVar_MakeEmpty<Type>( CSharedArrayBase<Type,Changer>::m_pValue, m_iCount );
  676. }
  677. public:
  678. int m_iCount;
  679. };
  680. // Shared handle array wrapper.
  681. template< class Type, class Changer >
  682. class CSharedHandleArrayBase : public CSharedArrayBase< EHANDLE, Changer >
  683. {
  684. public:
  685. virtual void Shared_Handle_Vars_Must_Use_CSharedHandle_Or_CSharedHandleArray() {}
  686. void Initialize( char *pchName, int iEntNum, int iCount )
  687. {
  688. Assert( !this->m_pSharedMemory && !(CSharedHandleArrayBase<Type,Changer>::m_pValue) && iCount > 0 );
  689. this->m_iCount = iCount;
  690. this->m_pSharedMemory = engine->GetSinglePlayerSharedMemorySpace( pchName, iEntNum );
  691. 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
  692. this->m_pValue = (EHANDLE*)this->m_pSharedMemory->Base();
  693. m_piClientIndex = (int*)((void*)(CSharedHandleArrayBase<Type,Changer>::m_pValue + this->m_iCount));
  694. }
  695. const int& Count() const
  696. {
  697. return this->m_iCount;
  698. }
  699. const Type& Get( int i ) const
  700. {
  701. Assert( i >= 0 && i < this->m_iCount );
  702. return Get_Internal( i );
  703. }
  704. const Type* operator[]( int i ) const
  705. {
  706. return Get_Internal( i );
  707. }
  708. #if defined( GAME_DLL )
  709. // Data can only be set on the server
  710. const Type* Set( int i, const Type *val )
  711. {
  712. Assert( i >= 0 && i < this->m_iCount );
  713. CSharedHandleArrayBase<Type,Changer>::m_pValue[i] = val;
  714. // Store the int that we'll need to translate to the EHandle on the client
  715. m_piClientIndex[i] = Server_EHandleToInt( CSharedHandleArrayBase<Type,Changer>::m_pValue[i] );
  716. return val;
  717. }
  718. #endif
  719. private:
  720. EHANDLE GetHandle_Internal( int i ) const
  721. {
  722. #if defined( GAME_DLL )
  723. // Server can get the handle directly
  724. return CSharedHandleArrayBase<Type,Changer>::m_pValue[i];
  725. #else
  726. // Client needs to get the handle translated from the stroed int
  727. EHANDLE hClient = Client_IntToEHandle( m_piClientIndex[i] );
  728. return hClient;
  729. #endif
  730. }
  731. Type* Get_Internal( int i ) const
  732. {
  733. return static_cast< Type* >( GetHandle_Internal(i).Get() );
  734. }
  735. private:
  736. void UpdateClientIndices( void )
  737. {
  738. for ( int i = 0; i < this->m_iConcept; ++i )
  739. {
  740. m_piClientIndex[i] = Server_EHandleToInt( CSharedHandleBase<Type,Changer>::m_pValue[i] );
  741. }
  742. }
  743. virtual void _Restore( IRestore *pRestore )
  744. {
  745. SharedVar_Restore<EHANDLE>( pRestore, CSharedHandleArrayBase<Type,Changer>::m_pValue );
  746. UpdateClientIndices();
  747. }
  748. public:
  749. int *m_piClientIndex; // Pointer to ints for Client handle translations
  750. };
  751. // Prevent Shared Vars from using UtlVector templates without the UtlVector wrapper
  752. template< class Type, class Changer >
  753. class CSharedVarBase< CUtlVector<Type>, Changer > : public ISharedVarBase
  754. {
  755. public:
  756. CSharedVarBase( void )
  757. {
  758. m_pSharedMemory = NULL;
  759. m_pValue = NULL;
  760. }
  761. ~CSharedVarBase( void )
  762. {
  763. if ( m_pSharedMemory )
  764. {
  765. m_pSharedMemory->Release();
  766. m_pSharedMemory = NULL;
  767. }
  768. m_pValue = NULL;
  769. }
  770. protected:
  771. virtual void Shared_CUtlVector_Vars_Must_Use_CSharedUtlVector() = 0;
  772. public:
  773. ISPSharedMemory *m_pSharedMemory;
  774. CUtlVector<Type> *m_pValue;
  775. };
  776. // Shared UtlVector wrapper.
  777. template< class Type, class Changer >
  778. class CSharedUtlVectorBase : public CSharedVarBase< CUtlVector<Type>, Changer >
  779. {
  780. public:
  781. void Initialize( char *pchName, int iEntNum )
  782. {
  783. Assert( !this->m_pSharedMemory && !(CSharedUtlVectorBase<Type,Changer>::m_pValue) );
  784. this->m_pSharedMemory = engine->GetSinglePlayerSharedMemorySpace( pchName, iEntNum );
  785. this->m_pSharedMemory->Init( sizeof( CUtlVector<Type> ) );
  786. CSharedUtlVectorBase<Type,Changer>::m_pValue = (CUtlVector<Type>*)this->m_pSharedMemory->Base();
  787. }
  788. #if defined( GAME_DLL )
  789. // Data can only be set on the server
  790. operator CUtlVector<Type>&()
  791. {
  792. return *CSharedUtlVectorBase<Type,Changer>::m_pValue;
  793. }
  794. CUtlVector<Type>& GetForModify()
  795. {
  796. return *CSharedUtlVectorBase<Type,Changer>::m_pValue;
  797. }
  798. CUtlVector<Type>* operator->()
  799. {
  800. return CSharedUtlVectorBase<Type,Changer>::m_pValue;
  801. }
  802. Type& operator[]( int i )
  803. {
  804. return GetForModify( i );
  805. }
  806. Type& GetForModify( int i )
  807. {
  808. Assert( i >= 0 && i < (CSharedUtlVectorBase<Type,Changer>::m_pValue)->Count() );
  809. return (*CSharedUtlVectorBase<Type,Changer>::m_pValue)[i];
  810. }
  811. void Set( int i, const Type &val )
  812. {
  813. Assert( i >= 0 && i < (CSharedUtlVectorBase<Type,Changer>::m_pValue)->Count() );
  814. (*CSharedUtlVectorBase<Type,Changer>::m_pValue)[i] = val;
  815. }
  816. #endif
  817. operator const CUtlVector<Type>&() const
  818. {
  819. return *CSharedUtlVectorBase<Type,Changer>::m_pValue;
  820. }
  821. const CUtlVector<Type>& Get() const
  822. {
  823. return *CSharedUtlVectorBase<Type,Changer>::m_pValue;
  824. }
  825. const CUtlVector<Type>* operator->() const
  826. {
  827. return CSharedUtlVectorBase<Type,Changer>::m_pValue;
  828. }
  829. const Type& operator[]( int i ) const
  830. {
  831. return Get( i );
  832. }
  833. const Type& Get( int i ) const
  834. {
  835. Assert( i >= 0 && i < (CSharedUtlVectorBase<Type,Changer>::m_pValue)->Count() );
  836. return (*CSharedUtlVectorBase<Type,Changer>::m_pValue)[i];
  837. }
  838. const int Count() const
  839. {
  840. return CSharedUtlVectorBase<Type,Changer>::m_pValue->Count();
  841. }
  842. protected:
  843. virtual void Shared_CUtlVector_Vars_Must_Use_CSharedUtlVector() {}
  844. private:
  845. virtual void _Save( ISave *pSave )
  846. {
  847. SharedVar_SaveUtlVector<Type>( pSave, CSharedUtlVectorBase<Type,Changer>::m_pValue, 1 );
  848. }
  849. virtual void _Restore( IRestore *pRestore )
  850. {
  851. SharedVar_RestoreUtlVector<Type>( pRestore, CSharedUtlVectorBase<Type,Changer>::m_pValue );
  852. }
  853. virtual bool _IsEmpty( void )
  854. {
  855. return SharedVar_IsEmptyUtlVector<Type>( CSharedUtlVectorBase<Type,Changer>::m_pValue, 1 );
  856. }
  857. virtual void _MakeEmpty( void )
  858. {
  859. SharedVar_MakeEmptyUtlVector<Type>( CSharedUtlVectorBase<Type,Changer>::m_pValue, 1 );
  860. }
  861. };
  862. // Use this macro to define a network variable.
  863. #define CSharedVar( type, name ) \
  864. SHARED_VAR_START( type, name ) \
  865. SHARED_VAR_END( type, name, CSharedVarBase )
  866. // Helper for color32's. Contains GetR(), SetR(), etc.. functions.
  867. #define CSharedColor32( name ) \
  868. SHARED_VAR_START( color32, name ) \
  869. SHARED_VAR_END( color32, name, CSharedColor32Base )
  870. // Vectors + some convenient helper functions.
  871. #define CSharedVector( name ) CSharedVectorInternal( Vector, name )
  872. #define CSharedQAngle( name ) CSharedVectorInternal( QAngle, name )
  873. #define CSharedVectorInternal( type, name ) \
  874. SHARED_VAR_START( type, name ) \
  875. SHARED_VAR_END( type, name, CSharedVectorBase )
  876. #define CSharedQuaternion( name ) \
  877. SHARED_VAR_START( Quaternion, name ) \
  878. SHARED_VAR_END( Quaternion, name, CSharedQuaternionBase )
  879. #define CSharedHandle( handletype, name ) \
  880. SHARED_VAR_START( handletype, name ) \
  881. SHARED_VAR_END( handletype, name, CSharedHandleBase )
  882. #define CSharedArray( type, name, count ) \
  883. SHARED_VAR_START( type, name ) \
  884. SHARED_VAR_END( type, name, CSharedArrayBase ) \
  885. enum { m_SharedArray_count_##name = count };
  886. #define CSharedString( name, length ) \
  887. CSharedArray( char, name, length )
  888. #define CSharedHandleArray( handletype, name, count ) \
  889. SHARED_VAR_START( handletype, name ) \
  890. SHARED_VAR_END( handletype, name, CSharedHandleArrayBase ) \
  891. enum { m_SharedArray_count_##name = count };
  892. #define CSharedUtlVector( utlvectortype, name ) \
  893. SHARED_VAR_START( utlvectortype, name ) \
  894. SHARED_VAR_END( utlvectortype, name, CSharedUtlVectorBase ) \
  895. // Internal macros used in definitions of network vars.
  896. #define SHARED_VAR_START( type, name ) \
  897. class SharedVar_##name; \
  898. friend class SharedVar_##name; \
  899. typedef ThisClass MakeASharedVar_##name; \
  900. class SharedVar_##name \
  901. { \
  902. public: \
  903. template <typename T> friend int ServerClassInit(T *);
  904. #define SHARED_VAR_END( type, name, base ) \
  905. }; \
  906. base< type, SharedVar_##name > name;
  907. #define DECLARE_SHAREDCLASS() \
  908. virtual void InitSharedVars( void );
  909. #define IMPLEMENT_SHAREDCLASS_DT( type ) \
  910. void type::InitSharedVars( void ) \
  911. { \
  912. BaseClass::InitSharedVars();
  913. #define END_SHARED_TABLE() \
  914. }
  915. #define SharedProp( var ) \
  916. var.Initialize( "SharedVar_"#var, entindex() );
  917. #define SharedPropArray( var ) \
  918. var.Initialize( "SharedVar_"#var, entindex(), m_SharedArray_count_##var );
  919. // Save/Restore handling
  920. class CSharedVarSaveDataOps : public CDefSaveRestoreOps
  921. {
  922. // saves the entire array of variables
  923. virtual void Save( const SaveRestoreFieldInfo_t &fieldInfo, ISave *pSave )
  924. {
  925. ISharedVarBase *pSharedVar = (ISharedVarBase *)fieldInfo.pField;
  926. pSharedVar->_Save( pSave );
  927. }
  928. // restores a single instance of the variable
  929. virtual void Restore( const SaveRestoreFieldInfo_t &fieldInfo, IRestore *pRestore )
  930. {
  931. ISharedVarBase *pSharedVar = (ISharedVarBase *)fieldInfo.pField;
  932. pSharedVar->_Restore( pRestore );
  933. }
  934. virtual bool IsEmpty( const SaveRestoreFieldInfo_t &fieldInfo )
  935. {
  936. ISharedVarBase *pSharedVar = (ISharedVarBase *)fieldInfo.pField;
  937. return pSharedVar->_IsEmpty();
  938. }
  939. virtual void MakeEmpty( const SaveRestoreFieldInfo_t &fieldInfo )
  940. {
  941. ISharedVarBase *pSharedVar = (ISharedVarBase *)fieldInfo.pField;
  942. return pSharedVar->_MakeEmpty();
  943. }
  944. };
  945. static CSharedVarSaveDataOps g_SharedVarSaveDataOps;
  946. #define DEFINE_SHARED_FIELD(name) \
  947. { FIELD_CUSTOM, #name, offsetof(classNameTypedef, name), 1, FTYPEDESC_SAVE, NULL, &g_SharedVarSaveDataOps, NULL }
  948. #endif // SHAREDVAR_H