void CGameGibManager::AddGibToLRU( CBaseAnimating *pEntity ) { int i, next; if ( pEntity == NULL ) return; //Find stale gibs. for ( i = m_LRU.Head(); i < m_LRU.InvalidIndex(); i = next ) { next = m_LRU.Next(i); if ( m_LRU[i].Get() == NULL ) { m_LRU.Remove(i); } } // We're not tracking gibs at the moment if ( m_iCurrentMaxPieces <= 0 ) return; while ( m_LRU.Count() >= m_iCurrentMaxPieces ) { i = m_LRU.Head(); //TODO: Make this fade out instead of pop. UTIL_Remove( m_LRU[i] ); m_LRU.Remove(i); } m_LRU.AddToTail( pEntity ); m_iLastFrame = gpGlobals->framecount; }
//----------------------------------------------------------------------------- // Purpose: Gets any failed sends - returns any packet that could not be delivered //----------------------------------------------------------------------------- IReceiveMessage *CTrackerNET::GetFailedMessage() { if (m_FailedMsgs.Count()) { // pop the failed message from the front of the queue and return it FailedMsg_t &msg = m_FailedMsgs[m_FailedMsgs.Head()]; IReceiveMessage *recvMsg = msg.message; m_FailedMsgs.Remove(m_FailedMsgs.Head()); return recvMsg; } return NULL; }
void CGroundLine::DrawAllGroundLines() { VPROF("CGroundLine::DrawAllGroundLines()"); unsigned short i; for( i = s_GroundLines.Head(); i != s_GroundLines.InvalidIndex(); i = s_GroundLines.Next(i) ) { s_GroundLines[i]->Draw(); } }
//----------------------------------------------------------------------------- // Purpose: // Input : *focus - //----------------------------------------------------------------------------- void CInputWin32::PanelDeleted(VPANEL focus) { HInputContext i; for (i = m_Contexts.Head(); i != m_Contexts.InvalidIndex(); i = m_Contexts.Next(i) ) { PanelDeleted( focus, m_Contexts[i] ); } PanelDeleted( focus, m_DefaultInputContext ); }
void CVGui::DestroyAllContexts( ) { HContext next; HContext i = m_Contexts.Head(); while (i != m_Contexts.InvalidIndex()) { next = m_Contexts.Next(i); DestroyContext( i ); i = next; } }
//----------------------------------------------------------------------------- // Purpose: Checks for any waiting messages //----------------------------------------------------------------------------- IReceiveMessage *CTrackerNET::GetIncomingData() { // check the receive list if (m_ReceivedMsgs.Count()) { int head = m_ReceivedMsgs.Head(); IReceiveMessage *msg = m_ReceivedMsgs[head].message; m_ReceivedMsgs.Remove(head); return msg; } return NULL; }
void TimeoutJobIDs() { double flCurTime = Plat_FloatTime(); int iNext; for ( int i=g_JobMemories.Head(); i != g_JobMemories.InvalidIndex(); i=iNext ) { iNext = g_JobMemories.Next( i ); if ( (flCurTime - g_JobMemories[i].m_Time) > JOB_MEMORY_DURATION ) g_JobMemories.Remove( i ); } }
bool FindJobMemory( int id[4] ) { int iNext; for ( int i=g_JobMemories.Head(); i != g_JobMemories.InvalidIndex(); i=iNext ) { iNext = g_JobMemories.Next( i ); CJobMemory *pJob = &g_JobMemories[i]; if ( memcmp( pJob->m_ID, id, sizeof( pJob->m_ID ) ) == 0 ) return true; } return false; }
static bool EventCollidesWithRows( CUtlLinkedList< CChoreoEvent*, int >& list, CChoreoEvent *event, char *trackName, size_t trackNameLength ) { float st = event->GetStartTime(); float ed = event->GetEndTime(); for ( int i = list.Head(); i != list.InvalidIndex(); i = list.Next( i ) ) { CChoreoEvent *test = list[ i ]; float teststart = test->GetStartTime(); float testend = test->GetEndTime(); // See if spans overlap if ( teststart >= ed ) continue; if ( testend <= st ) continue; // Now see if they deal with the same flex controller int tc = event->GetNumFlexAnimationTracks(); for ( int track = 0; track < tc; ++track ) { CFlexAnimationTrack *t = event->GetFlexAnimationTrack( track ); if ( !t->IsTrackActive() ) { continue; } int sampleCountNormal = t->GetNumSamples( 0 ); int sampleCountBalance = 0; if ( t->IsComboType() ) { sampleCountBalance = t->GetNumSamples( 1 ); } if ( !sampleCountNormal && !sampleCountBalance ) continue; // Otherwise, see if the test track has this as an active track if ( IsFlexTrackBeingUsed( test, t->GetFlexControllerName() ) ) { Q_strncpy( trackName, t->GetFlexControllerName(), trackNameLength ); return true; } } return false; } return false; }
//----------------------------------------------------------------------------- // Purpose: Checks to see if we need to send any ack packets // in response to reliable messages we've received //----------------------------------------------------------------------------- void CTrackerNET::CheckSendingAcknowledgements() { float time = (float)m_pThreads->GetTime(); // the target list is in order of ackTime's while (m_TargetList.Count()) { int targetIndex = m_TargetList.Head(); NetworkTarget_t &target = m_TargetList[targetIndex]; if (!target.needAck) break; // target does not need acknowledging, we're at the end of the list if (target.ackTime > time) break; // this packet not yet ready to be acknowledged if (target.incomingSequence > target.incomingAcknowledged) { // send an acknowledgement ISendMessage *pMsg = CreateMessage(TMSG_ACK); pMsg->SetNetAddress(target.netAddress); SendMessage(pMsg, NET_UNRELIABLE); } // this target has been acknowledged, move to the end of the list target.needAck = false; m_TargetList.Unlink(targetIndex); m_TargetList.LinkToTail(targetIndex); // check to see if the highest ack target needs to be reset if (targetIndex == m_iHighestAckTarget) { m_iHighestAckTarget = -1; } } }
//----------------------------------------------------------------------------- // Purpose: message pump // loops through and sends all active messages // note that more messages may be posted during the process //----------------------------------------------------------------------------- bool CVGui::DispatchMessages() { int time = g_pSystem->GetTimeMillis(); m_InDispatcher = true; bool doneWork = (m_MessageQueue.Count() > 12); bool bUsingDelayedQueue = (m_DelayedMessageQueue.Count() > 0); // Need two passes because we send the mouse move message after all // other messages are done, but the mouse move message may itself generate // some more messages int nPassCount = 0; while ( nPassCount < 2 ) { while (m_MessageQueue.Count() > 0 || (m_SecondaryQueue.Count() > 0) || bUsingDelayedQueue) { // get the first message MessageItem_t *messageItem = NULL; int messageIndex = 0; // use the secondary queue until it empties. empty it after each message in the // primary queue. this makes primary messages completely resolve bool bUsingSecondaryQueue = (m_SecondaryQueue.Count() > 0); if (bUsingSecondaryQueue) { doneWork = true; messageIndex = m_SecondaryQueue.Head(); messageItem = &m_SecondaryQueue[messageIndex]; } else if (bUsingDelayedQueue) { if (m_DelayedMessageQueue.Count() >0) { messageItem = (MessageItem_t*)&m_DelayedMessageQueue.ElementAtHead(); } if (!messageItem || messageItem->_arrivalTime > time) { // no more items in the delayed message queue, move to the system queue bUsingDelayedQueue = false; continue; } } else { messageIndex = m_MessageQueue.Head(); messageItem = &m_MessageQueue[messageIndex]; } // message debug code if ( m_bDebugMessages ) { char *qname = bUsingSecondaryQueue ? "Secondary" : "Primary"; if (strcmp(messageItem->_params->GetName(), "Tick") && strcmp(messageItem->_params->GetName(), "MouseFocusTicked") && strcmp(messageItem->_params->GetName(), "KeyFocusTicked") && strcmp(messageItem->_params->GetName(), "CursorMoved")) { if (!stricmp(messageItem->_params->GetName(), "command")) { g_pIVgui->DPrintf2( "%s Queue dispatching command( %s, %s -- %i )\n", qname, messageItem->_params->GetName(), messageItem->_params->GetString("command"), messageItem->_messageID ); } else { g_pIVgui->DPrintf2( "%s Queue dispatching( %s -- %i )\n", qname ,messageItem->_params->GetName(), messageItem->_messageID ); } } } // send it KeyValues *params = messageItem->_params; // Deal with special internal cursor movement messages if ( messageItem->_messageTo == 0xFFFFFFFF ) { if ( !Q_stricmp( params->GetName(), "SetCursorPosInternal" ) ) { int nXPos = params->GetInt( "xpos", 0 ); int nYPos = params->GetInt( "ypos", 0 ); g_pInput->UpdateCursorPosInternal( nXPos, nYPos ); } } else { VPanel *vto = (VPanel *)g_pIVgui->HandleToPanel(messageItem->_messageTo); if (vto) { // Msg("Sending message: %s to %s\n", params ? params->GetName() : "\"\"", vto->GetName() ? vto->GetName() : "\"\""); vto->SendMessage(params, g_pIVgui->HandleToPanel(messageItem->_from)); } } // free the keyvalues memory // we can't reference the messageItem pointer anymore since the queue might have moved in memory if (params) { params->deleteThis(); } // remove it from the queue if (bUsingSecondaryQueue) { m_SecondaryQueue.Remove(messageIndex); } else if (bUsingDelayedQueue) { m_DelayedMessageQueue.RemoveAtHead(); } else { m_MessageQueue.Remove(messageIndex); } } ++nPassCount; if ( nPassCount == 1 ) { // Specifically post the current mouse position as a message g_pInput->PostCursorMessage(); } } // Make sure the windows cursor is in the right place after processing input // Needs to be done here because a message provoked by the cursor moved // message may move the cursor also g_pInput->HandleExplicitSetCursor( ); m_InDispatcher = false; return doneWork; }
//----------------------------------------------------------------------------- // 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 } }