summaryrefslogtreecommitdiff
path: root/game/client/cliententitylist.h
diff options
context:
space:
mode:
authorFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
committerFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
commit3bf9df6b2785fa6d951086978a3e66f49427166a (patch)
tree2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /game/client/cliententitylist.h
downloadarchived-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.h308
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
+