diff options
Diffstat (limited to 'indra/newview/llavatarlist.cpp')
-rw-r--r-- | indra/newview/llavatarlist.cpp | 136 |
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 { |