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.

302 lines
8.7 KiB

  1. //===== Copyright � 1996-2005, Valve Corporation, All rights reserved. ======//
  2. //
  3. // Purpose:
  4. //
  5. // $Workfile: $
  6. // $Date: $
  7. // $NoKeywords: $
  8. //===========================================================================//
  9. #if !defined( CLIENTENTITYLIST_H )
  10. #define CLIENTENTITYLIST_H
  11. #ifdef _WIN32
  12. #pragma once
  13. #endif
  14. #include "tier0/dbg.h"
  15. #include "icliententitylist.h"
  16. #include "iclientunknown.h"
  17. #include "utllinkedlist.h"
  18. #include "utlvector.h"
  19. #include "icliententityinternal.h"
  20. #include "ispatialpartition.h"
  21. #include "cdll_util.h"
  22. #include "entitylist_base.h"
  23. #include "utlmap.h"
  24. class C_Beam;
  25. class C_BaseViewModel;
  26. class C_BaseEntity;
  27. #define INPVS_YES 0x0001 // The entity thinks it's in the PVS.
  28. #define INPVS_THISFRAME 0x0002 // Accumulated as different views are rendered during the frame and used to notify the entity if
  29. // it is not in the PVS anymore (at the end of the frame).
  30. #define INPVS_NEEDSNOTIFY 0x0004 // The entity thinks it's in the PVS.
  31. class IClientEntityListener;
  32. abstract_class C_BaseEntityClassList
  33. {
  34. public:
  35. C_BaseEntityClassList();
  36. ~C_BaseEntityClassList();
  37. virtual void LevelShutdown() = 0;
  38. C_BaseEntityClassList *m_pNextClassList;
  39. };
  40. template< class T >
  41. class C_EntityClassList : public C_BaseEntityClassList
  42. {
  43. public:
  44. virtual void LevelShutdown() { m_pClassList = NULL; }
  45. void Insert( T *pEntity )
  46. {
  47. pEntity->m_pNext = m_pClassList;
  48. m_pClassList = pEntity;
  49. }
  50. void Remove( T *pEntity )
  51. {
  52. T **pPrev = &m_pClassList;
  53. T *pCur = *pPrev;
  54. while ( pCur )
  55. {
  56. if ( pCur == pEntity )
  57. {
  58. *pPrev = pCur->m_pNext;
  59. return;
  60. }
  61. pPrev = &pCur->m_pNext;
  62. pCur = *pPrev;
  63. }
  64. }
  65. static T *m_pClassList;
  66. };
  67. // Maximum size of entity list
  68. #define INVALID_CLIENTENTITY_HANDLE CBaseHandle( INVALID_EHANDLE )
  69. //
  70. // This is the IClientEntityList implemenation. It serves two functions:
  71. //
  72. // 1. It converts server entity indices into IClientNetworkables for the engine.
  73. //
  74. // 2. It provides a place to store IClientUnknowns and gives out ClientEntityHandle_t's
  75. // so they can be indexed and retreived. For example, this is how static props are referenced
  76. // by the spatial partition manager - it doesn't know what is being inserted, so it's
  77. // given ClientEntityHandle_t's, and the handlers for spatial partition callbacks can
  78. // use the client entity list to look them up and check for supported interfaces.
  79. //
  80. class CClientEntityList : public CBaseEntityList, public IClientEntityList
  81. {
  82. friend class C_BaseEntityIterator;
  83. friend class C_AllBaseEntityIterator;
  84. public:
  85. // Constructor, destructor
  86. CClientEntityList( void );
  87. virtual ~CClientEntityList( void );
  88. void Release(); // clears everything and releases entities
  89. // Implement IClientEntityList
  90. public:
  91. virtual IClientNetworkable* GetClientNetworkable( int entnum );
  92. virtual EntityCacheInfo_t *GetClientNetworkableArray();
  93. virtual IClientEntity* GetClientEntity( int entnum );
  94. virtual int NumberOfEntities( bool bIncludeNonNetworkable = false );
  95. virtual IClientUnknown* GetClientUnknownFromHandle( ClientEntityHandle_t hEnt );
  96. virtual IClientNetworkable* GetClientNetworkableFromHandle( ClientEntityHandle_t hEnt );
  97. virtual IClientEntity* GetClientEntityFromHandle( ClientEntityHandle_t hEnt );
  98. virtual int GetHighestEntityIndex( void );
  99. virtual void SetMaxEntities( int maxents );
  100. virtual int GetMaxEntities( );
  101. // CBaseEntityList overrides.
  102. protected:
  103. virtual void OnAddEntity( IHandleEntity *pEnt, CBaseHandle handle );
  104. virtual void OnRemoveEntity( IHandleEntity *pEnt, CBaseHandle handle );
  105. // Internal to client DLL.
  106. public:
  107. // All methods of accessing specialized IClientUnknown's go through here.
  108. IClientUnknown* GetListedEntity( int entnum );
  109. // Simple wrappers for convenience..
  110. C_BaseEntity* GetBaseEntity( int entnum );
  111. ICollideable* GetCollideable( int entnum );
  112. IClientRenderable* GetClientRenderableFromHandle( ClientEntityHandle_t hEnt );
  113. C_BaseEntity* GetBaseEntityFromHandle( ClientEntityHandle_t hEnt );
  114. ICollideable* GetCollideableFromHandle( ClientEntityHandle_t hEnt );
  115. IClientThinkable* GetClientThinkableFromHandle( ClientEntityHandle_t hEnt );
  116. // Convenience methods to convert between entindex + ClientEntityHandle_t
  117. ClientEntityHandle_t EntIndexToHandle( int entnum );
  118. int HandleToEntIndex( ClientEntityHandle_t handle );
  119. // Is a handle valid?
  120. bool IsHandleValid( ClientEntityHandle_t handle ) const;
  121. // For backwards compatibility...
  122. C_BaseEntity* GetEnt( int entnum ) { return GetBaseEntity( entnum ); }
  123. void RecomputeHighestEntityUsed( void );
  124. // Use this to iterate over all the C_BaseEntities.
  125. C_BaseEntity* FirstBaseEntity() const;
  126. C_BaseEntity* NextBaseEntity( C_BaseEntity *pEnt ) const;
  127. class CPVSNotifyInfo
  128. {
  129. public:
  130. IPVSNotify *m_pNotify;
  131. IClientRenderable *m_pRenderable;
  132. unsigned char m_InPVSStatus; // Combination of the INPVS_ flags.
  133. unsigned short m_PVSNotifiersLink; // Into m_PVSNotifyInfos.
  134. };
  135. // Get the list of all PVS notifiers.
  136. CUtlLinkedList<CPVSNotifyInfo,unsigned short>& GetPVSNotifiers();
  137. CUtlVector<IClientEntityListener *> m_entityListeners;
  138. // add a class that gets notified of entity events
  139. void AddListenerEntity( IClientEntityListener *pListener );
  140. void RemoveListenerEntity( IClientEntityListener *pListener );
  141. void NotifyCreateEntity( C_BaseEntity *pEnt );
  142. void NotifyRemoveEntity( C_BaseEntity *pEnt );
  143. void SetDormant( int entityIndex, bool bDormant );
  144. private:
  145. // Current count
  146. int m_iNumServerEnts;
  147. // Max allowed
  148. int m_iMaxServerEnts;
  149. int m_iNumClientNonNetworkable;
  150. // Current last used slot
  151. int m_iMaxUsedServerIndex;
  152. // This holds fast lookups for special edicts.
  153. EntityCacheInfo_t m_EntityCacheInfo[NUM_ENT_ENTRIES];
  154. // For fast iteration.
  155. CUtlLinkedList<C_BaseEntity*, unsigned short> m_BaseEntities;
  156. private:
  157. void AddPVSNotifier( IClientUnknown *pUnknown );
  158. void RemovePVSNotifier( IClientUnknown *pUnknown );
  159. // These entities want to know when they enter and leave the PVS (server entities
  160. // already can get the equivalent notification with NotifyShouldTransmit, but client
  161. // entities have to get it this way).
  162. CUtlLinkedList<CPVSNotifyInfo,unsigned short> m_PVSNotifyInfos;
  163. CUtlMap<IClientUnknown*,unsigned short,unsigned short> m_PVSNotifierMap; // Maps IClientUnknowns to indices into m_PVSNotifyInfos.
  164. };
  165. // Use this to iterate over *all* (even dormant) the C_BaseEntities in the client entity list.
  166. class C_AllBaseEntityIterator
  167. {
  168. public:
  169. C_AllBaseEntityIterator();
  170. void Restart();
  171. C_BaseEntity* Next(); // keep calling this until it returns null.
  172. private:
  173. unsigned short m_CurBaseEntity;
  174. };
  175. class C_BaseEntityIterator
  176. {
  177. public:
  178. C_BaseEntityIterator();
  179. void Restart();
  180. C_BaseEntity* Next(); // keep calling this until it returns null.
  181. private:
  182. unsigned short m_CurBaseEntity;
  183. };
  184. //-----------------------------------------------------------------------------
  185. // Inline methods
  186. //-----------------------------------------------------------------------------
  187. inline bool CClientEntityList::IsHandleValid( ClientEntityHandle_t handle ) const
  188. {
  189. return handle.Get() != nullptr;
  190. }
  191. inline IClientUnknown* CClientEntityList::GetListedEntity( int entnum )
  192. {
  193. IHandleEntity* pHandle = LookupEntityByNetworkIndex( entnum );
  194. return static_cast< IClientUnknown* >( pHandle );
  195. }
  196. inline IClientUnknown* CClientEntityList::GetClientUnknownFromHandle( ClientEntityHandle_t hEnt )
  197. {
  198. return (IClientUnknown*)LookupEntity( hEnt );
  199. }
  200. inline CUtlLinkedList<CClientEntityList::CPVSNotifyInfo,unsigned short>& CClientEntityList::GetPVSNotifiers()
  201. {
  202. return m_PVSNotifyInfos;
  203. }
  204. //-----------------------------------------------------------------------------
  205. // Convenience methods to convert between entindex + ClientEntityHandle_t
  206. //-----------------------------------------------------------------------------
  207. inline ClientEntityHandle_t CClientEntityList::EntIndexToHandle( int entnum )
  208. {
  209. if ( entnum < -1 )
  210. return INVALID_EHANDLE;
  211. IClientUnknown *pUnk = GetListedEntity( entnum );
  212. return pUnk ? pUnk->GetRefEHandle() : INVALID_EHANDLE;
  213. }
  214. //-----------------------------------------------------------------------------
  215. // Returns the client entity list
  216. //-----------------------------------------------------------------------------
  217. extern CClientEntityList *cl_entitylist;
  218. inline CClientEntityList& ClientEntityList()
  219. {
  220. return *cl_entitylist;
  221. }
  222. // Implement this class and register with entlist to receive entity create/delete notification
  223. class IClientEntityListener
  224. {
  225. public:
  226. virtual void OnEntityCreated( C_BaseEntity *pEntity ) {};
  227. //virtual void OnEntitySpawned( C_BaseEntity *pEntity ) {};
  228. virtual void OnEntityDeleted( C_BaseEntity *pEntity ) {};
  229. };
  230. #endif // CLIENTENTITYLIST_H