summaryrefslogtreecommitdiff
path: root/indra/newview/llavatarlist.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llavatarlist.cpp')
-rw-r--r--indra/newview/llavatarlist.cpp136
1 files changed, 91 insertions, 45 deletions
diff --git a/indra/newview/llavatarlist.cpp b/indra/newview/llavatarlist.cpp
index ee14a2ff86..36f9780ad0 100644
--- a/indra/newview/llavatarlist.cpp
+++ b/indra/newview/llavatarlist.cpp
@@ -41,6 +41,10 @@
static LLDefaultChildRegistry::Register<LLAvatarList> r("avatar_list");
+// Maximum number of avatars that can be added to a list in one pass.
+// Used to limit time spent for avatar list update per frame.
+static const unsigned ADD_LIMIT = 50;
+
static bool findInsensitive(std::string haystack, const std::string& needle_upper)
{
LLStringUtil::toUpper(haystack);
@@ -65,6 +69,7 @@ LLAvatarList::LLAvatarList(const Params& p)
: LLFlatListView(p)
, mOnlineGoFirst(p.online_go_first)
, mContextMenu(NULL)
+, mDirty(true) // to force initial update
{
setCommitOnSelectionChange(true);
@@ -72,44 +77,40 @@ LLAvatarList::LLAvatarList(const Params& p)
setComparator(&NAME_COMPARATOR);
}
-void LLAvatarList::computeDifference(
- const std::vector<LLUUID>& vnew_unsorted,
- std::vector<LLUUID>& vadded,
- std::vector<LLUUID>& vremoved)
+// virtual
+void LLAvatarList::draw()
{
- std::vector<LLUUID> vcur;
- std::vector<LLUUID> vnew = vnew_unsorted;
+ if (mDirty)
+ refresh();
- // Convert LLSDs to LLUUIDs.
- {
- std::vector<LLSD> vcur_values;
- getValues(vcur_values);
+ LLFlatListView::draw();
+}
- for (size_t i=0; i<vcur_values.size(); i++)
- vcur.push_back(vcur_values[i].asUUID());
+void LLAvatarList::setNameFilter(const std::string& filter)
+{
+ if (mNameFilter != filter)
+ {
+ mNameFilter = filter;
+ setDirty();
}
+}
- std::sort(vcur.begin(), vcur.end());
- std::sort(vnew.begin(), vnew.end());
-
- std::vector<LLUUID>::iterator it;
- size_t maxsize = llmax(vcur.size(), vnew.size());
- vadded.resize(maxsize);
- vremoved.resize(maxsize);
-
- // what to remove
- it = set_difference(vcur.begin(), vcur.end(), vnew.begin(), vnew.end(), vremoved.begin());
- vremoved.erase(it, vremoved.end());
-
- // what to add
- it = set_difference(vnew.begin(), vnew.end(), vcur.begin(), vcur.end(), vadded.begin());
- vadded.erase(it, vadded.end());
+void LLAvatarList::sortByName()
+{
+ setComparator(&NAME_COMPARATOR);
+ sort();
}
-BOOL LLAvatarList::update(const std::vector<LLUUID>& all_buddies, const std::string& name_filter)
+//////////////////////////////////////////////////////////////////////////
+// PROTECTED SECTION
+//////////////////////////////////////////////////////////////////////////
+
+void LLAvatarList::refresh()
{
- BOOL have_names = TRUE;
- bool have_filter = name_filter != LLStringUtil::null;
+ bool have_names = TRUE;
+ bool add_limit_exceeded = false;
+ bool modified = false;
+ bool have_filter = !mNameFilter.empty();
// Save selection.
std::vector<LLUUID> selected_ids;
@@ -118,22 +119,36 @@ BOOL LLAvatarList::update(const std::vector<LLUUID>& all_buddies, const std::str
// Determine what to add and what to remove.
std::vector<LLUUID> added, removed;
- LLAvatarList::computeDifference(all_buddies, added, removed);
+ LLAvatarList::computeDifference(getIDs(), added, removed);
// Handle added items.
+ unsigned nadded = 0;
for (std::vector<LLUUID>::const_iterator it=added.begin(); it != added.end(); it++)
{
std::string name;
const LLUUID& buddy_id = *it;
- have_names &= gCacheName->getFullName(buddy_id, name);
- if (!have_filter || findInsensitive(name, name_filter))
- addNewItem(buddy_id, name, LLAvatarTracker::instance().isBuddyOnline(buddy_id));
+ have_names &= (bool)gCacheName->getFullName(buddy_id, name);
+ if (!have_filter || findInsensitive(name, mNameFilter))
+ {
+ if (nadded >= ADD_LIMIT)
+ {
+ add_limit_exceeded = true;
+ break;
+ }
+ else
+ {
+ addNewItem(buddy_id, name, LLAvatarTracker::instance().isBuddyOnline(buddy_id));
+ modified = true;
+ nadded++;
+ }
+ }
}
// Handle removed items.
for (std::vector<LLUUID>::const_iterator it=removed.begin(); it != removed.end(); it++)
{
removeItemByUUID(*it);
+ modified = true;
}
// Handle filter.
@@ -146,9 +161,12 @@ BOOL LLAvatarList::update(const std::vector<LLUUID>& all_buddies, const std::str
{
std::string name;
const LLUUID& buddy_id = it->asUUID();
- have_names &= gCacheName->getFullName(buddy_id, name);
- if (!findInsensitive(name, name_filter))
+ have_names &= (bool)gCacheName->getFullName(buddy_id, name);
+ if (!findInsensitive(name, mNameFilter))
+ {
removeItemByUUID(buddy_id);
+ modified = true;
+ }
}
}
@@ -167,18 +185,15 @@ BOOL LLAvatarList::update(const std::vector<LLUUID>& all_buddies, const std::str
//
// Otherwise, if we have no filter then no need to update again
// because the items will update their names.
- return !have_filter || have_names;
-}
+ bool dirty = add_limit_exceeded || (have_filter && !have_names);
+ setDirty(dirty);
-void LLAvatarList::sortByName()
-{
- setComparator(&NAME_COMPARATOR);
- sort();
+ // Commit if we've added/removed items.
+ if (modified)
+ onCommit();
}
-//////////////////////////////////////////////////////////////////////////
-// PROTECTED SECTION
-//////////////////////////////////////////////////////////////////////////
+
void LLAvatarList::addNewItem(const LLUUID& id, const std::string& name, BOOL is_bold, EAddPosition pos)
{
LLAvatarListItem* item = new LLAvatarListItem();
@@ -194,8 +209,39 @@ void LLAvatarList::addNewItem(const LLUUID& id, const std::string& name, BOOL is
addItem(item, id, pos);
}
+void LLAvatarList::computeDifference(
+ const std::vector<LLUUID>& vnew_unsorted,
+ std::vector<LLUUID>& vadded,
+ std::vector<LLUUID>& vremoved)
+{
+ std::vector<LLUUID> vcur;
+ std::vector<LLUUID> vnew = vnew_unsorted;
+ // Convert LLSDs to LLUUIDs.
+ {
+ std::vector<LLSD> vcur_values;
+ getValues(vcur_values);
+ for (size_t i=0; i<vcur_values.size(); i++)
+ vcur.push_back(vcur_values[i].asUUID());
+ }
+
+ std::sort(vcur.begin(), vcur.end());
+ std::sort(vnew.begin(), vnew.end());
+
+ std::vector<LLUUID>::iterator it;
+ size_t maxsize = llmax(vcur.size(), vnew.size());
+ vadded.resize(maxsize);
+ vremoved.resize(maxsize);
+
+ // what to remove
+ it = set_difference(vcur.begin(), vcur.end(), vnew.begin(), vnew.end(), vremoved.begin());
+ vremoved.erase(it, vremoved.end());
+
+ // what to add
+ it = set_difference(vnew.begin(), vnew.end(), vcur.begin(), vcur.end(), vadded.begin());
+ vadded.erase(it, vadded.end());
+}
bool LLAvatarItemComparator::compare(const LLPanel* item1, const LLPanel* item2) const
{