#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(); CBaseHandle AddNetworkableEntity(IHandleEntity* pEnt, int index, int iForcedSerialNum = -1); CBaseHandle AddNonNetworkableEntity(IHandleEntity* pEnt); void RemoveEntity(CBaseHandle handle); CBaseHandle GetNetworkableHandle(int iEntity) const; IHandleEntity* LookupEntity(const CBaseHandle& handle) const; IHandleEntity* LookupEntityByNetworkIndex(int edictIndex) const; 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; protected: virtual void OnAddEntity(IHandleEntity* pEnt, CBaseHandle handle); 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; CEntInfo m_EntPtrArray[NUM_ENT_ENTRIES]; CEntInfoList m_activeList; CEntInfoList m_freeNonNetworkableList; }; 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 { 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]; } #endif