void CClientThinkList::SetNextClientThink( ClientEntityHandle_t hEnt, float nextTime )
{
	if ( nextTime == CLIENT_THINK_NEVER )
	{
		RemoveThinkable( hEnt );
	}
	else
	{
		IClientThinkable *pThink = ClientEntityList().GetClientThinkableFromHandle( hEnt );
		if ( pThink )
		{
			ClientThinkHandle_t hThink = pThink->GetThinkHandle();

			// Add it to the list if it's not already in there.
			if ( hThink == INVALID_THINK_HANDLE )
			{
				hThink = (ClientThinkHandle_t)m_ThinkEntries.AddToTail();
				pThink->SetThinkHandle( hThink );

				GetThinkEntry( hThink )->m_hEnt = hEnt;
			}

			// Set the next think time..
			GetThinkEntry( hThink )->m_flNextClientThink = nextTime;
		}
	}
}
예제 #2
0
//-----------------------------------------------------------------------------
// Performs the think function
//-----------------------------------------------------------------------------
void CClientThinkList::PerformThinkFunction( ThinkEntry_t *pEntry, float flCurtime )
{
	IClientThinkable *pThink = ClientEntityList().GetClientThinkableFromHandle( pEntry->m_hEnt );
	if ( !pThink )
	{
		RemoveThinkable( pEntry->m_hEnt );
		return;
	}

	if ( pEntry->m_flNextClientThink == CLIENT_THINK_ALWAYS )
	{
		// NOTE: The Think function here could call SetNextClientThink
		// which would cause it to be removed + readded into the list
		pThink->ClientThink();
	}
	else if ( pEntry->m_flNextClientThink == FLT_MAX )
	{
		// This is an entity that doesn't need to think again; remove it
		RemoveThinkable( pEntry->m_hEnt );
	}
	else
	{
		Assert( pEntry->m_flNextClientThink <= flCurtime );

		// Indicate we're not going to think again
		pEntry->m_flNextClientThink = FLT_MAX;

		// NOTE: The Think function here could call SetNextClientThink
		// which would cause it to be readded into the list
		pThink->ClientThink();
	}

	// Set this after the Think calls in case they look at LastClientThink
	pEntry->m_flLastClientThink = flCurtime;
}
void CClientThinkList::PerformThinkFunctions()
{
	float curtime = gpGlobals->curtime;

	unsigned long iNext;
	for ( unsigned long iCur=m_ThinkEntries.Head(); iCur != m_ThinkEntries.InvalidIndex(); iCur = iNext )
	{
		iNext = m_ThinkEntries.Next( iCur );

		CThinkEntry *pEntry = &m_ThinkEntries[iCur];
		
		IClientThinkable *pThink = ClientEntityList().GetClientThinkableFromHandle( pEntry->m_hEnt );
		if ( pThink )
		{
			if ( pEntry->m_flNextClientThink == CLIENT_THINK_ALWAYS )
			{
				// NOTE: The Think function here could call SetNextClientThink
				// which would cause it to be removed + readded into the list
				pThink->ClientThink();

				// NOTE: The Think() call can cause other things to be added to the Think
				// list, which could reallocate memory and invalidate the pEntry pointer
				pEntry = &m_ThinkEntries[iCur];
			}
			else if ( pEntry->m_flNextClientThink < curtime )
			{
				pEntry->m_flNextClientThink = curtime;

				// NOTE: The Think function here could call SetNextClientThink
				// which would cause it to be readded into the list
				pThink->ClientThink();

				// NOTE: The Think() call can cause other things to be added to the Think
				// list, which could reallocate memory and invalidate the pEntry pointer
				pEntry = &m_ThinkEntries[iCur];

				// If they haven't changed the think time, then it should be removed.
				if ( pEntry->m_flNextClientThink == curtime )
				{
					RemoveThinkable( pEntry->m_hEnt );
				}
			}

			Assert( pEntry == &m_ThinkEntries[iCur] );

			// Set this after the Think calls in case they look at LastClientThink
			m_ThinkEntries[iCur].m_flLastClientThink = curtime;
		}
		else
		{
			// This should be almost impossible. When ClientEntityHandle_t's are versioned,
			// this should be totally impossible.
			Assert( false );
			m_ThinkEntries.Remove( iCur );
		}
	}

	// Clear out the client-side entity deletion list.
	CleanUpDeleteList();
}
//-----------------------------------------------------------------------------
// Purpose: Clears all entity lists and releases entities
//-----------------------------------------------------------------------------
void CClientEntityList::Release( void )
{
	// Free all the entities.
	ClientEntityHandle_t iter = FirstHandle();
	ClientEntityHandle_t next;
	while( iter != InvalidHandle() )
	{
		next = NextHandle( iter );
		
		// 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 = next;
	}

	m_iNumServerEnts = 0;
	m_iMaxServerEnts = 0;
	m_iMaxUsedServerIndex = -1;
}
예제 #5
0
//-----------------------------------------------------------------------------
// Removes the thinkable from the list
//-----------------------------------------------------------------------------
void CClientThinkList::RemoveThinkable( ClientEntityHandle_t hEnt )
{
	IClientThinkable *pThink = ClientEntityList().GetClientThinkableFromHandle( hEnt );
	if ( pThink )
	{
		ClientThinkHandle_t hThink = pThink->GetThinkHandle();
		if ( hThink != INVALID_THINK_HANDLE )
		{
			Assert( GetThinkEntry( hThink )->m_hEnt == hEnt );
			RemoveThinkable( hThink );
		}
	}
}
void CClientThinkList::RemoveThinkable( ClientEntityHandle_t hEnt )
{
	IClientThinkable *pThink = ClientEntityList().GetClientThinkableFromHandle( hEnt );
	if ( pThink )
	{
		ClientThinkHandle_t hThink = pThink->GetThinkHandle();

		// It will never think so make sure it's NOT in the list.
		if ( hThink != INVALID_THINK_HANDLE )
		{
			m_ThinkEntries.Remove( (unsigned long)hThink );
			pThink->SetThinkHandle( INVALID_THINK_HANDLE );
		}
	}
}
예제 #7
0
void CClientThinkList::SetNextClientThink( ClientEntityHandle_t hEnt, float flNextTime )
{
	if ( flNextTime == CLIENT_THINK_NEVER )
	{
		RemoveThinkable( hEnt );
		return;
	}

	IClientThinkable *pThink = ClientEntityList().GetClientThinkableFromHandle( hEnt );
	if ( !pThink )
		return;

	ClientThinkHandle_t hThink = pThink->GetThinkHandle();

	if ( m_bInThinkLoop )
	{
		// Queue up all changes
		int i = m_aChangeList.AddToTail();
		m_aChangeList[i].m_hEnt = hEnt;
		m_aChangeList[i].m_hThink = hThink;
		m_aChangeList[i].m_flNextTime = flNextTime;
		return;
	}

	// Add it to the list if it's not already in there.
	if ( hThink == INVALID_THINK_HANDLE )
	{
		hThink = (ClientThinkHandle_t)m_ThinkEntries.AddToTail();
		pThink->SetThinkHandle( hThink );

		ThinkEntry_t *pEntry = GetThinkEntry( hThink );
		pEntry->m_hEnt = hEnt;
		pEntry->m_nIterEnum = -1;
		pEntry->m_flLastClientThink = 0.0f;
	}

	Assert( GetThinkEntry( hThink )->m_hEnt == hEnt );
	GetThinkEntry( hThink )->m_flNextClientThink = flNextTime;
}
예제 #8
0
//-----------------------------------------------------------------------------
// Removes the thinkable from the list
//-----------------------------------------------------------------------------
void CClientThinkList::RemoveThinkable( ClientThinkHandle_t hThink )
{
	if ( hThink == INVALID_THINK_HANDLE )
		return;

	if ( m_bInThinkLoop )
	{
		// Queue up all changes
		int i = m_aChangeList.AddToTail();
		m_aChangeList[i].m_hEnt = INVALID_CLIENTENTITY_HANDLE;
		m_aChangeList[i].m_hThink = hThink;
		m_aChangeList[i].m_flNextTime = CLIENT_THINK_NEVER;
		return;
	}

	ThinkEntry_t *pEntry = GetThinkEntry( hThink );
	IClientThinkable *pThink = ClientEntityList().GetClientThinkableFromHandle( pEntry->m_hEnt );
	if ( pThink )
	{
		pThink->SetThinkHandle( INVALID_THINK_HANDLE );
	}
	m_ThinkEntries.Remove( (unsigned long)hThink );
}
예제 #9
0
void CClientThinkList::CleanUpDeleteList()
{
	int nThinkCount = m_aDeleteList.Count();
	for ( int iThink = 0; iThink < nThinkCount; ++iThink )
	{
		ClientEntityHandle_t handle = m_aDeleteList[iThink];
		if ( handle != ClientEntityList().InvalidHandle() )
		{
			C_BaseEntity *pEntity = ClientEntityList().GetBaseEntityFromHandle( handle );
			if ( pEntity )
			{
				pEntity->SetRemovalFlag( false );
			}

			IClientThinkable *pThink = ClientEntityList().GetClientThinkableFromHandle( handle );
			if ( pThink )
			{
				pThink->Release();
			}
		}
	}

	m_aDeleteList.RemoveAll();
}