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.

341 lines
9.4 KiB

  1. //===================== Copyright (c) Valve Corporation. All Rights Reserved. ======================
  2. //
  3. // Included by networkvar.h
  4. //
  5. //==================================================================================================
  6. #ifndef NETWORKVAR_VECTOR_H
  7. #define NETWORKVAR_VECTOR_H
  8. #ifdef _WIN32
  9. #pragma once
  10. #endif
  11. // This is the normal case.. you've got a SendPropVector to match your CNetworkVector
  12. #define CNetworkVector( name ) CNetworkVectorInternal( Vector, name, NetworkStateChanged, CNetworkVectorBase )
  13. // This variant of a CNetworkVector should be used if you want to use SendPropFloat
  14. // on each individual component of the vector.
  15. #define CNetworkVectorXYZ( name ) CNetworkVectorInternal( Vector, name, NetworkStateChanged, CNetworkVectorXYZBase )
  16. // This variant of a CNetworkVector should be used if you want to use SendPropVectorXY
  17. // for the XY components and SendPropFloat for the Z component.
  18. #define CNetworkVectorXY_SeparateZ( name ) CNetworkVectorInternal( Vector, name, NetworkStateChanged, CNetworkVectorXY_SeparateZBase )
  19. // This is the normal case.. you've got a SendPropQAngle to match your CNetworkQAngle
  20. #define CNetworkQAngle( name ) CNetworkVectorInternal( QAngle, name, NetworkStateChanged, CNetworkVectorBase )
  21. // This variant of a CNetworkQAngle should be used if you want to use SendPropFloat
  22. // on each individual component of the vector.
  23. #define CNetworkQAngleXYZ( name ) CNetworkVectorInternal( QAngle, name, NetworkStateChanged, CNetworkVectorXYZBase )
  24. //
  25. // Use these variants if you want the networkvar to not trigger a change in the baseclass
  26. // version but you might want it to trigger changes in derived classes that do network that variable.
  27. //
  28. #define CNetworkVectorForDerived( name ) \
  29. virtual void NetworkStateChanged_##name() {} \
  30. virtual void NetworkStateChanged_##name( void *pVar ) {} \
  31. CNetworkVectorInternal( Vector, name, NetworkStateChanged_##name, CNetworkVectorBase )
  32. #define CNetworkVectorXYZForDerived( name ) \
  33. virtual void NetworkStateChanged_##name() {} \
  34. virtual void NetworkStateChanged_##name( void *pVar ) {} \
  35. CNetworkVectorInternal( Vector, name, NetworkStateChanged_##name, CNetworkVectorXYZBase )
  36. #define CNetworkVectorInternal( type, name, stateChangedFn, baseClass ) \
  37. NETWORK_VAR_START( type, name ) \
  38. NETWORK_VAR_END( type, name, baseClass, stateChangedFn )
  39. // Network vector wrapper.
  40. //
  41. // The common base is shared between all CNetworkVectors.
  42. // It includes everything but the Set() and operator=() functions,
  43. // because the behavior of each of those is different for each vector type.
  44. template< class Type, class Changer >
  45. class CNetworkVectorCommonBase : public CNetworkVarBase< Type, Changer >
  46. {
  47. typedef CNetworkVarBase< Type, Changer > base;
  48. public:
  49. FORCEINLINE void Init( float ix=0, float iy=0, float iz=0 )
  50. {
  51. base::Set( Type( ix, iy, iz ) );
  52. }
  53. FORCEINLINE float GetX() const { return this->m_Value.x; }
  54. FORCEINLINE float GetY() const { return this->m_Value.y; }
  55. FORCEINLINE float GetZ() const { return this->m_Value.z; }
  56. FORCEINLINE float operator[]( int i ) const { return this->m_Value[i]; }
  57. FORCEINLINE bool operator==( const Type &val ) const
  58. {
  59. return this->m_Value == (Type)val;
  60. }
  61. FORCEINLINE bool operator!=( const Type &val ) const
  62. {
  63. return this->m_Value != (Type)val;
  64. }
  65. FORCEINLINE const Type operator+( const Type &val ) const
  66. {
  67. return this->m_Value + val;
  68. }
  69. FORCEINLINE const Type operator-( const Type &val ) const
  70. {
  71. return this->m_Value - val;
  72. }
  73. FORCEINLINE const Type operator*( const Type &val ) const
  74. {
  75. return this->m_Value * val;
  76. }
  77. FORCEINLINE const Type& operator*=( float val )
  78. {
  79. return base::Set( this->m_Value * val );
  80. }
  81. FORCEINLINE const Type operator*( float val ) const
  82. {
  83. return this->m_Value * val;
  84. }
  85. FORCEINLINE const Type operator/( const Type &val ) const
  86. {
  87. return this->m_Value / val;
  88. }
  89. protected:
  90. FORCEINLINE void DetectChange( float &out, float in )
  91. {
  92. if ( out != in )
  93. {
  94. this->NetworkStateChanged();
  95. out = in;
  96. }
  97. }
  98. };
  99. //
  100. // This is for a CNetworkVector that only generates one change offset.
  101. // It should only ever be used with SendPropVector/QAngle.
  102. //
  103. // Single-component things like SendPropFloat should never refer to it because
  104. // they require the network var to report an offset for each component.
  105. //
  106. template< class Type, class Changer >
  107. class CNetworkVectorBase : public CNetworkVectorCommonBase< Type, Changer >
  108. {
  109. typedef CNetworkVarBase< Type, Changer > base;
  110. public:
  111. static FORCEINLINE int GetNetworkVarFlags() { return NETWORKVAR_IS_A_VECTOR; }
  112. FORCEINLINE const Type& operator=( const Type &val )
  113. {
  114. return base::Set( val );
  115. }
  116. FORCEINLINE const Type& operator=( const CNetworkVectorBase<Type,Changer> &val )
  117. {
  118. return base::Set( val.m_Value );
  119. }
  120. FORCEINLINE void SetX( float val ) { this->DetectChange( this->m_Value.x, val ); }
  121. FORCEINLINE void SetY( float val ) { this->DetectChange( this->m_Value.y, val ); }
  122. FORCEINLINE void SetZ( float val ) { this->DetectChange( this->m_Value.z, val ); }
  123. FORCEINLINE void Set( int i, float val ) { this->DetectChange( this->m_Value[i], val ); }
  124. FORCEINLINE const Type& operator*=( float val )
  125. {
  126. return base::Set( this->m_Value * val );
  127. }
  128. };
  129. //
  130. // This variant of a CNetworkVector should be used if you want to use SendPropFloat
  131. // on each individual component of the vector.
  132. //
  133. template< class Type, class Changer >
  134. class CNetworkVectorXYZBase : public CNetworkVectorCommonBase< Type, Changer >
  135. {
  136. typedef CNetworkVectorCommonBase< Type, Changer > base;
  137. public:
  138. static FORCEINLINE int GetNetworkVarFlags() { return NETWORKVAR_IS_A_VECTOR | NETWORKVAR_VECTOR_XYZ_FLAG; }
  139. FORCEINLINE const Type& operator=( const Type &val )
  140. {
  141. return Set( val );
  142. }
  143. FORCEINLINE const Type& operator=( const CNetworkVectorBase<Type,Changer> &val )
  144. {
  145. return Set( val.m_Value );
  146. }
  147. FORCEINLINE const Type& Set( const Type &val )
  148. {
  149. SetX( val.x );
  150. SetY( val.y );
  151. SetZ( val.z );
  152. return this->m_Value;
  153. }
  154. FORCEINLINE Type& GetForModify()
  155. {
  156. this->NetworkStateChanged( &((float*)this)[0] );
  157. this->NetworkStateChanged( &((float*)this)[1] );
  158. this->NetworkStateChanged( &((float*)this)[2] );
  159. return this->m_Value;
  160. }
  161. FORCEINLINE const Type& SetDirect( const Type &val )
  162. {
  163. GetForModify() = val;
  164. return this->m_Value;
  165. }
  166. FORCEINLINE void SetX( float val ) { DetectChange( 0, val ); }
  167. FORCEINLINE void SetY( float val ) { DetectChange( 1, val ); }
  168. FORCEINLINE void SetZ( float val ) { DetectChange( 2, val ); }
  169. FORCEINLINE void Set( int i, float val ) { DetectChange( i, val ); }
  170. FORCEINLINE const Type& operator+=( const Type &val )
  171. {
  172. return Set( this->m_Value + val );
  173. }
  174. FORCEINLINE const Type& operator-=( const Type &val )
  175. {
  176. return Set( this->m_Value - val );
  177. }
  178. FORCEINLINE const Type& operator*=( float val )
  179. {
  180. return Set( this->m_Value * val );
  181. }
  182. FORCEINLINE const Type& operator/=( float val )
  183. {
  184. return Set( this->m_Value / val );
  185. }
  186. private:
  187. FORCEINLINE void DetectChange( int nComponent, float in )
  188. {
  189. float *pVar = &((float*)this)[nComponent];
  190. if ( *pVar != in )
  191. {
  192. if ( pVar != &((float*)this)[0] )
  193. {
  194. this->NetworkStateChanged( &((float*)this)[0] ); // Always mark the start of the vector as changed
  195. }
  196. this->NetworkStateChanged( pVar );
  197. *pVar = in;
  198. }
  199. }
  200. };
  201. //
  202. // This variant of a CNetworkVector should be used if you want to use SendPropVectorXY
  203. // for the XY components and SendPropFloat for the Z component.
  204. //
  205. template< class Type, class Changer >
  206. class CNetworkVectorXY_SeparateZBase : public CNetworkVectorCommonBase< Type, Changer >
  207. {
  208. typedef CNetworkVectorCommonBase< Type, Changer > base;
  209. public:
  210. static FORCEINLINE int GetNetworkVarFlags() { return NETWORKVAR_IS_A_VECTOR | NETWORKVAR_VECTOR_XY_SEPARATEZ_FLAG; }
  211. FORCEINLINE const Type& operator=( const Type &val )
  212. {
  213. return Set( val );
  214. }
  215. FORCEINLINE const Type& operator=( const CNetworkVectorBase<Type,Changer> &val )
  216. {
  217. return Set( val.m_Value );
  218. }
  219. FORCEINLINE const Type& Set( const Type &val )
  220. {
  221. SetX( val.x );
  222. SetY( val.y );
  223. SetZ( val.z );
  224. return this->m_Value;
  225. }
  226. FORCEINLINE Type& GetForModify()
  227. {
  228. this->NetworkStateChanged( &((float*)this)[0] ); // Mark the offset of our XY SendProp as changed.
  229. this->NetworkStateChanged( &((float*)this)[2] ); // Mark the offset of our Z SendProp as changed.
  230. return this->m_Value;
  231. }
  232. FORCEINLINE const Type& SetDirect( const Type &val )
  233. {
  234. GetForModify() = val;
  235. return this->m_Value;
  236. }
  237. FORCEINLINE void SetX( float val ) { DetectChange( 0, val ); }
  238. FORCEINLINE void SetY( float val ) { DetectChange( 1, val ); }
  239. FORCEINLINE void SetZ( float val ) { DetectChange( 2, val ); }
  240. FORCEINLINE void Set( int i, float val ) { DetectChange( i, val ); }
  241. FORCEINLINE const Type& operator+=( const Type &val )
  242. {
  243. return Set( this->m_Value + val );
  244. }
  245. FORCEINLINE const Type& operator-=( const Type &val )
  246. {
  247. return Set( this->m_Value - val );
  248. }
  249. FORCEINLINE const Type& operator*=( float val )
  250. {
  251. return Set( this->m_Value * val );
  252. }
  253. FORCEINLINE const Type& operator/=( float val )
  254. {
  255. return Set( this->m_Value / val );
  256. }
  257. private:
  258. FORCEINLINE void DetectChange( int nComponent, float in )
  259. {
  260. float *pVar = &((float*)this)[nComponent];
  261. if ( *pVar != in )
  262. {
  263. this->NetworkStateChanged( &((float*)this)[0] ); // Mark the offset of our XY SendProp as changed.
  264. this->NetworkStateChanged( &((float*)this)[2] ); // Mark the offset of our Z SendProp as changed.
  265. *pVar = in;
  266. }
  267. }
  268. };
  269. #endif // NETWORKVAR_VECTOR_H