Team Fortress 2 Source Code as on 22/4/2020
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.

209 lines
5.6 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================//
  6. #ifndef ENTITYLIST_BASE_H
  7. #define ENTITYLIST_BASE_H
  8. #ifdef _WIN32
  9. #pragma once
  10. #endif
  11. #include "const.h"
  12. #include "basehandle.h"
  13. #include "utllinkedlist.h"
  14. #include "ihandleentity.h"
  15. class CEntInfo
  16. {
  17. public:
  18. IHandleEntity *m_pEntity;
  19. int m_SerialNumber;
  20. CEntInfo *m_pPrev;
  21. CEntInfo *m_pNext;
  22. void ClearLinks();
  23. };
  24. class CBaseEntityList
  25. {
  26. public:
  27. CBaseEntityList();
  28. ~CBaseEntityList();
  29. // Add and remove entities. iForcedSerialNum should only be used on the client. The server
  30. // gets to dictate what the networkable serial numbers are on the client so it can send
  31. // ehandles over and they work.
  32. CBaseHandle AddNetworkableEntity( IHandleEntity *pEnt, int index, int iForcedSerialNum = -1 );
  33. CBaseHandle AddNonNetworkableEntity( IHandleEntity *pEnt );
  34. void RemoveEntity( CBaseHandle handle );
  35. // Get an ehandle from a networkable entity's index (note: if there is no entity in that slot,
  36. // then the ehandle will be invalid and produce NULL).
  37. CBaseHandle GetNetworkableHandle( int iEntity ) const;
  38. // ehandles use this in their Get() function to produce a pointer to the entity.
  39. IHandleEntity* LookupEntity( const CBaseHandle &handle ) const;
  40. IHandleEntity* LookupEntityByNetworkIndex( int edictIndex ) const;
  41. // Use these to iterate over all the entities.
  42. CBaseHandle FirstHandle() const;
  43. CBaseHandle NextHandle( CBaseHandle hEnt ) const;
  44. static CBaseHandle InvalidHandle();
  45. const CEntInfo *FirstEntInfo() const;
  46. const CEntInfo *NextEntInfo( const CEntInfo *pInfo ) const;
  47. const CEntInfo *GetEntInfoPtr( const CBaseHandle &hEnt ) const;
  48. const CEntInfo *GetEntInfoPtrByIndex( int index ) const;
  49. // Overridables.
  50. protected:
  51. // These are notifications to the derived class. It can cache info here if it wants.
  52. virtual void OnAddEntity( IHandleEntity *pEnt, CBaseHandle handle );
  53. // It is safe to delete the entity here. We won't be accessing the pointer after
  54. // calling OnRemoveEntity.
  55. virtual void OnRemoveEntity( IHandleEntity *pEnt, CBaseHandle handle );
  56. private:
  57. CBaseHandle AddEntityAtSlot( IHandleEntity *pEnt, int iSlot, int iForcedSerialNum );
  58. void RemoveEntityAtSlot( int iSlot );
  59. private:
  60. class CEntInfoList
  61. {
  62. public:
  63. CEntInfoList();
  64. const CEntInfo *Head() const { return m_pHead; }
  65. const CEntInfo *Tail() const { return m_pTail; }
  66. CEntInfo *Head() { return m_pHead; }
  67. CEntInfo *Tail() { return m_pTail; }
  68. void AddToHead( CEntInfo *pElement ) { LinkAfter( NULL, pElement ); }
  69. void AddToTail( CEntInfo *pElement ) { LinkBefore( NULL, pElement ); }
  70. void LinkBefore( CEntInfo *pBefore, CEntInfo *pElement );
  71. void LinkAfter( CEntInfo *pBefore, CEntInfo *pElement );
  72. void Unlink( CEntInfo *pElement );
  73. bool IsInList( CEntInfo *pElement );
  74. private:
  75. CEntInfo *m_pHead;
  76. CEntInfo *m_pTail;
  77. };
  78. int GetEntInfoIndex( const CEntInfo *pEntInfo ) const;
  79. // The first MAX_EDICTS entities are networkable. The rest are client-only or server-only.
  80. CEntInfo m_EntPtrArray[NUM_ENT_ENTRIES];
  81. CEntInfoList m_activeList;
  82. CEntInfoList m_freeNonNetworkableList;
  83. };
  84. // ------------------------------------------------------------------------------------ //
  85. // Inlines.
  86. // ------------------------------------------------------------------------------------ //
  87. inline int CBaseEntityList::GetEntInfoIndex( const CEntInfo *pEntInfo ) const
  88. {
  89. Assert( pEntInfo );
  90. int index = (int)(pEntInfo - m_EntPtrArray);
  91. Assert( index >= 0 && index < NUM_ENT_ENTRIES );
  92. return index;
  93. }
  94. inline CBaseHandle CBaseEntityList::GetNetworkableHandle( int iEntity ) const
  95. {
  96. Assert( iEntity >= 0 && iEntity < MAX_EDICTS );
  97. if ( m_EntPtrArray[iEntity].m_pEntity )
  98. return CBaseHandle( iEntity, m_EntPtrArray[iEntity].m_SerialNumber );
  99. else
  100. return CBaseHandle();
  101. }
  102. inline IHandleEntity* CBaseEntityList::LookupEntity( const CBaseHandle &handle ) const
  103. {
  104. if ( handle.m_Index == INVALID_EHANDLE_INDEX )
  105. return NULL;
  106. const CEntInfo *pInfo = &m_EntPtrArray[ handle.GetEntryIndex() ];
  107. if ( pInfo->m_SerialNumber == handle.GetSerialNumber() )
  108. return (IHandleEntity*)pInfo->m_pEntity;
  109. else
  110. return NULL;
  111. }
  112. inline IHandleEntity* CBaseEntityList::LookupEntityByNetworkIndex( int edictIndex ) const
  113. {
  114. // (Legacy support).
  115. if ( edictIndex < 0 )
  116. return NULL;
  117. Assert( edictIndex < NUM_ENT_ENTRIES );
  118. return (IHandleEntity*)m_EntPtrArray[edictIndex].m_pEntity;
  119. }
  120. inline CBaseHandle CBaseEntityList::FirstHandle() const
  121. {
  122. if ( !m_activeList.Head() )
  123. return INVALID_EHANDLE_INDEX;
  124. int index = GetEntInfoIndex( m_activeList.Head() );
  125. return CBaseHandle( index, m_EntPtrArray[index].m_SerialNumber );
  126. }
  127. inline CBaseHandle CBaseEntityList::NextHandle( CBaseHandle hEnt ) const
  128. {
  129. int iSlot = hEnt.GetEntryIndex();
  130. CEntInfo *pNext = m_EntPtrArray[iSlot].m_pNext;
  131. if ( !pNext )
  132. return INVALID_EHANDLE_INDEX;
  133. int index = GetEntInfoIndex( pNext );
  134. return CBaseHandle( index, m_EntPtrArray[index].m_SerialNumber );
  135. }
  136. inline CBaseHandle CBaseEntityList::InvalidHandle()
  137. {
  138. return INVALID_EHANDLE_INDEX;
  139. }
  140. inline const CEntInfo *CBaseEntityList::FirstEntInfo() const
  141. {
  142. return m_activeList.Head();
  143. }
  144. inline const CEntInfo *CBaseEntityList::NextEntInfo( const CEntInfo *pInfo ) const
  145. {
  146. return pInfo->m_pNext;
  147. }
  148. inline const CEntInfo *CBaseEntityList::GetEntInfoPtr( const CBaseHandle &hEnt ) const
  149. {
  150. int iSlot = hEnt.GetEntryIndex();
  151. return &m_EntPtrArray[iSlot];
  152. }
  153. inline const CEntInfo *CBaseEntityList::GetEntInfoPtrByIndex( int index ) const
  154. {
  155. return &m_EntPtrArray[index];
  156. }
  157. extern CBaseEntityList *g_pEntityList;
  158. #endif // ENTITYLIST_BASE_H