summaryrefslogtreecommitdiff
path: root/indra/newview/llfriendcard.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llfriendcard.cpp')
-rw-r--r--indra/newview/llfriendcard.cpp166
1 files changed, 161 insertions, 5 deletions
diff --git a/indra/newview/llfriendcard.cpp b/indra/newview/llfriendcard.cpp
index 97b7f3e9ad..c956657825 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);
}
@@ -135,14 +171,14 @@ const LLUUID LLFriendCardsManager::extractAvatarID(const LLUUID& avatarID)
// and this method must be called before any actions with friend list
void LLFriendCardsManager::ensureFriendFoldersExist()
{
- LLUUID callingCardsFolderID = gInventory.findCategoryUUIDForType(LLAssetType::AT_CALLINGCARD);
+ const LLUUID callingCardsFolderID = gInventory.findCategoryUUIDForType(LLFolderType::FT_CALLINGCARD);
LLUUID friendFolderUUID = findFriendFolderUUIDImpl();
if (friendFolderUUID.isNull())
{
friendFolderUUID = gInventory.createNewCategory(callingCardsFolderID,
- LLAssetType::AT_CALLINGCARD, get_friend_folder_name());
+ LLFolderType::FT_CALLINGCARD, get_friend_folder_name());
}
LLUUID friendAllSubfolderUUID = findFriendAllSubfolderUUIDImpl();
@@ -150,7 +186,7 @@ void LLFriendCardsManager::ensureFriendFoldersExist()
if (friendAllSubfolderUUID.isNull())
{
friendAllSubfolderUUID = gInventory.createNewCategory(friendFolderUUID,
- LLAssetType::AT_CALLINGCARD, get_friend_all_subfolder_name());
+ LLFolderType::FT_CALLINGCARD, get_friend_all_subfolder_name());
}
}
@@ -166,6 +202,93 @@ bool LLFriendCardsManager::isItemInAnyFriendsList(const LLViewerInventoryItem* i
return items.count() > 0;
}
+
+bool LLFriendCardsManager::isObjDirectDescendentOfCategory(const LLInventoryObject* obj,
+ const LLViewerInventoryCategory* cat) const
+{
+ // we need both params to proceed.
+ if ( !obj || !cat )
+ return false;
+
+ // Need to check that target category is in the Calling Card/Friends folder.
+ // In other case function returns unpredictable result.
+ if ( !isCategoryInFriendFolder(cat) )
+ return false;
+
+ bool result = false;
+
+ LLInventoryModel::item_array_t* items;
+ LLInventoryModel::cat_array_t* cats;
+
+ gInventory.lockDirectDescendentArrays(cat->getUUID(), cats, items);
+ if ( items )
+ {
+ if ( obj->getType() == LLAssetType::AT_CALLINGCARD )
+ {
+ // For CALLINGCARD compare items by creator's id, if they are equal assume
+ // that it is same card and return true. Note: UUID's of compared items
+ // may be not equal. Also, we already know that obj should be type of LLInventoryItem,
+ // but in case inventory database is broken check what dynamic_cast returns.
+ const LLInventoryItem* item = dynamic_cast < const LLInventoryItem* > (obj);
+ if ( item )
+ {
+ LLUUID creator_id = item->getCreatorUUID();
+ LLViewerInventoryItem* cur_item = NULL;
+ for ( S32 i = items->count() - 1; i >= 0; --i )
+ {
+ cur_item = items->get(i);
+ if ( creator_id == cur_item->getCreatorUUID() )
+ {
+ result = true;
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ // Else check that items have same type and name.
+ // Note: UUID's of compared items also may be not equal.
+ std::string obj_name = obj->getName();
+ LLViewerInventoryItem* cur_item = NULL;
+ for ( S32 i = items->count() - 1; i >= 0; --i )
+ {
+ cur_item = items->get(i);
+ if ( obj->getType() != cur_item->getType() )
+ continue;
+ if ( obj_name == cur_item->getName() )
+ {
+ result = true;
+ break;
+ }
+ }
+ }
+ }
+ if ( !result && cats )
+ {
+ // There is no direct descendent in items, so check categories.
+ // If target obj and descendent category have same type and name
+ // then return true. Note: UUID's of compared items also may be not equal.
+ std::string obj_name = obj->getName();
+ LLViewerInventoryCategory* cur_cat = NULL;
+ for ( S32 i = cats->count() - 1; i >= 0; --i )
+ {
+ cur_cat = cats->get(i);
+ if ( obj->getType() != cur_cat->getType() )
+ continue;
+ if ( obj_name == cur_cat->getName() )
+ {
+ result = true;
+ break;
+ }
+ }
+ }
+ gInventory.unlockDirectDescendentArrays(cat->getUUID());
+
+ return result;
+}
+
+
bool LLFriendCardsManager::isCategoryInFriendFolder(const LLViewerInventoryCategory* cat) const
{
if (NULL == cat)
@@ -182,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();
@@ -210,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
@@ -264,7 +411,7 @@ void LLFriendCardsManager::collectFriendsLists(folderid_buddies_map_t& folderBud
/************************************************************************/
const LLUUID& LLFriendCardsManager::findFriendFolderUUIDImpl() const
{
- LLUUID callingCardsFolderID = gInventory.findCategoryUUIDForType(LLAssetType::AT_CALLINGCARD);
+ const LLUUID callingCardsFolderID = gInventory.findCategoryUUIDForType(LLFolderType::FT_CALLINGCARD);
std::string friendFolderName = get_friend_folder_name();
@@ -374,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)
{
@@ -433,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