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.
|
|
//========= 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
|