llmessagethrottle.cpp
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:6k
源码类别:

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file llmessagethrottle.cpp
  3.  * @brief LLMessageThrottle class used for throttling messages.
  4.  *
  5.  * $LicenseInfo:firstyear=2004&license=viewergpl$
  6.  * 
  7.  * Copyright (c) 2004-2010, Linden Research, Inc.
  8.  * 
  9.  * Second Life Viewer Source Code
  10.  * The source code in this file ("Source Code") is provided by Linden Lab
  11.  * to you under the terms of the GNU General Public License, version 2.0
  12.  * ("GPL"), unless you have obtained a separate licensing agreement
  13.  * ("Other License"), formally executed by you and Linden Lab.  Terms of
  14.  * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15.  * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16.  * 
  17.  * There are special exceptions to the terms and conditions of the GPL as
  18.  * it is applied to this Source Code. View the full text of the exception
  19.  * in the file doc/FLOSS-exception.txt in this software distribution, or
  20.  * online at
  21.  * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22.  * 
  23.  * By copying, modifying or distributing this software, you acknowledge
  24.  * that you have read and understood your obligations described above,
  25.  * and agree to abide by those obligations.
  26.  * 
  27.  * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28.  * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29.  * COMPLETENESS OR PERFORMANCE.
  30.  * $/LicenseInfo$
  31.  */
  32. #include "linden_common.h"
  33. #include "llhash.h"
  34. #include "llmessagethrottle.h"
  35. #include "llframetimer.h"
  36. // This is used for the stl search_n function.
  37. #if _MSC_VER >= 1500 // VC9 has a bug in search_n
  38. struct eq_message_throttle_entry : public std::binary_function< LLMessageThrottleEntry, LLMessageThrottleEntry, bool >
  39. {
  40. bool operator()(const LLMessageThrottleEntry& a, const LLMessageThrottleEntry& b) const
  41. {
  42. return a.getHash() == b.getHash();
  43. }
  44. };
  45. #else
  46. bool eq_message_throttle_entry(LLMessageThrottleEntry a, LLMessageThrottleEntry b)
  47.   { return a.getHash() == b.getHash(); }
  48. #endif
  49. const U64 SEC_TO_USEC = 1000000;
  50. // How long (in microseconds) each type of message stays in its throttle list.
  51. const U64 MAX_MESSAGE_AGE[MTC_EOF] =
  52. {
  53. 10 * SEC_TO_USEC, // MTC_VIEWER_ALERT
  54. 10 * SEC_TO_USEC // MTC_AGENT_ALERT
  55. };
  56. LLMessageThrottle::LLMessageThrottle()
  57. {
  58. }
  59. LLMessageThrottle::~LLMessageThrottle()
  60. {
  61. }
  62. void LLMessageThrottle::pruneEntries()
  63. {
  64. // Go through each message category, and prune entries older than max age.
  65. S32 cat;
  66. for (cat = 0; cat < MTC_EOF; cat++)
  67. {
  68. message_list_t* message_list = &(mMessageList[cat]);
  69. // Use a reverse iterator, since entries on the back will be the oldest.
  70. message_list_reverse_iterator_t r_iterator  = message_list->rbegin();
  71. message_list_reverse_iterator_t r_last  = message_list->rend();
  72. // Look for the first entry younger than the maximum age.
  73. F32 max_age = (F32)MAX_MESSAGE_AGE[cat]; 
  74. BOOL found = FALSE;
  75. while (r_iterator != r_last && !found)
  76. {
  77. if ( LLFrameTimer::getTotalTime() - (*r_iterator).getEntryTime() < max_age )
  78. {
  79. // We found a young enough entry.
  80. found = TRUE;
  81. // Did we find at least one entry to remove?
  82. if (r_iterator != message_list->rbegin())
  83. {
  84. // Yes, remove it.
  85. message_list->erase(r_iterator.base(), message_list->end());
  86. }
  87. }
  88. else
  89. {
  90. r_iterator++;
  91. }
  92. }
  93. // If we didn't find any entries young enough to keep, remove them all.
  94. if (!found)
  95. {
  96. message_list->clear();
  97. }
  98. }
  99. }
  100. BOOL LLMessageThrottle::addViewerAlert(const LLUUID& to, const std::string& mesg)
  101. {
  102. message_list_t* message_list = &(mMessageList[MTC_VIEWER_ALERT]);
  103. // Concatenate from,to,mesg into one string.
  104. std::ostringstream full_mesg;
  105. full_mesg << to << mesg;
  106. // Create an entry for this message.
  107. size_t hash = llhash(full_mesg.str().c_str());
  108. LLMessageThrottleEntry entry(hash, LLFrameTimer::getTotalTime());
  109. // Check if this message is already in the list.
  110. #if _MSC_VER >= 1500 // VC9 has a bug in search_n
  111. // SJB: This *should* work but has not been tested yet *TODO: Test!
  112. message_list_iterator_t found = std::find_if(message_list->begin(), message_list->end(),
  113.  std::bind2nd(eq_message_throttle_entry(), entry));
  114. #else
  115.   message_list_iterator_t found = std::search_n(message_list->begin(), message_list->end(),
  116.     1, entry, eq_message_throttle_entry);
  117. #endif
  118. if (found == message_list->end())
  119. {
  120. // This message was not found.  Add it to the list.
  121. message_list->push_front(entry);
  122. return TRUE;
  123. }
  124. else
  125. {
  126. // This message was already in the list.
  127. return FALSE;
  128. }
  129. }
  130. BOOL LLMessageThrottle::addAgentAlert(const LLUUID& agent, const LLUUID& task, const std::string& mesg)
  131. {
  132. message_list_t* message_list = &(mMessageList[MTC_AGENT_ALERT]);
  133. // Concatenate from,to,mesg into one string.
  134. std::ostringstream full_mesg;
  135. full_mesg << agent << task << mesg;
  136. // Create an entry for this message.
  137. size_t hash = llhash(full_mesg.str().c_str());
  138. LLMessageThrottleEntry entry(hash, LLFrameTimer::getTotalTime());
  139. // Check if this message is already in the list.
  140. #if _MSC_VER >= 1500 // VC9 has a bug in search_n
  141. // SJB: This *should* work but has not been tested yet *TODO: Test!
  142. message_list_iterator_t found = std::find_if(message_list->begin(), message_list->end(),
  143.  std::bind2nd(eq_message_throttle_entry(), entry));
  144. #else
  145. message_list_iterator_t found = std::search_n(message_list->begin(), message_list->end(),
  146.   1, entry, eq_message_throttle_entry);
  147. #endif
  148. if (found == message_list->end())
  149. {
  150. // This message was not found.  Add it to the list.
  151. message_list->push_front(entry);
  152. return TRUE;
  153. }
  154. else
  155. {
  156. // This message was already in the list.
  157. return FALSE;
  158. }
  159. }