From f56bb35301836e56582a575a75864392a0177875 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20P=2E=20Tjern=C3=B8?= Date: Mon, 2 Dec 2013 19:31:46 -0800 Subject: Fix line endings. WHAMMY. --- mp/src/game/client/cliententitylist.cpp | 1008 +++++++++++++++---------------- 1 file changed, 504 insertions(+), 504 deletions(-) (limited to 'mp/src/game/client/cliententitylist.cpp') diff --git a/mp/src/game/client/cliententitylist.cpp b/mp/src/game/client/cliententitylist.cpp index 758ab8f8..294d4ff1 100644 --- a/mp/src/game/client/cliententitylist.cpp +++ b/mp/src/game/client/cliententitylist.cpp @@ -1,505 +1,505 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $Workfile: $ -// $NoKeywords: $ -//===========================================================================// - -//----------------------------------------------------------------------------- -// Purpose: a global list of all the entities in the game. All iteration through -// entities is done through this object. -//----------------------------------------------------------------------------- -#include "cbase.h" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -//----------------------------------------------------------------------------- -// Globals -//----------------------------------------------------------------------------- - -// Create interface -static CClientEntityList s_EntityList; -CBaseEntityList *g_pEntityList = &s_EntityList; - -// Expose list to engine -EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CClientEntityList, IClientEntityList, VCLIENTENTITYLIST_INTERFACE_VERSION, s_EntityList ); - -// Store local pointer to interface for rest of client .dll only -// (CClientEntityList instead of IClientEntityList ) -CClientEntityList *cl_entitylist = &s_EntityList; - - -bool PVSNotifierMap_LessFunc( IClientUnknown* const &a, IClientUnknown* const &b ) -{ - return a < b; -} - - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -CClientEntityList::CClientEntityList( void ) : - m_PVSNotifierMap( 0, 0, PVSNotifierMap_LessFunc ) -{ - m_iMaxUsedServerIndex = -1; - m_iMaxServerEnts = 0; - Release(); - -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -CClientEntityList::~CClientEntityList( void ) -{ - Release(); -} - -//----------------------------------------------------------------------------- -// Purpose: Clears all entity lists and releases entities -//----------------------------------------------------------------------------- -void CClientEntityList::Release( void ) -{ - // Free all the entities. - ClientEntityHandle_t iter = FirstHandle(); - while( iter != InvalidHandle() ) - { - // Try to call release on anything we can. - IClientNetworkable *pNet = GetClientNetworkableFromHandle( iter ); - if ( pNet ) - { - pNet->Release(); - } - else - { - // Try to call release on anything we can. - IClientThinkable *pThinkable = GetClientThinkableFromHandle( iter ); - if ( pThinkable ) - { - pThinkable->Release(); - } - } - RemoveEntity( iter ); - - iter = FirstHandle(); - } - - m_iNumServerEnts = 0; - m_iMaxServerEnts = 0; - m_iNumClientNonNetworkable = 0; - m_iMaxUsedServerIndex = -1; -} - -IClientNetworkable* CClientEntityList::GetClientNetworkable( int entnum ) -{ - Assert( entnum >= 0 ); - Assert( entnum < MAX_EDICTS ); - return m_EntityCacheInfo[entnum].m_pNetworkable; -} - - -IClientEntity* CClientEntityList::GetClientEntity( int entnum ) -{ - IClientUnknown *pEnt = GetListedEntity( entnum ); - return pEnt ? pEnt->GetIClientEntity() : 0; -} - - -int CClientEntityList::NumberOfEntities( bool bIncludeNonNetworkable ) -{ - if ( bIncludeNonNetworkable == true ) - return m_iNumServerEnts + m_iNumClientNonNetworkable; - - return m_iNumServerEnts; -} - - -void CClientEntityList::SetMaxEntities( int maxents ) -{ - m_iMaxServerEnts = maxents; -} - - -int CClientEntityList::GetMaxEntities( void ) -{ - return m_iMaxServerEnts; -} - - -//----------------------------------------------------------------------------- -// Convenience methods to convert between entindex + ClientEntityHandle_t -//----------------------------------------------------------------------------- -int CClientEntityList::HandleToEntIndex( ClientEntityHandle_t handle ) -{ - if ( handle == INVALID_EHANDLE_INDEX ) - return -1; - C_BaseEntity *pEnt = GetBaseEntityFromHandle( handle ); - return pEnt ? pEnt->entindex() : -1; -} - - -//----------------------------------------------------------------------------- -// Purpose: Because m_iNumServerEnts != last index -// Output : int -//----------------------------------------------------------------------------- -int CClientEntityList::GetHighestEntityIndex( void ) -{ - return m_iMaxUsedServerIndex; -} - -void CClientEntityList::RecomputeHighestEntityUsed( void ) -{ - m_iMaxUsedServerIndex = -1; - - // Walk backward looking for first valid index - int i; - for ( i = MAX_EDICTS - 1; i >= 0; i-- ) - { - if ( GetListedEntity( i ) != NULL ) - { - m_iMaxUsedServerIndex = i; - break; - } - } -} - - -//----------------------------------------------------------------------------- -// Purpose: Add a raw C_BaseEntity to the entity list. -// Input : index - -//----------------------------------------------------------------------------- - -//----------------------------------------------------------------------------- -// Purpose: -// Input : index - -//----------------------------------------------------------------------------- - -C_BaseEntity* CClientEntityList::GetBaseEntity( int entnum ) -{ - IClientUnknown *pEnt = GetListedEntity( entnum ); - return pEnt ? pEnt->GetBaseEntity() : 0; -} - - -ICollideable* CClientEntityList::GetCollideable( int entnum ) -{ - IClientUnknown *pEnt = GetListedEntity( entnum ); - return pEnt ? pEnt->GetCollideable() : 0; -} - - -IClientNetworkable* CClientEntityList::GetClientNetworkableFromHandle( ClientEntityHandle_t hEnt ) -{ - IClientUnknown *pEnt = GetClientUnknownFromHandle( hEnt ); - return pEnt ? pEnt->GetClientNetworkable() : 0; -} - - -IClientEntity* CClientEntityList::GetClientEntityFromHandle( ClientEntityHandle_t hEnt ) -{ - IClientUnknown *pEnt = GetClientUnknownFromHandle( hEnt ); - return pEnt ? pEnt->GetIClientEntity() : 0; -} - - -IClientRenderable* CClientEntityList::GetClientRenderableFromHandle( ClientEntityHandle_t hEnt ) -{ - IClientUnknown *pEnt = GetClientUnknownFromHandle( hEnt ); - return pEnt ? pEnt->GetClientRenderable() : 0; -} - - -C_BaseEntity* CClientEntityList::GetBaseEntityFromHandle( ClientEntityHandle_t hEnt ) -{ - IClientUnknown *pEnt = GetClientUnknownFromHandle( hEnt ); - return pEnt ? pEnt->GetBaseEntity() : 0; -} - - -ICollideable* CClientEntityList::GetCollideableFromHandle( ClientEntityHandle_t hEnt ) -{ - IClientUnknown *pEnt = GetClientUnknownFromHandle( hEnt ); - return pEnt ? pEnt->GetCollideable() : 0; -} - - -IClientThinkable* CClientEntityList::GetClientThinkableFromHandle( ClientEntityHandle_t hEnt ) -{ - IClientUnknown *pEnt = GetClientUnknownFromHandle( hEnt ); - return pEnt ? pEnt->GetClientThinkable() : 0; -} - - -void CClientEntityList::AddPVSNotifier( IClientUnknown *pUnknown ) -{ - IClientRenderable *pRen = pUnknown->GetClientRenderable(); - if ( pRen ) - { - IPVSNotify *pNotify = pRen->GetPVSNotifyInterface(); - if ( pNotify ) - { - unsigned short index = m_PVSNotifyInfos.AddToTail(); - CPVSNotifyInfo *pInfo = &m_PVSNotifyInfos[index]; - pInfo->m_pNotify = pNotify; - pInfo->m_pRenderable = pRen; - pInfo->m_InPVSStatus = 0; - pInfo->m_PVSNotifiersLink = index; - - m_PVSNotifierMap.Insert( pUnknown, index ); - } - } -} - - -void CClientEntityList::RemovePVSNotifier( IClientUnknown *pUnknown ) -{ - IClientRenderable *pRenderable = pUnknown->GetClientRenderable(); - if ( pRenderable ) - { - IPVSNotify *pNotify = pRenderable->GetPVSNotifyInterface(); - if ( pNotify ) - { - unsigned short index = m_PVSNotifierMap.Find( pUnknown ); - if ( !m_PVSNotifierMap.IsValidIndex( index ) ) - { - Warning( "PVS notifier not in m_PVSNotifierMap\n" ); - Assert( false ); - return; - } - - unsigned short indexIntoPVSNotifyInfos = m_PVSNotifierMap[index]; - - Assert( m_PVSNotifyInfos[indexIntoPVSNotifyInfos].m_pNotify == pNotify ); - Assert( m_PVSNotifyInfos[indexIntoPVSNotifyInfos].m_pRenderable == pRenderable ); - - m_PVSNotifyInfos.Remove( indexIntoPVSNotifyInfos ); - m_PVSNotifierMap.RemoveAt( index ); - return; - } - } - - // If it didn't report itself as a notifier, let's hope it's not in the notifier list now - // (which would mean that it reported itself as a notifier earlier, but not now). -#ifdef _DEBUG - unsigned short index = m_PVSNotifierMap.Find( pUnknown ); - Assert( !m_PVSNotifierMap.IsValidIndex( index ) ); -#endif -} - -void CClientEntityList::AddListenerEntity( IClientEntityListener *pListener ) -{ - if ( m_entityListeners.Find( pListener ) >= 0 ) - { - AssertMsg( 0, "Can't add listeners multiple times\n" ); - return; - } - m_entityListeners.AddToTail( pListener ); -} - -void CClientEntityList::RemoveListenerEntity( IClientEntityListener *pListener ) -{ - m_entityListeners.FindAndRemove( pListener ); -} - -void CClientEntityList::OnAddEntity( IHandleEntity *pEnt, CBaseHandle handle ) -{ - int entnum = handle.GetEntryIndex(); - EntityCacheInfo_t *pCache = &m_EntityCacheInfo[entnum]; - - if ( entnum >= 0 && entnum < MAX_EDICTS ) - { - // Update our counters. - m_iNumServerEnts++; - if ( entnum > m_iMaxUsedServerIndex ) - { - m_iMaxUsedServerIndex = entnum; - } - - - // Cache its networkable pointer. - Assert( dynamic_cast< IClientUnknown* >( pEnt ) ); - Assert( ((IClientUnknown*)pEnt)->GetClientNetworkable() ); // Server entities should all be networkable. - pCache->m_pNetworkable = ((IClientUnknown*)pEnt)->GetClientNetworkable(); - } - - IClientUnknown *pUnknown = (IClientUnknown*)pEnt; - - // If this thing wants PVS notifications, hook it up. - AddPVSNotifier( pUnknown ); - - // Store it in a special list for fast iteration if it's a C_BaseEntity. - C_BaseEntity *pBaseEntity = pUnknown->GetBaseEntity(); - if ( pBaseEntity ) - { - pCache->m_BaseEntitiesIndex = m_BaseEntities.AddToTail( pBaseEntity ); - - if ( pBaseEntity->ObjectCaps() & FCAP_SAVE_NON_NETWORKABLE ) - { - m_iNumClientNonNetworkable++; - } - - //DevMsg(2,"Created %s\n", pBaseEnt->GetClassname() ); - for ( int i = m_entityListeners.Count()-1; i >= 0; i-- ) - { - m_entityListeners[i]->OnEntityCreated( pBaseEntity ); - } - } - else - { - pCache->m_BaseEntitiesIndex = m_BaseEntities.InvalidIndex(); - } - - -} - - -void CClientEntityList::OnRemoveEntity( IHandleEntity *pEnt, CBaseHandle handle ) -{ - int entnum = handle.GetEntryIndex(); - EntityCacheInfo_t *pCache = &m_EntityCacheInfo[entnum]; - - if ( entnum >= 0 && entnum < MAX_EDICTS ) - { - // This is a networkable ent. Clear out our cache info for it. - pCache->m_pNetworkable = NULL; - m_iNumServerEnts--; - - if ( entnum >= m_iMaxUsedServerIndex ) - { - RecomputeHighestEntityUsed(); - } - } - - - IClientUnknown *pUnknown = (IClientUnknown*)pEnt; - - // If this is a PVS notifier, remove it. - RemovePVSNotifier( pUnknown ); - - C_BaseEntity *pBaseEntity = pUnknown->GetBaseEntity(); - - if ( pBaseEntity ) - { - if ( pBaseEntity->ObjectCaps() & FCAP_SAVE_NON_NETWORKABLE ) - { - m_iNumClientNonNetworkable--; - } - - //DevMsg(2,"Deleted %s\n", pBaseEnt->GetClassname() ); - for ( int i = m_entityListeners.Count()-1; i >= 0; i-- ) - { - m_entityListeners[i]->OnEntityDeleted( pBaseEntity ); - } - } - - if ( pCache->m_BaseEntitiesIndex != m_BaseEntities.InvalidIndex() ) - m_BaseEntities.Remove( pCache->m_BaseEntitiesIndex ); - - pCache->m_BaseEntitiesIndex = m_BaseEntities.InvalidIndex(); -} - - -// Use this to iterate over all the C_BaseEntities. -C_BaseEntity* CClientEntityList::FirstBaseEntity() const -{ - const CEntInfo *pList = FirstEntInfo(); - while ( pList ) - { - if ( pList->m_pEntity ) - { - IClientUnknown *pUnk = static_cast( pList->m_pEntity ); - C_BaseEntity *pRet = pUnk->GetBaseEntity(); - if ( pRet ) - return pRet; - } - pList = pList->m_pNext; - } - - return NULL; - -} - -C_BaseEntity* CClientEntityList::NextBaseEntity( C_BaseEntity *pEnt ) const -{ - if ( pEnt == NULL ) - return FirstBaseEntity(); - - // Run through the list until we get a C_BaseEntity. - const CEntInfo *pList = GetEntInfoPtr( pEnt->GetRefEHandle() ); - if ( pList ) - { - pList = NextEntInfo(pList); - } - - while ( pList ) - { - if ( pList->m_pEntity ) - { - IClientUnknown *pUnk = static_cast( pList->m_pEntity ); - C_BaseEntity *pRet = pUnk->GetBaseEntity(); - if ( pRet ) - return pRet; - } - pList = pList->m_pNext; - } - - return NULL; -} - - - -// -------------------------------------------------------------------------------------------------- // -// C_AllBaseEntityIterator -// -------------------------------------------------------------------------------------------------- // -C_AllBaseEntityIterator::C_AllBaseEntityIterator() -{ - Restart(); -} - - -void C_AllBaseEntityIterator::Restart() -{ - m_CurBaseEntity = ClientEntityList().m_BaseEntities.Head(); -} - - -C_BaseEntity* C_AllBaseEntityIterator::Next() -{ - if ( m_CurBaseEntity == ClientEntityList().m_BaseEntities.InvalidIndex() ) - return NULL; - - C_BaseEntity *pRet = ClientEntityList().m_BaseEntities[m_CurBaseEntity]; - m_CurBaseEntity = ClientEntityList().m_BaseEntities.Next( m_CurBaseEntity ); - return pRet; -} - - -// -------------------------------------------------------------------------------------------------- // -// C_BaseEntityIterator -// -------------------------------------------------------------------------------------------------- // -C_BaseEntityIterator::C_BaseEntityIterator() -{ - Restart(); -} - -void C_BaseEntityIterator::Restart() -{ - m_CurBaseEntity = ClientEntityList().m_BaseEntities.Head(); -} - -C_BaseEntity* C_BaseEntityIterator::Next() -{ - // Skip dormant entities - while ( m_CurBaseEntity != ClientEntityList().m_BaseEntities.InvalidIndex() ) - { - C_BaseEntity *pRet = ClientEntityList().m_BaseEntities[m_CurBaseEntity]; - m_CurBaseEntity = ClientEntityList().m_BaseEntities.Next( m_CurBaseEntity ); - - if (!pRet->IsDormant()) - return pRet; - } - - return NULL; +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Workfile: $ +// $NoKeywords: $ +//===========================================================================// + +//----------------------------------------------------------------------------- +// Purpose: a global list of all the entities in the game. All iteration through +// entities is done through this object. +//----------------------------------------------------------------------------- +#include "cbase.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +//----------------------------------------------------------------------------- +// Globals +//----------------------------------------------------------------------------- + +// Create interface +static CClientEntityList s_EntityList; +CBaseEntityList *g_pEntityList = &s_EntityList; + +// Expose list to engine +EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CClientEntityList, IClientEntityList, VCLIENTENTITYLIST_INTERFACE_VERSION, s_EntityList ); + +// Store local pointer to interface for rest of client .dll only +// (CClientEntityList instead of IClientEntityList ) +CClientEntityList *cl_entitylist = &s_EntityList; + + +bool PVSNotifierMap_LessFunc( IClientUnknown* const &a, IClientUnknown* const &b ) +{ + return a < b; +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CClientEntityList::CClientEntityList( void ) : + m_PVSNotifierMap( 0, 0, PVSNotifierMap_LessFunc ) +{ + m_iMaxUsedServerIndex = -1; + m_iMaxServerEnts = 0; + Release(); + +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CClientEntityList::~CClientEntityList( void ) +{ + Release(); +} + +//----------------------------------------------------------------------------- +// Purpose: Clears all entity lists and releases entities +//----------------------------------------------------------------------------- +void CClientEntityList::Release( void ) +{ + // Free all the entities. + ClientEntityHandle_t iter = FirstHandle(); + while( iter != InvalidHandle() ) + { + // Try to call release on anything we can. + IClientNetworkable *pNet = GetClientNetworkableFromHandle( iter ); + if ( pNet ) + { + pNet->Release(); + } + else + { + // Try to call release on anything we can. + IClientThinkable *pThinkable = GetClientThinkableFromHandle( iter ); + if ( pThinkable ) + { + pThinkable->Release(); + } + } + RemoveEntity( iter ); + + iter = FirstHandle(); + } + + m_iNumServerEnts = 0; + m_iMaxServerEnts = 0; + m_iNumClientNonNetworkable = 0; + m_iMaxUsedServerIndex = -1; +} + +IClientNetworkable* CClientEntityList::GetClientNetworkable( int entnum ) +{ + Assert( entnum >= 0 ); + Assert( entnum < MAX_EDICTS ); + return m_EntityCacheInfo[entnum].m_pNetworkable; +} + + +IClientEntity* CClientEntityList::GetClientEntity( int entnum ) +{ + IClientUnknown *pEnt = GetListedEntity( entnum ); + return pEnt ? pEnt->GetIClientEntity() : 0; +} + + +int CClientEntityList::NumberOfEntities( bool bIncludeNonNetworkable ) +{ + if ( bIncludeNonNetworkable == true ) + return m_iNumServerEnts + m_iNumClientNonNetworkable; + + return m_iNumServerEnts; +} + + +void CClientEntityList::SetMaxEntities( int maxents ) +{ + m_iMaxServerEnts = maxents; +} + + +int CClientEntityList::GetMaxEntities( void ) +{ + return m_iMaxServerEnts; +} + + +//----------------------------------------------------------------------------- +// Convenience methods to convert between entindex + ClientEntityHandle_t +//----------------------------------------------------------------------------- +int CClientEntityList::HandleToEntIndex( ClientEntityHandle_t handle ) +{ + if ( handle == INVALID_EHANDLE_INDEX ) + return -1; + C_BaseEntity *pEnt = GetBaseEntityFromHandle( handle ); + return pEnt ? pEnt->entindex() : -1; +} + + +//----------------------------------------------------------------------------- +// Purpose: Because m_iNumServerEnts != last index +// Output : int +//----------------------------------------------------------------------------- +int CClientEntityList::GetHighestEntityIndex( void ) +{ + return m_iMaxUsedServerIndex; +} + +void CClientEntityList::RecomputeHighestEntityUsed( void ) +{ + m_iMaxUsedServerIndex = -1; + + // Walk backward looking for first valid index + int i; + for ( i = MAX_EDICTS - 1; i >= 0; i-- ) + { + if ( GetListedEntity( i ) != NULL ) + { + m_iMaxUsedServerIndex = i; + break; + } + } +} + + +//----------------------------------------------------------------------------- +// Purpose: Add a raw C_BaseEntity to the entity list. +// Input : index - +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Purpose: +// Input : index - +//----------------------------------------------------------------------------- + +C_BaseEntity* CClientEntityList::GetBaseEntity( int entnum ) +{ + IClientUnknown *pEnt = GetListedEntity( entnum ); + return pEnt ? pEnt->GetBaseEntity() : 0; +} + + +ICollideable* CClientEntityList::GetCollideable( int entnum ) +{ + IClientUnknown *pEnt = GetListedEntity( entnum ); + return pEnt ? pEnt->GetCollideable() : 0; +} + + +IClientNetworkable* CClientEntityList::GetClientNetworkableFromHandle( ClientEntityHandle_t hEnt ) +{ + IClientUnknown *pEnt = GetClientUnknownFromHandle( hEnt ); + return pEnt ? pEnt->GetClientNetworkable() : 0; +} + + +IClientEntity* CClientEntityList::GetClientEntityFromHandle( ClientEntityHandle_t hEnt ) +{ + IClientUnknown *pEnt = GetClientUnknownFromHandle( hEnt ); + return pEnt ? pEnt->GetIClientEntity() : 0; +} + + +IClientRenderable* CClientEntityList::GetClientRenderableFromHandle( ClientEntityHandle_t hEnt ) +{ + IClientUnknown *pEnt = GetClientUnknownFromHandle( hEnt ); + return pEnt ? pEnt->GetClientRenderable() : 0; +} + + +C_BaseEntity* CClientEntityList::GetBaseEntityFromHandle( ClientEntityHandle_t hEnt ) +{ + IClientUnknown *pEnt = GetClientUnknownFromHandle( hEnt ); + return pEnt ? pEnt->GetBaseEntity() : 0; +} + + +ICollideable* CClientEntityList::GetCollideableFromHandle( ClientEntityHandle_t hEnt ) +{ + IClientUnknown *pEnt = GetClientUnknownFromHandle( hEnt ); + return pEnt ? pEnt->GetCollideable() : 0; +} + + +IClientThinkable* CClientEntityList::GetClientThinkableFromHandle( ClientEntityHandle_t hEnt ) +{ + IClientUnknown *pEnt = GetClientUnknownFromHandle( hEnt ); + return pEnt ? pEnt->GetClientThinkable() : 0; +} + + +void CClientEntityList::AddPVSNotifier( IClientUnknown *pUnknown ) +{ + IClientRenderable *pRen = pUnknown->GetClientRenderable(); + if ( pRen ) + { + IPVSNotify *pNotify = pRen->GetPVSNotifyInterface(); + if ( pNotify ) + { + unsigned short index = m_PVSNotifyInfos.AddToTail(); + CPVSNotifyInfo *pInfo = &m_PVSNotifyInfos[index]; + pInfo->m_pNotify = pNotify; + pInfo->m_pRenderable = pRen; + pInfo->m_InPVSStatus = 0; + pInfo->m_PVSNotifiersLink = index; + + m_PVSNotifierMap.Insert( pUnknown, index ); + } + } +} + + +void CClientEntityList::RemovePVSNotifier( IClientUnknown *pUnknown ) +{ + IClientRenderable *pRenderable = pUnknown->GetClientRenderable(); + if ( pRenderable ) + { + IPVSNotify *pNotify = pRenderable->GetPVSNotifyInterface(); + if ( pNotify ) + { + unsigned short index = m_PVSNotifierMap.Find( pUnknown ); + if ( !m_PVSNotifierMap.IsValidIndex( index ) ) + { + Warning( "PVS notifier not in m_PVSNotifierMap\n" ); + Assert( false ); + return; + } + + unsigned short indexIntoPVSNotifyInfos = m_PVSNotifierMap[index]; + + Assert( m_PVSNotifyInfos[indexIntoPVSNotifyInfos].m_pNotify == pNotify ); + Assert( m_PVSNotifyInfos[indexIntoPVSNotifyInfos].m_pRenderable == pRenderable ); + + m_PVSNotifyInfos.Remove( indexIntoPVSNotifyInfos ); + m_PVSNotifierMap.RemoveAt( index ); + return; + } + } + + // If it didn't report itself as a notifier, let's hope it's not in the notifier list now + // (which would mean that it reported itself as a notifier earlier, but not now). +#ifdef _DEBUG + unsigned short index = m_PVSNotifierMap.Find( pUnknown ); + Assert( !m_PVSNotifierMap.IsValidIndex( index ) ); +#endif +} + +void CClientEntityList::AddListenerEntity( IClientEntityListener *pListener ) +{ + if ( m_entityListeners.Find( pListener ) >= 0 ) + { + AssertMsg( 0, "Can't add listeners multiple times\n" ); + return; + } + m_entityListeners.AddToTail( pListener ); +} + +void CClientEntityList::RemoveListenerEntity( IClientEntityListener *pListener ) +{ + m_entityListeners.FindAndRemove( pListener ); +} + +void CClientEntityList::OnAddEntity( IHandleEntity *pEnt, CBaseHandle handle ) +{ + int entnum = handle.GetEntryIndex(); + EntityCacheInfo_t *pCache = &m_EntityCacheInfo[entnum]; + + if ( entnum >= 0 && entnum < MAX_EDICTS ) + { + // Update our counters. + m_iNumServerEnts++; + if ( entnum > m_iMaxUsedServerIndex ) + { + m_iMaxUsedServerIndex = entnum; + } + + + // Cache its networkable pointer. + Assert( dynamic_cast< IClientUnknown* >( pEnt ) ); + Assert( ((IClientUnknown*)pEnt)->GetClientNetworkable() ); // Server entities should all be networkable. + pCache->m_pNetworkable = ((IClientUnknown*)pEnt)->GetClientNetworkable(); + } + + IClientUnknown *pUnknown = (IClientUnknown*)pEnt; + + // If this thing wants PVS notifications, hook it up. + AddPVSNotifier( pUnknown ); + + // Store it in a special list for fast iteration if it's a C_BaseEntity. + C_BaseEntity *pBaseEntity = pUnknown->GetBaseEntity(); + if ( pBaseEntity ) + { + pCache->m_BaseEntitiesIndex = m_BaseEntities.AddToTail( pBaseEntity ); + + if ( pBaseEntity->ObjectCaps() & FCAP_SAVE_NON_NETWORKABLE ) + { + m_iNumClientNonNetworkable++; + } + + //DevMsg(2,"Created %s\n", pBaseEnt->GetClassname() ); + for ( int i = m_entityListeners.Count()-1; i >= 0; i-- ) + { + m_entityListeners[i]->OnEntityCreated( pBaseEntity ); + } + } + else + { + pCache->m_BaseEntitiesIndex = m_BaseEntities.InvalidIndex(); + } + + +} + + +void CClientEntityList::OnRemoveEntity( IHandleEntity *pEnt, CBaseHandle handle ) +{ + int entnum = handle.GetEntryIndex(); + EntityCacheInfo_t *pCache = &m_EntityCacheInfo[entnum]; + + if ( entnum >= 0 && entnum < MAX_EDICTS ) + { + // This is a networkable ent. Clear out our cache info for it. + pCache->m_pNetworkable = NULL; + m_iNumServerEnts--; + + if ( entnum >= m_iMaxUsedServerIndex ) + { + RecomputeHighestEntityUsed(); + } + } + + + IClientUnknown *pUnknown = (IClientUnknown*)pEnt; + + // If this is a PVS notifier, remove it. + RemovePVSNotifier( pUnknown ); + + C_BaseEntity *pBaseEntity = pUnknown->GetBaseEntity(); + + if ( pBaseEntity ) + { + if ( pBaseEntity->ObjectCaps() & FCAP_SAVE_NON_NETWORKABLE ) + { + m_iNumClientNonNetworkable--; + } + + //DevMsg(2,"Deleted %s\n", pBaseEnt->GetClassname() ); + for ( int i = m_entityListeners.Count()-1; i >= 0; i-- ) + { + m_entityListeners[i]->OnEntityDeleted( pBaseEntity ); + } + } + + if ( pCache->m_BaseEntitiesIndex != m_BaseEntities.InvalidIndex() ) + m_BaseEntities.Remove( pCache->m_BaseEntitiesIndex ); + + pCache->m_BaseEntitiesIndex = m_BaseEntities.InvalidIndex(); +} + + +// Use this to iterate over all the C_BaseEntities. +C_BaseEntity* CClientEntityList::FirstBaseEntity() const +{ + const CEntInfo *pList = FirstEntInfo(); + while ( pList ) + { + if ( pList->m_pEntity ) + { + IClientUnknown *pUnk = static_cast( pList->m_pEntity ); + C_BaseEntity *pRet = pUnk->GetBaseEntity(); + if ( pRet ) + return pRet; + } + pList = pList->m_pNext; + } + + return NULL; + +} + +C_BaseEntity* CClientEntityList::NextBaseEntity( C_BaseEntity *pEnt ) const +{ + if ( pEnt == NULL ) + return FirstBaseEntity(); + + // Run through the list until we get a C_BaseEntity. + const CEntInfo *pList = GetEntInfoPtr( pEnt->GetRefEHandle() ); + if ( pList ) + { + pList = NextEntInfo(pList); + } + + while ( pList ) + { + if ( pList->m_pEntity ) + { + IClientUnknown *pUnk = static_cast( pList->m_pEntity ); + C_BaseEntity *pRet = pUnk->GetBaseEntity(); + if ( pRet ) + return pRet; + } + pList = pList->m_pNext; + } + + return NULL; +} + + + +// -------------------------------------------------------------------------------------------------- // +// C_AllBaseEntityIterator +// -------------------------------------------------------------------------------------------------- // +C_AllBaseEntityIterator::C_AllBaseEntityIterator() +{ + Restart(); +} + + +void C_AllBaseEntityIterator::Restart() +{ + m_CurBaseEntity = ClientEntityList().m_BaseEntities.Head(); +} + + +C_BaseEntity* C_AllBaseEntityIterator::Next() +{ + if ( m_CurBaseEntity == ClientEntityList().m_BaseEntities.InvalidIndex() ) + return NULL; + + C_BaseEntity *pRet = ClientEntityList().m_BaseEntities[m_CurBaseEntity]; + m_CurBaseEntity = ClientEntityList().m_BaseEntities.Next( m_CurBaseEntity ); + return pRet; +} + + +// -------------------------------------------------------------------------------------------------- // +// C_BaseEntityIterator +// -------------------------------------------------------------------------------------------------- // +C_BaseEntityIterator::C_BaseEntityIterator() +{ + Restart(); +} + +void C_BaseEntityIterator::Restart() +{ + m_CurBaseEntity = ClientEntityList().m_BaseEntities.Head(); +} + +C_BaseEntity* C_BaseEntityIterator::Next() +{ + // Skip dormant entities + while ( m_CurBaseEntity != ClientEntityList().m_BaseEntities.InvalidIndex() ) + { + C_BaseEntity *pRet = ClientEntityList().m_BaseEntities[m_CurBaseEntity]; + m_CurBaseEntity = ClientEntityList().m_BaseEntities.Next( m_CurBaseEntity ); + + if (!pRet->IsDormant()) + return pRet; + } + + return NULL; } \ No newline at end of file -- cgit v1.2.3