diff options
author | Mike Antipov <mantipov@productengine.com> | 2009-11-04 16:02:12 +0200 |
---|---|---|
committer | Mike Antipov <mantipov@productengine.com> | 2009-11-04 16:02:12 +0200 |
commit | 14af8485fd3759cda8b5471b0f6171b832d3e1b4 (patch) | |
tree | 62edba6caabc5ba89299d3e191acc564d363cf5d | |
parent | 380bb0ce09913ae05000c86fb0a0ed410ead1089 (diff) |
Fixed normal bug EXT-2061 ("All" list doesn't contain any friends while "Online" list isn't empty in "Friends" tab on People Panel)
- added code to force fetching of Inventory "Friends/All" folder in case it is incomplete on startup.
--HG--
branch : product-engine
-rw-r--r-- | indra/newview/llfriendcard.cpp | 71 | ||||
-rw-r--r-- | indra/newview/llfriendcard.h | 13 |
2 files changed, 82 insertions, 2 deletions
diff --git a/indra/newview/llfriendcard.cpp b/indra/newview/llfriendcard.cpp index fbcaeee01f..724b18ded2 100644 --- a/indra/newview/llfriendcard.cpp +++ b/indra/newview/llfriendcard.cpp @@ -91,8 +91,44 @@ const LLUUID& get_folder_uuid(const LLUUID& parentFolderUUID, LLInventoryCollect return LLUUID::null; } + +// LLViewerInventoryCategory::fetchDescendents has it own period of fetching. +// for now it is FETCH_TIMER_EXPIRY = 10.0f; So made our period a bit more. +const F32 FETCH_FRIENDS_DESCENDENTS_PERIOD = 11.0f; + + +/** + * Intended to call passed callback after the specified period of time. + * + * Implemented to fix an issue when Inventory folders are in incomplete state. See EXT-2061, EXT-1935, EXT-813. + * For now it uses to periodically sync Inventory Friends/All folder with a Agent's Friends List + * until it is complete. + */ +class FriendListUpdater : public LLEventTimer +{ +public: + typedef boost::function<bool()> callback_t; + + FriendListUpdater(callback_t cb, F32 period) + : LLEventTimer(period) + , mCallback(cb) + { + mEventTimer.start(); + } + + virtual BOOL tick() // from LLEventTimer + { + return mCallback(); + } + +private: + callback_t mCallback; +}; + + // LLFriendCardsManager Constructor / Destructor LLFriendCardsManager::LLFriendCardsManager() +: mFriendsAllFolderCompleted(true) { LLAvatarTracker::instance().addObserver(this); } @@ -269,7 +305,7 @@ bool LLFriendCardsManager::isAnyFriendCategory(const LLUUID& catID) const return TRUE == gInventory.isObjectDescendentOf(catID, friendFolderID); } -void LLFriendCardsManager::syncFriendsFolder() +bool LLFriendCardsManager::syncFriendsFolder() { //lets create "Friends" and "Friends/All" in the Inventory "Calling Cards" if they are absent LLFriendCardsManager::instance().ensureFriendFoldersExist(); @@ -297,11 +333,35 @@ void LLFriendCardsManager::syncFriendsFolder() // 2. Add missing Friend Cards for friends LLAvatarTracker::buddy_map_t::const_iterator buddy_it = all_buddies.begin(); llinfos << "try to build friends, count: " << all_buddies.size() << llendl; + mFriendsAllFolderCompleted = true; for(; buddy_it != all_buddies.end(); ++buddy_it) { const LLUUID& buddy_id = (*buddy_it).first; addFriendCardToInventory(buddy_id); } + + if (!mFriendsAllFolderCompleted) + { + forceFriendListIsLoaded(findFriendAllSubfolderUUIDImpl()); + + static bool timer_started = false; + if (!timer_started) + { + lldebugs << "Create and start timer to sync Inventory Friends All folder with Friends list" << llendl; + + // do not worry about destruction of the FriendListUpdater. + // It will be deleted by LLEventTimer::updateClass when FriendListUpdater::tick() returns true. + new FriendListUpdater(boost::bind(&LLFriendCardsManager::syncFriendsFolder, this), + FETCH_FRIENDS_DESCENDENTS_PERIOD); + } + timer_started = true; + } + else + { + lldebugs << "Friends/All Inventory folder is synchronized with the Agent's Friends List" << llendl; + } + + return mFriendsAllFolderCompleted; } void LLFriendCardsManager::collectFriendsLists(folderid_buddies_map_t& folderBuddiesMap) const @@ -461,7 +521,9 @@ bool LLFriendCardsManager::addFriendCardToInventory(const LLUUID& avatarID) LLUUID friendListFolderID = findFriendAllSubfolderUUIDImpl(); if (shouldBeAdded && !invModel->isCategoryComplete(friendListFolderID)) { + mFriendsAllFolderCompleted = false; shouldBeAdded = false; + lldebugs << "Friends/All category is not completed" << llendl; } if (shouldBeAdded) { @@ -520,4 +582,11 @@ void LLFriendCardsManager::onFriendListUpdate(U32 changed_mask) } } +void LLFriendCardsManager::forceFriendListIsLoaded(const LLUUID& folder_id) const +{ + bool fetching_inventory = gInventory.fetchDescendentsOf(folder_id); + lldebugs << "Trying to fetch descendants of Friends/All Inventory folder, fetched: " + << fetching_inventory << llendl; +} + // EOF diff --git a/indra/newview/llfriendcard.h b/indra/newview/llfriendcard.h index 6ada342831..feea05bc1d 100644 --- a/indra/newview/llfriendcard.h +++ b/indra/newview/llfriendcard.h @@ -89,8 +89,10 @@ public: /** * Synchronizes content of the Calling Card/Friends/All Global Inventory folder with Agent's Friend List + * + * @return true - if folder is already synchronized, false otherwise. */ - void syncFriendsFolder(); + bool syncFriendsFolder(); /*! * \brief @@ -144,11 +146,20 @@ private: void onFriendListUpdate(U32 changed_mask); + /** + * Force fetching of the Inventory folder specified by passed folder's LLUUID. + * + * It only sends request to server, server reply should be processed in other place. + * Because request can be sent via UDP we need to periodically check if request was completed with success. + */ + void forceFriendListIsLoaded(const LLUUID& folder_id) const; + private: typedef std::set<LLUUID> avatar_uuid_set_t; avatar_uuid_set_t mBuddyIDSet; + bool mFriendsAllFolderCompleted; }; #endif // LL_LLFRIENDCARD_H |