void CClientLeafSystem::RemoveRenderable( ClientRenderHandle_t handle ) { // This can happen upon level shutdown if (!m_Renderables.IsValidIndex(handle)) return; // Reset the render handle in the entity. IClientRenderable *pRenderable = m_Renderables[handle].m_pRenderable; Assert( handle == pRenderable->RenderHandle() ); pRenderable->RenderHandle() = INVALID_CLIENT_RENDER_HANDLE; // Reemove the renderable from the dirty list if ( m_Renderables[handle].m_Flags & RENDER_FLAGS_HASCHANGED ) { // NOTE: This isn't particularly fast (linear search), // but I'm assuming it's an unusual case where we remove // renderables that are changing or that m_DirtyRenderables usually // only has a couple entries int i = m_DirtyRenderables.Find( handle ); Assert( i != m_DirtyRenderables.InvalidIndex() ); m_DirtyRenderables.FastRemove( i ); } if ( IsViewModelRenderGroup( (RenderGroup_t)m_Renderables[handle].m_RenderGroup ) ) { RemoveFromViewModelList( handle ); } RemoveFromTree( handle ); m_Renderables.Remove( handle ); }
void CBSPTreeData::Remove( BSPTreeDataHandle_t handle ) { if (!m_Handles.IsValidIndex(handle)) return; RemoveFromTree( handle ); m_Handles.Free( handle ); }
//----------------------------------------------------------------------------- // Purpose: Updates the current sequence info with the new packet // scans the message window to see if future packets can be used //----------------------------------------------------------------------------- void CTrackerNET::UpdateSequence(NetworkTarget_t *target, int targetIndex, int seqNum) { // update sequence target->incomingSequence = seqNum; // check to see when we should send acknowledgement if (!target->needAck) { target->ackTime = m_pThreads->GetTime() + ACK_DELAY; target->needAck = true; // move the target to the end of the ack list m_TargetList.Unlink(targetIndex); if (m_TargetList.IsValidIndex(m_iHighestAckTarget) && m_TargetList.IsInList(m_iHighestAckTarget)) { m_TargetList.LinkAfter(m_iHighestAckTarget, targetIndex); } else { m_TargetList.LinkToHead(targetIndex); } // set the need high mark for the packets that need ack m_iHighestAckTarget = targetIndex; } // check to see if packets in the window are now valid while (target->m_MessageWindow.Count()) { int index = target->m_MessageWindow.Head(); if (target->m_MessageWindow[index].sequenceNumber == target->incomingSequence + 1) { // this is the next message // update sequence numbers target->incomingSequence = target->m_MessageWindow[index].sequenceNumber; // add message to received list int receivedIndex = m_ReceivedMsgs.AddToTail(); m_ReceivedMsgs[receivedIndex].message = target->m_MessageWindow[index].message; WriteToLog("-> Recv match in window (is: %d)\n", target->m_MessageWindow[index].sequenceNumber); // remove message from window target->m_MessageWindow.Remove(index); } else { // no more break; } } }
//----------------------------------------------------------------------------- // Retrieve leaf handles to leaves a renderable is in // the pOutLeaf parameter is filled with the leaf the renderable is in. // If pInIterator is not specified, pOutLeaf is the first leaf in the list. // if pInIterator is specified, that iterator is used to return the next leaf // in the list in pOutLeaf. // the pOutIterator parameter is filled with the iterater which index to the pOutLeaf returned. // // Returns false on failure cases where pOutLeaf will be invalid. CHECK THE RETURN! //----------------------------------------------------------------------------- bool CClientLeafSystem::GetRenderableLeaf(ClientRenderHandle_t handle, int* pOutLeaf, const int* pInIterator /* = 0 */, int* pOutIterator /* = 0 */) { // bail on invalid handle if ( !m_Renderables.IsValidIndex( handle ) ) return false; // bail on no output value pointer if ( !pOutLeaf ) return false; // an iterator was specified if ( pInIterator ) { int iter = *pInIterator; // test for invalid iterator if ( iter == m_RenderablesInLeaf.InvalidIndex() ) return false; int iterNext = m_RenderablesInLeaf.NextBucket( iter ); // test for end of list if ( iterNext == m_RenderablesInLeaf.InvalidIndex() ) return false; // Give the caller the iterator used if ( pOutIterator ) { *pOutIterator = iterNext; } // set output value to the next leaf *pOutLeaf = m_RenderablesInLeaf.Bucket( iterNext ); } else // no iter param, give them the first bucket in the renderable's list { int iter = m_RenderablesInLeaf.FirstBucket( handle ); if ( iter == m_RenderablesInLeaf.InvalidIndex() ) return false; // Set output value to this leaf *pOutLeaf = m_RenderablesInLeaf.Bucket( iter ); // give this iterator to caller if ( pOutIterator ) { *pOutIterator = iter; } } return true; }
//----------------------------------------------------------------------------- // Call this when the renderable moves //----------------------------------------------------------------------------- void CClientLeafSystem::RenderableChanged( ClientRenderHandle_t handle ) { Assert ( handle != INVALID_CLIENT_RENDER_HANDLE ); Assert( m_Renderables.IsValidIndex( handle ) ); if ( !m_Renderables.IsValidIndex( handle ) ) return; if ( (m_Renderables[handle].m_Flags & RENDER_FLAGS_HASCHANGED ) == 0 ) { m_Renderables[handle].m_Flags |= RENDER_FLAGS_HASCHANGED; m_DirtyRenderables.AddToTail( handle ); } #if _DEBUG else { // It had better be in the list Assert( m_DirtyRenderables.Find( handle ) != m_DirtyRenderables.InvalidIndex() ); } #endif }
int CClientLeafSystem::GetRenderableLeaves( ClientRenderHandle_t handle, int leaves[128] ) { if ( !m_Renderables.IsValidIndex( handle ) ) return -1; RenderableInfo_t *pRenderable = &m_Renderables[handle]; if ( pRenderable->m_LeafList == m_RenderablesInLeaf.InvalidIndex() ) return -1; int nLeaves = 0; for ( int i=m_RenderablesInLeaf.FirstBucket( handle ); i != m_RenderablesInLeaf.InvalidIndex(); i = m_RenderablesInLeaf.NextBucket( i ) ) { leaves[nLeaves++] = m_RenderablesInLeaf.Bucket( i ); if ( nLeaves >= 128 ) break; } return nLeaves; }
//----------------------------------------------------------------------------- // Activates a particular context, use DEFAULT_VGUI_CONTEXT // to get the one normally used by VGUI //----------------------------------------------------------------------------- void CVGui::ActivateContext( HContext context ) { Assert( (context == DEFAULT_VGUI_CONTEXT) || m_Contexts.IsValidIndex(context) ); if ( m_hContext != context ) { // Clear out any messages queues that may be full... if ( !IsReentrant() ) { DispatchMessages(); } m_hContext = context; g_pInput->ActivateInputContext( GetContext(m_hContext)->m_hInputContext ); if ( context != DEFAULT_VGUI_CONTEXT && !IsReentrant() ) { g_pInput->RunFrame( ); } } }
//----------------------------------------------------------------------------- // Purpose: Destructor //----------------------------------------------------------------------------- CParticleEffect::~CParticleEffect( void ) { #if defined( _DEBUG ) int index = g_ParticleEffects.Find( this ); Assert( g_ParticleEffects.IsValidIndex(index) ); g_ParticleEffects.Remove( index ); #endif // HACKHACK: Prevent re-entering the destructor, clear m_Flags. // For some reason we'll get a callback into NotifyRemove() after being deleted! // Investigate dangling pointer m_Flags = 0; #if !defined( _XBOX ) if ( ( m_nToolParticleEffectId != TOOLPARTICLESYSTEMID_INVALID ) && clienttools->IsInRecordingMode() ) { KeyValues *msg = new KeyValues( "OldParticleSystem_Destroy" ); msg->SetInt( "id", m_nToolParticleEffectId ); msg->SetFloat( "time", gpGlobals->curtime ); ToolFramework_PostToolMessage( HTOOLHANDLE_INVALID, msg ); m_nToolParticleEffectId = TOOLPARTICLESYSTEMID_INVALID; } #endif }
//----------------------------------------------------------------------------- // Purpose: Checks to see if we should resend any reliable packets //----------------------------------------------------------------------------- void CTrackerNET::CheckReliablePacketSending() { float time = m_pThreads->GetTime(); // reliable packets are held in the m_ReliableMessages queue in the order that they were sent // if a packet is resent, it is moved to the end of the queue // packets are also checked at this time to see if they have been acknowledged while (m_ReliableMessages.Count()) { // get the first message int index = m_ReliableMessages.Head(); // get the message SentMessage_t &msg = m_ReliableMessages[index]; // check the resend time, if it's not time to resend then we have nothing more to do if (msg.resendTime > time) break; // get the network target for this message if (!m_TargetList.IsValidIndex(msg.networkTargetHandle) || !m_TargetList.IsInList(msg.networkTargetHandle) || m_TargetList[msg.networkTargetHandle].targetID != msg.networkTargetID) { // message's target has been removed, kill if (msg.message) { msg.message->deleteThis(); } m_ReliableMessages.Remove(index); continue; } NetworkTarget_t &target = m_TargetList[msg.networkTargetHandle]; // check to see if it's already been acknowledged if (msg.sequenceNumber <= target.outgoingAcknowledged) { // message has been acknowledged, kill if (msg.message) { msg.message->deleteThis(); } m_ReliableMessages.Remove(index); // move onto next message continue; } // check to see if we should resend this packet msg.resendAttempt++; if (msg.resendAttempt < MAX_SEND_ATTEMPTS) { // only send the message if it's in the message send window if (msg.sequenceNumber < target.outgoingAcknowledged + MESSAGE_WINDOW) { WriteToLog("-> Resending '%d' (os:%d > %d) (%s)\n", msg.message->GetMsgID(), msg.sequenceNumber, target.outgoingAcknowledged, target.netAddress.ToStaticString()); // send that it again InternalSendMessage(msg.message, &target, msg.sequenceNumber); } else { // hold back on sending the message WriteToLog("-> Holding back resend '%d' (os:%d > %d) (%s)\n", msg.message->GetMsgID(), msg.sequenceNumber, target.outgoingAcknowledged, target.netAddress.ToStaticString()); msg.resendAttempt--; } // set the time before retrying again // send times: 0.0 1.5 1.5 1.5 (1.5) = 6.0 second timeout, 4 packets sent msg.resendTime = time + RESEND_TIME; // move it to the end of the list m_ReliableMessages.Unlink(index); m_ReliableMessages.LinkToTail(index); // next packet continue; } // target has failed to respond, remove the target and respond with a failed message WriteToLog("Could not deliver packet: %d (os:%d)\n", msg.message->GetMsgID(), msg.sequenceNumber); // send back a send failure message to the app // convert the send message into a receive message CSendMessage *sendMsg = dynamic_cast<CSendMessage *>(msg.message); if (sendMsg) { IBinaryBuffer *buf = sendMsg->GetBuffer(); buf->SetPosition(buf->GetBufferData()); buf->Advance(buf->GetReservedSize()); CReceiveMessage *failMsg = new CReceiveMessage(buf, true); if (failMsg->IsValid()) { failMsg->SetFailed(); failMsg->SetNetAddress(target.netAddress); failMsg->SetSessionID(sendMsg->SessionID()); int newIndex = m_FailedMsgs.AddToTail(); FailedMsg_t &fmsg = m_FailedMsgs[newIndex]; fmsg.message = failMsg; } else { delete failMsg; } } // target not responding, so cancel the connection // remove from target map int mapindex = FindTargetIndexByAddress(target.netAddress); assert(m_TargetMap.IsValidIndex(mapindex)); m_TargetMap.RemoveAt(mapindex); // remove target from list m_TargetList.Remove(msg.networkTargetHandle); // message will automatically be delete since it's target is gone } }
//----------------------------------------------------------------------------- // Activates a particular input context, use DEFAULT_INPUT_CONTEXT // to get the one normally used by VGUI //----------------------------------------------------------------------------- void CInputWin32::ActivateInputContext( HInputContext context ) { assert( (context == DEFAULT_INPUT_CONTEXT) || m_Contexts.IsValidIndex(context) ); m_hContext = context; }
bool CFrameSnapshotManager::IsValidPackedEntity( CFrameSnapshot* pSnapshot, int entity ) const { return m_PackedEntities.IsValidIndex(pSnapshot->m_pPackedData[entity]); }