diff options
Diffstat (limited to 'game/shared/entitylist_base.h')
| -rw-r--r-- | game/shared/entitylist_base.h | 209 |
1 files changed, 209 insertions, 0 deletions
diff --git a/game/shared/entitylist_base.h b/game/shared/entitylist_base.h new file mode 100644 index 0000000..8e2db3b --- /dev/null +++ b/game/shared/entitylist_base.h @@ -0,0 +1,209 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#ifndef ENTITYLIST_BASE_H +#define ENTITYLIST_BASE_H +#ifdef _WIN32 +#pragma once +#endif + + +#include "const.h" +#include "basehandle.h" +#include "utllinkedlist.h" +#include "ihandleentity.h" + + +class CEntInfo +{ +public: + IHandleEntity *m_pEntity; + int m_SerialNumber; + CEntInfo *m_pPrev; + CEntInfo *m_pNext; + + void ClearLinks(); +}; + + +class CBaseEntityList +{ +public: + CBaseEntityList(); + ~CBaseEntityList(); + + // Add and remove entities. iForcedSerialNum should only be used on the client. The server + // gets to dictate what the networkable serial numbers are on the client so it can send + // ehandles over and they work. + CBaseHandle AddNetworkableEntity( IHandleEntity *pEnt, int index, int iForcedSerialNum = -1 ); + CBaseHandle AddNonNetworkableEntity( IHandleEntity *pEnt ); + void RemoveEntity( CBaseHandle handle ); + + // Get an ehandle from a networkable entity's index (note: if there is no entity in that slot, + // then the ehandle will be invalid and produce NULL). + CBaseHandle GetNetworkableHandle( int iEntity ) const; + + // ehandles use this in their Get() function to produce a pointer to the entity. + IHandleEntity* LookupEntity( const CBaseHandle &handle ) const; + IHandleEntity* LookupEntityByNetworkIndex( int edictIndex ) const; + + // Use these to iterate over all the entities. + CBaseHandle FirstHandle() const; + CBaseHandle NextHandle( CBaseHandle hEnt ) const; + static CBaseHandle InvalidHandle(); + + const CEntInfo *FirstEntInfo() const; + const CEntInfo *NextEntInfo( const CEntInfo *pInfo ) const; + const CEntInfo *GetEntInfoPtr( const CBaseHandle &hEnt ) const; + const CEntInfo *GetEntInfoPtrByIndex( int index ) const; + +// Overridables. +protected: + + // These are notifications to the derived class. It can cache info here if it wants. + virtual void OnAddEntity( IHandleEntity *pEnt, CBaseHandle handle ); + + // It is safe to delete the entity here. We won't be accessing the pointer after + // calling OnRemoveEntity. + virtual void OnRemoveEntity( IHandleEntity *pEnt, CBaseHandle handle ); + + +private: + + CBaseHandle AddEntityAtSlot( IHandleEntity *pEnt, int iSlot, int iForcedSerialNum ); + void RemoveEntityAtSlot( int iSlot ); + + +private: + + class CEntInfoList + { + public: + CEntInfoList(); + + const CEntInfo *Head() const { return m_pHead; } + const CEntInfo *Tail() const { return m_pTail; } + CEntInfo *Head() { return m_pHead; } + CEntInfo *Tail() { return m_pTail; } + void AddToHead( CEntInfo *pElement ) { LinkAfter( NULL, pElement ); } + void AddToTail( CEntInfo *pElement ) { LinkBefore( NULL, pElement ); } + + void LinkBefore( CEntInfo *pBefore, CEntInfo *pElement ); + void LinkAfter( CEntInfo *pBefore, CEntInfo *pElement ); + void Unlink( CEntInfo *pElement ); + bool IsInList( CEntInfo *pElement ); + + private: + CEntInfo *m_pHead; + CEntInfo *m_pTail; + }; + + int GetEntInfoIndex( const CEntInfo *pEntInfo ) const; + + + // The first MAX_EDICTS entities are networkable. The rest are client-only or server-only. + CEntInfo m_EntPtrArray[NUM_ENT_ENTRIES]; + CEntInfoList m_activeList; + CEntInfoList m_freeNonNetworkableList; +}; + + +// ------------------------------------------------------------------------------------ // +// Inlines. +// ------------------------------------------------------------------------------------ // + +inline int CBaseEntityList::GetEntInfoIndex( const CEntInfo *pEntInfo ) const +{ + Assert( pEntInfo ); + int index = (int)(pEntInfo - m_EntPtrArray); + Assert( index >= 0 && index < NUM_ENT_ENTRIES ); + return index; +} + +inline CBaseHandle CBaseEntityList::GetNetworkableHandle( int iEntity ) const +{ + Assert( iEntity >= 0 && iEntity < MAX_EDICTS ); + if ( m_EntPtrArray[iEntity].m_pEntity ) + return CBaseHandle( iEntity, m_EntPtrArray[iEntity].m_SerialNumber ); + else + return CBaseHandle(); +} + + +inline IHandleEntity* CBaseEntityList::LookupEntity( const CBaseHandle &handle ) const +{ + if ( handle.m_Index == INVALID_EHANDLE_INDEX ) + return NULL; + + const CEntInfo *pInfo = &m_EntPtrArray[ handle.GetEntryIndex() ]; + if ( pInfo->m_SerialNumber == handle.GetSerialNumber() ) + return (IHandleEntity*)pInfo->m_pEntity; + else + return NULL; +} + + +inline IHandleEntity* CBaseEntityList::LookupEntityByNetworkIndex( int edictIndex ) const +{ + // (Legacy support). + if ( edictIndex < 0 ) + return NULL; + + Assert( edictIndex < NUM_ENT_ENTRIES ); + return (IHandleEntity*)m_EntPtrArray[edictIndex].m_pEntity; +} + + +inline CBaseHandle CBaseEntityList::FirstHandle() const +{ + if ( !m_activeList.Head() ) + return INVALID_EHANDLE_INDEX; + + int index = GetEntInfoIndex( m_activeList.Head() ); + return CBaseHandle( index, m_EntPtrArray[index].m_SerialNumber ); +} + +inline CBaseHandle CBaseEntityList::NextHandle( CBaseHandle hEnt ) const +{ + int iSlot = hEnt.GetEntryIndex(); + CEntInfo *pNext = m_EntPtrArray[iSlot].m_pNext; + if ( !pNext ) + return INVALID_EHANDLE_INDEX; + + int index = GetEntInfoIndex( pNext ); + + return CBaseHandle( index, m_EntPtrArray[index].m_SerialNumber ); +} + +inline CBaseHandle CBaseEntityList::InvalidHandle() +{ + return INVALID_EHANDLE_INDEX; +} + +inline const CEntInfo *CBaseEntityList::FirstEntInfo() const +{ + return m_activeList.Head(); +} + +inline const CEntInfo *CBaseEntityList::NextEntInfo( const CEntInfo *pInfo ) const +{ + return pInfo->m_pNext; +} + +inline const CEntInfo *CBaseEntityList::GetEntInfoPtr( const CBaseHandle &hEnt ) const +{ + int iSlot = hEnt.GetEntryIndex(); + return &m_EntPtrArray[iSlot]; +} + +inline const CEntInfo *CBaseEntityList::GetEntInfoPtrByIndex( int index ) const +{ + return &m_EntPtrArray[index]; +} + +extern CBaseEntityList *g_pEntityList; + +#endif // ENTITYLIST_BASE_H |