summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
Diffstat (limited to 'indra')
-rw-r--r--indra/llmessage/llavatarnamecache.cpp281
-rw-r--r--indra/llmessage/llavatarnamecache.h98
-rw-r--r--indra/newview/llappviewer.cpp13
-rw-r--r--indra/newview/llavatarlist.cpp2
-rw-r--r--indra/newview/llfloaterconversationpreview.cpp2
-rw-r--r--indra/newview/llfloaterimcontainer.cpp4
-rw-r--r--indra/newview/llfloaterimnearbychat.cpp2
-rw-r--r--indra/newview/llfloaterpreference.cpp4
-rw-r--r--indra/newview/llimprocessing.cpp2
-rw-r--r--indra/newview/llimview.cpp2
-rw-r--r--indra/newview/llnotificationhandlerutil.cpp2
-rw-r--r--indra/newview/llstartup.cpp9
-rw-r--r--indra/newview/llviewermenu.cpp1
13 files changed, 220 insertions, 202 deletions
diff --git a/indra/llmessage/llavatarnamecache.cpp b/indra/llmessage/llavatarnamecache.cpp
index ba1a2a035e..6a287f0cc5 100644
--- a/indra/llmessage/llavatarnamecache.cpp
+++ b/indra/llmessage/llavatarnamecache.cpp
@@ -49,101 +49,22 @@
#include <map>
#include <set>
-namespace LLAvatarNameCache
-{
- use_display_name_signal_t mUseDisplayNamesSignal;
-
- // Cache starts in a paused state until we can determine if the
- // current region supports display names.
- bool sRunning = false;
-
- // Use the People API (modern) for fetching name if true. Use the old legacy protocol if false.
- // For testing, there's a UsePeopleAPI setting that can be flipped (must restart viewer).
- bool sUsePeopleAPI = true;
-
- // Base lookup URL for name service.
- // On simulator, loaded from indra.xml
- // On viewer, usually a simulator capability (at People API team's request)
- // Includes the trailing slash, like "http://pdp60.lindenlab.com:8000/agents/"
- std::string sNameLookupURL;
-
- // Accumulated agent IDs for next query against service
- typedef std::set<LLUUID> ask_queue_t;
- ask_queue_t sAskQueue;
-
- // Agent IDs that have been requested, but with no reply.
- // Maps agent ID to frame time request was made.
- typedef std::map<LLUUID, F64> pending_queue_t;
- pending_queue_t sPendingQueue;
-
- // Callbacks to fire when we received a name.
- // May have multiple callbacks for a single ID, which are
- // represented as multiple slots bound to the signal.
- // Avoid copying signals via pointers.
- typedef std::map<LLUUID, callback_signal_t*> signal_map_t;
- signal_map_t sSignalMap;
-
- // The cache at last, i.e. avatar names we know about.
- typedef std::map<LLUUID, LLAvatarName> cache_t;
- cache_t sCache;
-
- // Send bulk lookup requests a few times a second at most.
- // Only need per-frame timing resolution.
- LLFrameTimer sRequestTimer;
-
- // Maximum time an unrefreshed cache entry is allowed.
- const F64 MAX_UNREFRESHED_TIME = 20.0 * 60.0;
-
- // Time when unrefreshed cached names were checked last.
- static F64 sLastExpireCheck;
-
- // Time-to-live for a temp cache entry.
- const F64 TEMP_CACHE_ENTRY_LIFETIME = 60.0;
-
- LLCore::HttpRequest::ptr_t sHttpRequest;
- LLCore::HttpHeaders::ptr_t sHttpHeaders;
- LLCore::HttpOptions::ptr_t sHttpOptions;
- LLCore::HttpRequest::policy_t sHttpPolicy;
- LLCore::HttpRequest::priority_t sHttpPriority;
-
- //-----------------------------------------------------------------------
- // Internal methods
- //-----------------------------------------------------------------------
-
- // Handle name response off network.
- void processName(const LLUUID& agent_id,
- const LLAvatarName& av_name);
-
- void requestNamesViaCapability();
-
- // Legacy name system callbacks
- void legacyNameCallback(const LLUUID& agent_id,
- const std::string& full_name,
- bool is_group);
- void legacyNameFetch(const LLUUID& agent_id,
- const std::string& full_name,
- bool is_group);
-
- void requestNamesViaLegacy();
-
- // Do a single callback to a given slot
- void fireSignal(const LLUUID& agent_id,
- const callback_slot_t& slot,
- const LLAvatarName& av_name);
-
- // Is a request in-flight over the network?
- bool isRequestPending(const LLUUID& agent_id);
- // Erase expired names from cache
- void eraseUnrefreshed();
+// Time-to-live for a temp cache entry.
+const F64 TEMP_CACHE_ENTRY_LIFETIME = 60.0;
+// Maximum time an unrefreshed cache entry is allowed.
+const F64 MAX_UNREFRESHED_TIME = 20.0 * 60.0;
- bool expirationFromCacheControl(const LLSD& headers, F64 *expires);
+// Send bulk lookup requests a few times a second at most.
+// Only need per-frame timing resolution.
+static LLFrameTimer sRequestTimer;
- // This is a coroutine.
- void requestAvatarNameCache_(std::string url, std::vector<LLUUID> agentIds);
-
- void handleAvNameCacheSuccess(const LLSD &data, const LLSD &httpResult);
-}
+// static to avoid unnessesary dependencies
+LLCore::HttpRequest::ptr_t sHttpRequest;
+LLCore::HttpHeaders::ptr_t sHttpHeaders;
+LLCore::HttpOptions::ptr_t sHttpOptions;
+LLCore::HttpRequest::policy_t sHttpPolicy;
+LLCore::HttpRequest::priority_t sHttpPriority;
/* Sample response:
<?xml version="1.0"?>
@@ -187,6 +108,30 @@ namespace LLAvatarNameCache
// Coroutine for sending and processing avatar name cache requests.
// Do not call directly. See documentation in lleventcoro.h and llcoro.h for
// further explanation.
+
+LLAvatarNameCache::LLAvatarNameCache()
+{
+ // Will be set to running later
+ // For now fail immediate lookups and query async ones.
+ mRunning = false;
+
+ mUsePeopleAPI = true;
+
+ sHttpRequest = LLCore::HttpRequest::ptr_t(new LLCore::HttpRequest());
+ sHttpHeaders = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders());
+ sHttpOptions = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions());
+ sHttpPolicy = LLCore::HttpRequest::DEFAULT_POLICY_ID;
+ sHttpPriority = 0;
+}
+
+LLAvatarNameCache::~LLAvatarNameCache()
+{
+ sHttpRequest.reset();
+ sHttpHeaders.reset();
+ sHttpOptions.reset();
+ mCache.clear();
+}
+
void LLAvatarNameCache::requestAvatarNameCache_(std::string url, std::vector<LLUUID> agentIds)
{
LL_DEBUGS("AvNameCache") << "Entering coroutine " << LLCoros::instance().getName()
@@ -205,7 +150,7 @@ void LLAvatarNameCache::requestAvatarNameCache_(std::string url, std::vector<LLU
{
bool success = true;
- LLCoreHttpUtil::HttpCoroutineAdapter httpAdapter("NameCache", LLAvatarNameCache::sHttpPolicy);
+ LLCoreHttpUtil::HttpCoroutineAdapter httpAdapter("NameCache", sHttpPolicy);
LLSD results = httpAdapter.getAndSuspend(sHttpRequest, url);
LL_DEBUGS() << results << LL_ENDL;
@@ -233,12 +178,12 @@ void LLAvatarNameCache::requestAvatarNameCache_(std::string url, std::vector<LLU
for ( ; it != agentIds.end(); ++it)
{
const LLUUID& agent_id = *it;
- LLAvatarNameCache::handleAgentError(agent_id);
+ LLAvatarNameCache::getInstance()->handleAgentError(agent_id);
}
return;
}
- LLAvatarNameCache::handleAvNameCacheSuccess(results, httpResults);
+ LLAvatarNameCache::getInstance()->handleAvNameCacheSuccess(results, httpResults);
}
catch (...)
@@ -300,15 +245,15 @@ void LLAvatarNameCache::handleAvNameCacheSuccess(const LLSD &data, const LLSD &h
}
}
LL_DEBUGS("AvNameCache") << "LLAvatarNameResponder::result "
- << LLAvatarNameCache::sCache.size() << " cached names"
+ << LLAvatarNameCache::mCache.size() << " cached names"
<< LL_ENDL;
}
// Provide some fallback for agents that return errors
void LLAvatarNameCache::handleAgentError(const LLUUID& agent_id)
{
- std::map<LLUUID,LLAvatarName>::iterator existing = sCache.find(agent_id);
- if (existing == sCache.end())
+ std::map<LLUUID,LLAvatarName>::iterator existing = mCache.find(agent_id);
+ if (existing == mCache.end())
{
// there is no existing cache entry, so make a temporary name from legacy
LL_WARNS("AvNameCache") << "LLAvatarNameCache get legacy for agent "
@@ -322,7 +267,7 @@ void LLAvatarNameCache::handleAgentError(const LLUUID& agent_id)
// been returned by the get method, there is no need to signal anyone
// Clear this agent from the pending list
- LLAvatarNameCache::sPendingQueue.erase(agent_id);
+ LLAvatarNameCache::mPendingQueue.erase(agent_id);
LLAvatarName& av_name = existing->second;
LL_DEBUGS("AvNameCache") << "LLAvatarNameCache use cache for agent " << agent_id << LL_ENDL;
@@ -341,19 +286,19 @@ void LLAvatarNameCache::processName(const LLUUID& agent_id, const LLAvatarName&
}
// Add to the cache
- sCache[agent_id] = av_name;
+ mCache[agent_id] = av_name;
// Suppress request from the queue
- sPendingQueue.erase(agent_id);
+ mPendingQueue.erase(agent_id);
// Signal everyone waiting on this name
- signal_map_t::iterator sig_it = sSignalMap.find(agent_id);
- if (sig_it != sSignalMap.end())
+ signal_map_t::iterator sig_it = mSignalMap.find(agent_id);
+ if (sig_it != mSignalMap.end())
{
callback_signal_t* signal = sig_it->second;
(*signal)(agent_id, av_name);
- sSignalMap.erase(agent_id);
+ mSignalMap.erase(agent_id);
delete signal;
signal = NULL;
@@ -379,16 +324,16 @@ void LLAvatarNameCache::requestNamesViaCapability()
U32 ids = 0;
ask_queue_t::const_iterator it;
- while(!sAskQueue.empty())
+ while(!mAskQueue.empty())
{
- it = sAskQueue.begin();
+ it = mAskQueue.begin();
LLUUID agent_id = *it;
- sAskQueue.erase(it);
+ mAskQueue.erase(it);
if (url.empty())
{
// ...starting new request
- url += sNameLookupURL;
+ url += mNameLookupURL;
url += "?ids=";
ids = 1;
}
@@ -402,7 +347,7 @@ void LLAvatarNameCache::requestNamesViaCapability()
agent_ids.push_back(agent_id);
// mark request as pending
- sPendingQueue[agent_id] = now;
+ mPendingQueue[agent_id] = now;
if (url.size() > NAME_URL_SEND_THRESHOLD)
{
@@ -432,7 +377,7 @@ void LLAvatarNameCache::legacyNameCallback(const LLUUID& agent_id,
// Retrieve the name and set it to never (or almost never...) expire: when we are using the legacy
// protocol, we do not get an expiration date for each name and there's no reason to ask the
// data again and again so we set the expiration time to the largest value admissible.
- std::map<LLUUID,LLAvatarName>::iterator av_record = sCache.find(agent_id);
+ std::map<LLUUID,LLAvatarName>::iterator av_record = LLAvatarNameCache::getInstance()->mCache.find(agent_id);
LLAvatarName& av_name = av_record->second;
av_name.setExpires(MAX_UNREFRESHED_TIME);
}
@@ -451,7 +396,7 @@ void LLAvatarNameCache::legacyNameFetch(const LLUUID& agent_id,
av_name.fromString(full_name);
// Add to cache: we're still using the new cache even if we're using the old (legacy) protocol.
- processName(agent_id, av_name);
+ LLAvatarNameCache::getInstance()->processName(agent_id, av_name);
}
void LLAvatarNameCache::requestNamesViaLegacy()
@@ -460,15 +405,15 @@ void LLAvatarNameCache::requestNamesViaLegacy()
F64 now = LLFrameTimer::getTotalSeconds();
std::string full_name;
ask_queue_t::const_iterator it;
- for (S32 requests = 0; !sAskQueue.empty() && requests < MAX_REQUESTS; ++requests)
+ for (S32 requests = 0; !mAskQueue.empty() && requests < MAX_REQUESTS; ++requests)
{
- it = sAskQueue.begin();
+ it = mAskQueue.begin();
LLUUID agent_id = *it;
- sAskQueue.erase(it);
+ mAskQueue.erase(it);
// Mark as pending first, just in case the callback is immediately
// invoked below. This should never happen in practice.
- sPendingQueue[agent_id] = now;
+ mPendingQueue[agent_id] = now;
LL_DEBUGS("AvNameCache") << "agent " << agent_id << LL_ENDL;
@@ -477,26 +422,6 @@ void LLAvatarNameCache::requestNamesViaLegacy()
}
}
-void LLAvatarNameCache::initClass(bool running, bool usePeopleAPI)
-{
- sRunning = running;
- sUsePeopleAPI = usePeopleAPI;
-
- sHttpRequest = LLCore::HttpRequest::ptr_t(new LLCore::HttpRequest());
- sHttpHeaders = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders());
- sHttpOptions = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions());
- sHttpPolicy = LLCore::HttpRequest::DEFAULT_POLICY_ID;
- sHttpPriority = 0;
-}
-
-void LLAvatarNameCache::cleanupClass()
-{
- sHttpRequest.reset();
- sHttpHeaders.reset();
- sHttpOptions.reset();
- sCache.clear();
-}
-
bool LLAvatarNameCache::importFile(std::istream& istr)
{
LLSD data;
@@ -517,9 +442,9 @@ bool LLAvatarNameCache::importFile(std::istream& istr)
{
agent_id.set(it->first);
av_name.fromLLSD( it->second );
- sCache[agent_id] = av_name;
+ mCache[agent_id] = av_name;
}
- LL_INFOS("AvNameCache") << "LLAvatarNameCache loaded " << sCache.size() << LL_ENDL;
+ LL_INFOS("AvNameCache") << "LLAvatarNameCache loaded " << mCache.size() << LL_ENDL;
// Some entries may have expired since the cache was stored,
// but they will be flushed in the first call to eraseUnrefreshed
// from LLAvatarNameResponder::idle
@@ -531,9 +456,9 @@ void LLAvatarNameCache::exportFile(std::ostream& ostr)
{
LLSD agents;
F64 max_unrefreshed = LLFrameTimer::getTotalSeconds() - MAX_UNREFRESHED_TIME;
- LL_INFOS("AvNameCache") << "LLAvatarNameCache at exit cache has " << sCache.size() << LL_ENDL;
- cache_t::const_iterator it = sCache.begin();
- for ( ; it != sCache.end(); ++it)
+ LL_INFOS("AvNameCache") << "LLAvatarNameCache at exit cache has " << mCache.size() << LL_ENDL;
+ cache_t::const_iterator it = mCache.begin();
+ for ( ; it != mCache.end(); ++it)
{
const LLUUID& agent_id = it->first;
const LLAvatarName& av_name = it->second;
@@ -552,23 +477,28 @@ void LLAvatarNameCache::exportFile(std::ostream& ostr)
void LLAvatarNameCache::setNameLookupURL(const std::string& name_lookup_url)
{
- sNameLookupURL = name_lookup_url;
+ mNameLookupURL = name_lookup_url;
}
bool LLAvatarNameCache::hasNameLookupURL()
{
- return !sNameLookupURL.empty();
+ return !mNameLookupURL.empty();
+}
+
+void LLAvatarNameCache::setUsePeopleAPI(bool use_api)
+{
+ mUsePeopleAPI = use_api;
}
bool LLAvatarNameCache::usePeopleAPI()
{
- return hasNameLookupURL() && sUsePeopleAPI;
+ return hasNameLookupURL() && mUsePeopleAPI;
}
void LLAvatarNameCache::idle()
{
// By convention, start running at first idle() call
- sRunning = true;
+ mRunning = true;
// *TODO: Possibly re-enabled this based on People API load measurements
// 100 ms is the threshold for "user speed" operations, so we can
@@ -579,7 +509,7 @@ void LLAvatarNameCache::idle()
return;
}
- if (!sAskQueue.empty())
+ if (!mAskQueue.empty())
{
if (usePeopleAPI())
{
@@ -592,7 +522,7 @@ void LLAvatarNameCache::idle()
}
}
- if (sAskQueue.empty())
+ if (mAskQueue.empty())
{
// cleared the list, reset the request timer.
sRequestTimer.resetWithExpiry(SECS_BETWEEN_REQUESTS);
@@ -607,8 +537,8 @@ bool LLAvatarNameCache::isRequestPending(const LLUUID& agent_id)
bool isPending = false;
const F64 PENDING_TIMEOUT_SECS = 5.0 * 60.0;
- pending_queue_t::const_iterator it = sPendingQueue.find(agent_id);
- if (it != sPendingQueue.end())
+ pending_queue_t::const_iterator it = mPendingQueue.find(agent_id);
+ if (it != mPendingQueue.end())
{
// in the list of requests in flight, retry if too old
F64 expire_time = LLFrameTimer::getTotalSeconds() - PENDING_TIMEOUT_SECS;
@@ -622,11 +552,11 @@ void LLAvatarNameCache::eraseUnrefreshed()
F64 now = LLFrameTimer::getTotalSeconds();
F64 max_unrefreshed = now - MAX_UNREFRESHED_TIME;
- if (!sLastExpireCheck || sLastExpireCheck < max_unrefreshed)
+ if (!mLastExpireCheck || mLastExpireCheck < max_unrefreshed)
{
- sLastExpireCheck = now;
+ mLastExpireCheck = now;
S32 expired = 0;
- for (cache_t::iterator it = sCache.begin(); it != sCache.end();)
+ for (cache_t::iterator it = mCache.begin(); it != mCache.end();)
{
const LLAvatarName& av_name = it->second;
if (av_name.mExpires < max_unrefreshed)
@@ -635,7 +565,7 @@ void LLAvatarNameCache::eraseUnrefreshed()
<< " user '" << av_name.getAccountName() << "' "
<< "expired " << now - av_name.mExpires << " secs ago"
<< LL_ENDL;
- sCache.erase(it++);
+ mCache.erase(it++);
expired++;
}
else
@@ -644,19 +574,24 @@ void LLAvatarNameCache::eraseUnrefreshed()
}
}
LL_INFOS("AvNameCache") << "LLAvatarNameCache expired " << expired << " cached avatar names, "
- << sCache.size() << " remaining" << LL_ENDL;
+ << mCache.size() << " remaining" << LL_ENDL;
}
}
+//static, wrapper
+bool LLAvatarNameCache::get(const LLUUID& agent_id, LLAvatarName *av_name)
+{
+ return LLAvatarNameCache::getInstance()->getName(agent_id, av_name);
+}
// fills in av_name if it has it in the cache, even if expired (can check expiry time)
// returns bool specifying if av_name was filled, false otherwise
-bool LLAvatarNameCache::get(const LLUUID& agent_id, LLAvatarName *av_name)
+bool LLAvatarNameCache::getName(const LLUUID& agent_id, LLAvatarName *av_name)
{
- if (sRunning)
+ if (mRunning)
{
// ...only do immediate lookups when cache is running
- std::map<LLUUID,LLAvatarName>::iterator it = sCache.find(agent_id);
- if (it != sCache.end())
+ std::map<LLUUID,LLAvatarName>::iterator it = mCache.find(agent_id);
+ if (it != mCache.end())
{
*av_name = it->second;
@@ -667,7 +602,7 @@ bool LLAvatarNameCache::get(const LLUUID& agent_id, LLAvatarName *av_name)
{
LL_DEBUGS("AvNameCache") << "LLAvatarNameCache refresh agent " << agent_id
<< LL_ENDL;
- sAskQueue.insert(agent_id);
+ mAskQueue.insert(agent_id);
}
}
@@ -678,7 +613,7 @@ bool LLAvatarNameCache::get(const LLUUID& agent_id, LLAvatarName *av_name)
if (!isRequestPending(agent_id))
{
LL_DEBUGS("AvNameCache") << "LLAvatarNameCache queue request for agent " << agent_id << LL_ENDL;
- sAskQueue.insert(agent_id);
+ mAskQueue.insert(agent_id);
}
return false;
@@ -693,15 +628,21 @@ void LLAvatarNameCache::fireSignal(const LLUUID& agent_id,
signal(agent_id, av_name);
}
+// static, wrapper
LLAvatarNameCache::callback_connection_t LLAvatarNameCache::get(const LLUUID& agent_id, callback_slot_t slot)
{
+ return LLAvatarNameCache::getInstance()->getNameCallback(agent_id, slot);
+}
+
+LLAvatarNameCache::callback_connection_t LLAvatarNameCache::getNameCallback(const LLUUID& agent_id, callback_slot_t slot)
+{
callback_connection_t connection;
- if (sRunning)
+ if (mRunning)
{
// ...only do immediate lookups when cache is running
- std::map<LLUUID,LLAvatarName>::iterator it = sCache.find(agent_id);
- if (it != sCache.end())
+ std::map<LLUUID,LLAvatarName>::iterator it = mCache.find(agent_id);
+ if (it != mCache.end())
{
const LLAvatarName& av_name = it->second;
@@ -717,17 +658,17 @@ LLAvatarNameCache::callback_connection_t LLAvatarNameCache::get(const LLUUID& ag
// schedule a request
if (!isRequestPending(agent_id))
{
- sAskQueue.insert(agent_id);
+ mAskQueue.insert(agent_id);
}
// always store additional callback, even if request is pending
- signal_map_t::iterator sig_it = sSignalMap.find(agent_id);
- if (sig_it == sSignalMap.end())
+ signal_map_t::iterator sig_it = mSignalMap.find(agent_id);
+ if (sig_it == mSignalMap.end())
{
// ...new callback for this id
callback_signal_t* signal = new callback_signal_t();
connection = signal->connect(slot);
- sSignalMap[agent_id] = signal;
+ mSignalMap[agent_id] = signal;
}
else
{
@@ -760,20 +701,20 @@ void LLAvatarNameCache::setUseUsernames(bool use)
void LLAvatarNameCache::erase(const LLUUID& agent_id)
{
- sCache.erase(agent_id);
+ mCache.erase(agent_id);
}
void LLAvatarNameCache::insert(const LLUUID& agent_id, const LLAvatarName& av_name)
{
// *TODO: update timestamp if zero?
- sCache[agent_id] = av_name;
+ mCache[agent_id] = av_name;
}
LLUUID LLAvatarNameCache::findIdByName(const std::string& name)
{
std::map<LLUUID, LLAvatarName>::iterator it;
- std::map<LLUUID, LLAvatarName>::iterator end = sCache.end();
- for (it = sCache.begin(); it != end; ++it)
+ std::map<LLUUID, LLAvatarName>::iterator end = mCache.end();
+ for (it = mCache.begin(); it != end; ++it)
{
if (it->second.getUserName() == name)
{
diff --git a/indra/llmessage/llavatarnamecache.h b/indra/llmessage/llavatarnamecache.h
index 63e067c939..ba89d569f3 100644
--- a/indra/llmessage/llavatarnamecache.h
+++ b/indra/llmessage/llavatarnamecache.h
@@ -29,21 +29,20 @@
#define LLAVATARNAMECACHE_H
#include "llavatarname.h" // for convenience
+#include "llsingleton.h"
#include <boost/signals2.hpp>
+#include <set>
class LLSD;
class LLUUID;
-namespace LLAvatarNameCache
+class LLAvatarNameCache : public LLSingleton<LLAvatarNameCache>
{
+ LLSINGLETON(LLAvatarNameCache);
+ ~LLAvatarNameCache();
+public:
typedef boost::signals2::signal<void (void)> use_display_name_signal_t;
- // Until the cache is set running, immediate lookups will fail and
- // async lookups will be queued. This allows us to block requests
- // until we know if the first region supports display names.
- void initClass(bool running, bool usePeopleAPI);
- void cleanupClass();
-
// Import/export the name cache to file.
bool importFile(std::istream& istr);
void exportFile(std::ostream& ostr);
@@ -55,6 +54,7 @@ namespace LLAvatarNameCache
// Do we have a valid lookup URL, i.e. are we trying to use the
// more recent display name lookup system?
bool hasNameLookupURL();
+ void setUsePeopleAPI(bool use_api);
bool usePeopleAPI();
// Periodically makes a batch request for display names not already in
@@ -63,7 +63,8 @@ namespace LLAvatarNameCache
// If name is in cache, returns true and fills in provided LLAvatarName
// otherwise returns false.
- bool get(const LLUUID& agent_id, LLAvatarName *av_name);
+ static bool get(const LLUUID& agent_id, LLAvatarName *av_name);
+ bool getName(const LLUUID& agent_id, LLAvatarName *av_name);
// Callback types for get() below
typedef boost::signals2::signal<
@@ -74,7 +75,8 @@ namespace LLAvatarNameCache
// Fetches name information and calls callbacks.
// If name information is in cache, callbacks will be called immediately.
- callback_connection_t get(const LLUUID& agent_id, callback_slot_t slot);
+ static callback_connection_t get(const LLUUID& agent_id, callback_slot_t slot);
+ callback_connection_t getNameCallback(const LLUUID& agent_id, callback_slot_t slot);
// Set display name: flips the switch and triggers the callbacks.
void setUseDisplayNames(bool use);
@@ -100,7 +102,83 @@ namespace LLAvatarNameCache
F64 nameExpirationFromHeaders(const LLSD& headers);
void addUseDisplayNamesCallback(const use_display_name_signal_t::slot_type& cb);
-}
+
+private:
+ // Handle name response off network.
+ void processName(const LLUUID& agent_id,
+ const LLAvatarName& av_name);
+
+ void requestNamesViaCapability();
+
+ // Legacy name system callbacks
+ static void legacyNameCallback(const LLUUID& agent_id,
+ const std::string& full_name,
+ bool is_group);
+ static void legacyNameFetch(const LLUUID& agent_id,
+ const std::string& full_name,
+ bool is_group);
+
+ void requestNamesViaLegacy();
+
+ // Do a single callback to a given slot
+ void fireSignal(const LLUUID& agent_id,
+ const callback_slot_t& slot,
+ const LLAvatarName& av_name);
+
+ // Is a request in-flight over the network?
+ bool isRequestPending(const LLUUID& agent_id);
+
+ // Erase expired names from cache
+ void eraseUnrefreshed();
+
+ bool expirationFromCacheControl(const LLSD& headers, F64 *expires);
+
+ // This is a coroutine.
+ static void requestAvatarNameCache_(std::string url, std::vector<LLUUID> agentIds);
+
+ void handleAvNameCacheSuccess(const LLSD &data, const LLSD &httpResult);
+
+private:
+
+ use_display_name_signal_t mUseDisplayNamesSignal;
+
+ // Cache starts in a paused state until we can determine if the
+ // current region supports display names.
+ bool mRunning;
+
+ // Use the People API (modern) for fetching name if true. Use the old legacy protocol if false.
+ // For testing, there's a UsePeopleAPI setting that can be flipped (must restart viewer).
+ bool mUsePeopleAPI;
+
+ // Base lookup URL for name service.
+ // On simulator, loaded from indra.xml
+ // On viewer, usually a simulator capability (at People API team's request)
+ // Includes the trailing slash, like "http://pdp60.lindenlab.com:8000/agents/"
+ std::string mNameLookupURL;
+
+ // Accumulated agent IDs for next query against service
+ typedef std::set<LLUUID> ask_queue_t;
+ ask_queue_t mAskQueue;
+
+ // Agent IDs that have been requested, but with no reply.
+ // Maps agent ID to frame time request was made.
+ typedef std::map<LLUUID, F64> pending_queue_t;
+ pending_queue_t mPendingQueue;
+
+ // Callbacks to fire when we received a name.
+ // May have multiple callbacks for a single ID, which are
+ // represented as multiple slots bound to the signal.
+ // Avoid copying signals via pointers.
+ typedef std::map<LLUUID, callback_signal_t*> signal_map_t;
+ signal_map_t mSignalMap;
+
+ // The cache at last, i.e. avatar names we know about.
+ typedef std::map<LLUUID, LLAvatarName> cache_t;
+ cache_t mCache;
+
+ // Time when unrefreshed cached names were checked last.
+ F64 mLastExpireCheck;
+};
// Parse a cache-control header to get the max-age delta-seconds.
// Returns true if header has max-age param and it parses correctly.
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 151039acce..823ded7a50 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -4509,7 +4509,7 @@ void LLAppViewer::loadNameCache()
llifstream name_cache_stream(filename.c_str());
if(name_cache_stream.is_open())
{
- if ( ! LLAvatarNameCache::importFile(name_cache_stream))
+ if ( ! LLAvatarNameCache::getInstance()->importFile(name_cache_stream))
{
LL_WARNS("AppInit") << "removing invalid '" << filename << "'" << LL_ENDL;
name_cache_stream.close();
@@ -4536,7 +4536,7 @@ void LLAppViewer::saveNameCache()
llofstream name_cache_stream(filename.c_str());
if(name_cache_stream.is_open())
{
- LLAvatarNameCache::exportFile(name_cache_stream);
+ LLAvatarNameCache::getInstance()->exportFile(name_cache_stream);
}
// real names cache
@@ -5143,7 +5143,8 @@ void LLAppViewer::idleNameCache()
// granted to neighbor regions before the main agent gets there. Can't
// do it in the move-into-region code because cap not guaranteed to be
// granted yet, for example on teleport.
- bool had_capability = LLAvatarNameCache::hasNameLookupURL();
+ LLAvatarNameCache *name_cache = LLAvatarNameCache::getInstance();
+ bool had_capability = LLAvatarNameCache::getInstance()->hasNameLookupURL();
std::string name_lookup_url;
name_lookup_url.reserve(128); // avoid a memory allocation below
name_lookup_url = region->getCapability("GetDisplayNames");
@@ -5160,12 +5161,12 @@ void LLAppViewer::idleNameCache()
{
name_lookup_url += '/';
}
- LLAvatarNameCache::setNameLookupURL(name_lookup_url);
+ name_cache->setNameLookupURL(name_lookup_url);
}
else
{
// Display names not available on this region
- LLAvatarNameCache::setNameLookupURL( std::string() );
+ name_cache->setNameLookupURL( std::string() );
}
// Error recovery - did we change state?
@@ -5175,7 +5176,7 @@ void LLAppViewer::idleNameCache()
LLVOAvatar::invalidateNameTags();
}
- LLAvatarNameCache::idle();
+ name_cache->idle();
}
//
diff --git a/indra/newview/llavatarlist.cpp b/indra/newview/llavatarlist.cpp
index 513f25e301..b0715a3afd 100644
--- a/indra/newview/llavatarlist.cpp
+++ b/indra/newview/llavatarlist.cpp
@@ -154,7 +154,7 @@ LLAvatarList::LLAvatarList(const Params& p)
mLITUpdateTimer->start();
}
- LLAvatarNameCache::addUseDisplayNamesCallback(boost::bind(&LLAvatarList::handleDisplayNamesOptionChanged, this));
+ LLAvatarNameCache::getInstance()->addUseDisplayNamesCallback(boost::bind(&LLAvatarList::handleDisplayNamesOptionChanged, this));
}
diff --git a/indra/newview/llfloaterconversationpreview.cpp b/indra/newview/llfloaterconversationpreview.cpp
index 66198b3bf6..4905ce5fc2 100644
--- a/indra/newview/llfloaterconversationpreview.cpp
+++ b/indra/newview/llfloaterconversationpreview.cpp
@@ -221,7 +221,7 @@ void LLFloaterConversationPreview::showHistory()
else
{
std::string legacy_name = gCacheName->buildLegacyName(from);
- from_id = LLAvatarNameCache::findIdByName(legacy_name);
+ from_id = LLAvatarNameCache::getInstance()->findIdByName(legacy_name);
}
LLChat chat;
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 30d05ae287..21420b122b 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -237,7 +237,7 @@ BOOL LLFloaterIMContainer::postBuild()
collapseMessagesPane(gSavedPerAccountSettings.getBOOL("ConversationsMessagePaneCollapsed"));
collapseConversationsPane(gSavedPerAccountSettings.getBOOL("ConversationsListPaneCollapsed"), false);
- LLAvatarNameCache::addUseDisplayNamesCallback(boost::bind(&LLFloaterIMSessionTab::processChatHistoryStyleUpdate, false));
+ LLAvatarNameCache::getInstance()->addUseDisplayNamesCallback(boost::bind(&LLFloaterIMSessionTab::processChatHistoryStyleUpdate, false));
mMicroChangedSignal = LLVoiceClient::getInstance()->MicroChangedCallback(boost::bind(&LLFloaterIMContainer::updateSpeakBtnState, this));
if (! mMessagesPane->isCollapsed() && ! mConversationsPane->isCollapsed())
@@ -267,7 +267,7 @@ BOOL LLFloaterIMContainer::postBuild()
// We'll take care of view updates on idle
gIdleCallbacks.addFunction(idle, this);
// When display name option change, we need to reload all participant names
- LLAvatarNameCache::addUseDisplayNamesCallback(boost::bind(&LLFloaterIMContainer::processParticipantsStyleUpdate, this));
+ LLAvatarNameCache::getInstance()->addUseDisplayNamesCallback(boost::bind(&LLFloaterIMContainer::processParticipantsStyleUpdate, this));
mParticipantRefreshTimer.setTimerExpirySec(0);
mParticipantRefreshTimer.start();
diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp
index f9efd13608..a6531ed7e1 100644
--- a/indra/newview/llfloaterimnearbychat.cpp
+++ b/indra/newview/llfloaterimnearbychat.cpp
@@ -228,7 +228,7 @@ void LLFloaterIMNearbyChat::loadHistory()
else
{
std::string legacy_name = gCacheName->buildLegacyName(from);
- from_id = LLAvatarNameCache::findIdByName(legacy_name);
+ from_id = LLAvatarNameCache::getInstance()->findIdByName(legacy_name);
}
LLChat chat;
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 98e4cefebb..64a71c502d 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -278,13 +278,13 @@ bool callback_clear_browser_cache(const LLSD& notification, const LLSD& response
void handleNameTagOptionChanged(const LLSD& newvalue)
{
- LLAvatarNameCache::setUseUsernames(gSavedSettings.getBOOL("NameTagShowUsernames"));
+ LLAvatarNameCache::getInstance()->setUseUsernames(gSavedSettings.getBOOL("NameTagShowUsernames"));
LLVOAvatar::invalidateNameTags();
}
void handleDisplayNamesOptionChanged(const LLSD& newvalue)
{
- LLAvatarNameCache::setUseDisplayNames(newvalue.asBoolean());
+ LLAvatarNameCache::getInstance()->setUseDisplayNames(newvalue.asBoolean());
LLVOAvatar::invalidateNameTags();
}
diff --git a/indra/newview/llimprocessing.cpp b/indra/newview/llimprocessing.cpp
index d59c301210..3606a439a6 100644
--- a/indra/newview/llimprocessing.cpp
+++ b/indra/newview/llimprocessing.cpp
@@ -695,7 +695,7 @@ void LLIMProcessing::processNewMessage(LLUUID from_id,
// The group notice packet does not have an AgentID. Obtain one from the name cache.
// If last name is "Resident" strip it out so the cache name lookup works.
std::string legacy_name = gCacheName->buildLegacyName(original_name);
- agent_id = LLAvatarNameCache::findIdByName(legacy_name);
+ agent_id = LLAvatarNameCache::getInstance()->findIdByName(legacy_name);
if (agent_id.isNull())
{
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 8ec8c0a563..fc2f50b3f6 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -806,7 +806,7 @@ void LLIMModel::LLIMSession::addMessagesFromHistory(const std::list<LLSD>& histo
{
// convert it to a legacy name if we have a complete name
std::string legacy_name = gCacheName->buildLegacyName(from);
- from_id = LLAvatarNameCache::findIdByName(legacy_name);
+ from_id = LLAvatarNameCache::getInstance()->findIdByName(legacy_name);
}
std::string timestamp = msg[LL_IM_TIME];
diff --git a/indra/newview/llnotificationhandlerutil.cpp b/indra/newview/llnotificationhandlerutil.cpp
index 6a58196760..9a3f1a853a 100644
--- a/indra/newview/llnotificationhandlerutil.cpp
+++ b/indra/newview/llnotificationhandlerutil.cpp
@@ -177,7 +177,7 @@ void LLHandlerUtil::logGroupNoticeToIMGroup(
{
// Legacy support and fallback method
// if we can't retrieve sender id from group notice system message, try to lookup it from cache
- sender_id = LLAvatarNameCache::findIdByName(sender_name);
+ sender_id = LLAvatarNameCache::getInstance()->findIdByName(sender_name);
}
logToIM(IM_SESSION_GROUP_START, group_name, sender_name, payload["message"],
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 8be453ad6c..15b3ba75c9 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -2833,9 +2833,10 @@ void LLStartUp::initNameCache()
// Start cache in not-running state until we figure out if we have
// capabilities for display name lookup
- LLAvatarNameCache::initClass(false,gSavedSettings.getBOOL("UsePeopleAPI"));
- LLAvatarNameCache::setUseDisplayNames(gSavedSettings.getBOOL("UseDisplayNames"));
- LLAvatarNameCache::setUseUsernames(gSavedSettings.getBOOL("NameTagShowUsernames"));
+ LLAvatarNameCache* cache_inst = LLAvatarNameCache::getInstance();
+ cache_inst->setUsePeopleAPI(gSavedSettings.getBOOL("UsePeopleAPI"));
+ cache_inst->setUseDisplayNames(gSavedSettings.getBOOL("UseDisplayNames"));
+ cache_inst->setUseUsernames(gSavedSettings.getBOOL("NameTagShowUsernames"));
}
@@ -2850,8 +2851,6 @@ void LLStartUp::initExperiences()
void LLStartUp::cleanupNameCache()
{
- SUBSYSTEM_CLEANUP(LLAvatarNameCache);
-
delete gCacheName;
gCacheName = NULL;
}
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 8f90225359..f1c073ed84 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -8653,7 +8653,6 @@ class LLWorldPostProcess : public view_listener_t
void handle_flush_name_caches()
{
- SUBSYSTEM_CLEANUP(LLAvatarNameCache);
if (gCacheName) gCacheName->clear();
}