diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /game/client/cliententitylist.h | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'game/client/cliententitylist.h')
| -rw-r--r-- | game/client/cliententitylist.h | 308 |
1 files changed, 308 insertions, 0 deletions
diff --git a/game/client/cliententitylist.h b/game/client/cliententitylist.h new file mode 100644 index 0000000..f09b891 --- /dev/null +++ b/game/client/cliententitylist.h @@ -0,0 +1,308 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Workfile: $ +// $Date: $ +// $NoKeywords: $ +//===========================================================================// +#if !defined( CLIENTENTITYLIST_H ) +#define CLIENTENTITYLIST_H +#ifdef _WIN32 +#pragma once +#endif + +#include "tier0/dbg.h" +#include "icliententitylist.h" +#include "iclientunknown.h" +#include "utllinkedlist.h" +#include "utlvector.h" +#include "icliententityinternal.h" +#include "ispatialpartition.h" +#include "cdll_util.h" +#include "entitylist_base.h" +#include "utlmap.h" + +class C_Beam; +class C_BaseViewModel; +class C_BaseEntity; + + +#define INPVS_YES 0x0001 // The entity thinks it's in the PVS. +#define INPVS_THISFRAME 0x0002 // Accumulated as different views are rendered during the frame and used to notify the entity if + // it is not in the PVS anymore (at the end of the frame). +#define INPVS_NEEDSNOTIFY 0x0004 // The entity thinks it's in the PVS. + +class IClientEntityListener; + +abstract_class C_BaseEntityClassList +{ +public: + C_BaseEntityClassList(); + ~C_BaseEntityClassList(); + virtual void LevelShutdown() = 0; + + C_BaseEntityClassList *m_pNextClassList; +}; + +template< class T > +class C_EntityClassList : public C_BaseEntityClassList +{ +public: + virtual void LevelShutdown() { m_pClassList = NULL; } + + void Insert( T *pEntity ) + { + pEntity->m_pNext = m_pClassList; + m_pClassList = pEntity; + } + + void Remove( T *pEntity ) + { + T **pPrev = &m_pClassList; + T *pCur = *pPrev; + while ( pCur ) + { + if ( pCur == pEntity ) + { + *pPrev = pCur->m_pNext; + return; + } + pPrev = &pCur->m_pNext; + pCur = *pPrev; + } + } + + static T *m_pClassList; +}; + + +// Maximum size of entity list +#define INVALID_CLIENTENTITY_HANDLE CBaseHandle( INVALID_EHANDLE_INDEX ) + + +// +// This is the IClientEntityList implemenation. It serves two functions: +// +// 1. It converts server entity indices into IClientNetworkables for the engine. +// +// 2. It provides a place to store IClientUnknowns and gives out ClientEntityHandle_t's +// so they can be indexed and retreived. For example, this is how static props are referenced +// by the spatial partition manager - it doesn't know what is being inserted, so it's +// given ClientEntityHandle_t's, and the handlers for spatial partition callbacks can +// use the client entity list to look them up and check for supported interfaces. +// +class CClientEntityList : public CBaseEntityList, public IClientEntityList +{ +friend class C_BaseEntityIterator; +friend class C_AllBaseEntityIterator; + +public: + // Constructor, destructor + CClientEntityList( void ); + virtual ~CClientEntityList( void ); + + void Release(); // clears everything and releases entities + + +// Implement IClientEntityList +public: + + virtual IClientNetworkable* GetClientNetworkable( int entnum ); + virtual IClientEntity* GetClientEntity( int entnum ); + + virtual int NumberOfEntities( bool bIncludeNonNetworkable = false ); + + virtual IClientUnknown* GetClientUnknownFromHandle( ClientEntityHandle_t hEnt ); + virtual IClientNetworkable* GetClientNetworkableFromHandle( ClientEntityHandle_t hEnt ); + virtual IClientEntity* GetClientEntityFromHandle( ClientEntityHandle_t hEnt ); + + virtual int GetHighestEntityIndex( void ); + + virtual void SetMaxEntities( int maxents ); + virtual int GetMaxEntities( ); + + +// CBaseEntityList overrides. +protected: + + virtual void OnAddEntity( IHandleEntity *pEnt, CBaseHandle handle ); + virtual void OnRemoveEntity( IHandleEntity *pEnt, CBaseHandle handle ); + + +// Internal to client DLL. +public: + + // All methods of accessing specialized IClientUnknown's go through here. + IClientUnknown* GetListedEntity( int entnum ); + + // Simple wrappers for convenience.. + C_BaseEntity* GetBaseEntity( int entnum ); + ICollideable* GetCollideable( int entnum ); + + IClientRenderable* GetClientRenderableFromHandle( ClientEntityHandle_t hEnt ); + C_BaseEntity* GetBaseEntityFromHandle( ClientEntityHandle_t hEnt ); + ICollideable* GetCollideableFromHandle( ClientEntityHandle_t hEnt ); + IClientThinkable* GetClientThinkableFromHandle( ClientEntityHandle_t hEnt ); + + // Convenience methods to convert between entindex + ClientEntityHandle_t + ClientEntityHandle_t EntIndexToHandle( int entnum ); + int HandleToEntIndex( ClientEntityHandle_t handle ); + + // Is a handle valid? + bool IsHandleValid( ClientEntityHandle_t handle ) const; + + // For backwards compatibility... + C_BaseEntity* GetEnt( int entnum ) { return GetBaseEntity( entnum ); } + + void RecomputeHighestEntityUsed( void ); + + + // Use this to iterate over all the C_BaseEntities. + C_BaseEntity* FirstBaseEntity() const; + C_BaseEntity* NextBaseEntity( C_BaseEntity *pEnt ) const; + + class CPVSNotifyInfo + { + public: + IPVSNotify *m_pNotify; + IClientRenderable *m_pRenderable; + unsigned char m_InPVSStatus; // Combination of the INPVS_ flags. + unsigned short m_PVSNotifiersLink; // Into m_PVSNotifyInfos. + }; + + // Get the list of all PVS notifiers. + CUtlLinkedList<CPVSNotifyInfo,unsigned short>& GetPVSNotifiers(); + + CUtlVector<IClientEntityListener *> m_entityListeners; + + // add a class that gets notified of entity events + void AddListenerEntity( IClientEntityListener *pListener ); + void RemoveListenerEntity( IClientEntityListener *pListener ); + + void NotifyCreateEntity( C_BaseEntity *pEnt ); + void NotifyRemoveEntity( C_BaseEntity *pEnt ); + +private: + + // Cached info for networked entities. + struct EntityCacheInfo_t + { + // Cached off because GetClientNetworkable is called a *lot* + IClientNetworkable *m_pNetworkable; + unsigned short m_BaseEntitiesIndex; // Index into m_BaseEntities (or m_BaseEntities.InvalidIndex() if none). + }; + + // Current count + int m_iNumServerEnts; + // Max allowed + int m_iMaxServerEnts; + + int m_iNumClientNonNetworkable; + + // Current last used slot + int m_iMaxUsedServerIndex; + + // This holds fast lookups for special edicts. + EntityCacheInfo_t m_EntityCacheInfo[NUM_ENT_ENTRIES]; + + // For fast iteration. + CUtlLinkedList<C_BaseEntity*, unsigned short> m_BaseEntities; + + +private: + + void AddPVSNotifier( IClientUnknown *pUnknown ); + void RemovePVSNotifier( IClientUnknown *pUnknown ); + + // These entities want to know when they enter and leave the PVS (server entities + // already can get the equivalent notification with NotifyShouldTransmit, but client + // entities have to get it this way). + CUtlLinkedList<CPVSNotifyInfo,unsigned short> m_PVSNotifyInfos; + CUtlMap<IClientUnknown*,unsigned short,unsigned short> m_PVSNotifierMap; // Maps IClientUnknowns to indices into m_PVSNotifyInfos. +}; + + +// Use this to iterate over *all* (even dormant) the C_BaseEntities in the client entity list. +class C_AllBaseEntityIterator +{ +public: + C_AllBaseEntityIterator(); + + void Restart(); + C_BaseEntity* Next(); // keep calling this until it returns null. + +private: + unsigned short m_CurBaseEntity; +}; + +class C_BaseEntityIterator +{ +public: + C_BaseEntityIterator(); + + void Restart(); + C_BaseEntity* Next(); // keep calling this until it returns null. + +private: + unsigned short m_CurBaseEntity; +}; + +//----------------------------------------------------------------------------- +// Inline methods +//----------------------------------------------------------------------------- +inline bool CClientEntityList::IsHandleValid( ClientEntityHandle_t handle ) const +{ + return handle.Get() != 0; +} + +inline IClientUnknown* CClientEntityList::GetListedEntity( int entnum ) +{ + return (IClientUnknown*)LookupEntityByNetworkIndex( entnum ); +} + +inline IClientUnknown* CClientEntityList::GetClientUnknownFromHandle( ClientEntityHandle_t hEnt ) +{ + return (IClientUnknown*)LookupEntity( hEnt ); +} + +inline CUtlLinkedList<CClientEntityList::CPVSNotifyInfo,unsigned short>& CClientEntityList::GetPVSNotifiers() +{ + return m_PVSNotifyInfos; +} + + +//----------------------------------------------------------------------------- +// Convenience methods to convert between entindex + ClientEntityHandle_t +//----------------------------------------------------------------------------- +inline ClientEntityHandle_t CClientEntityList::EntIndexToHandle( int entnum ) +{ + if ( entnum < -1 ) + return INVALID_EHANDLE_INDEX; + IClientUnknown *pUnk = GetListedEntity( entnum ); + return pUnk ? pUnk->GetRefEHandle() : INVALID_EHANDLE_INDEX; +} + + +//----------------------------------------------------------------------------- +// Returns the client entity list +//----------------------------------------------------------------------------- +extern CClientEntityList *cl_entitylist; + +inline CClientEntityList& ClientEntityList() +{ + return *cl_entitylist; +} + +// Implement this class and register with entlist to receive entity create/delete notification +class IClientEntityListener +{ +public: + virtual void OnEntityCreated( C_BaseEntity *pEntity ) {}; + //virtual void OnEntitySpawned( C_BaseEntity *pEntity ) {}; + virtual void OnEntityDeleted( C_BaseEntity *pEntity ) {}; +}; + + +#endif // CLIENTENTITYLIST_H + |