From 0c95f8bf30bc6ec9835c5a298bf27115a2a92047 Mon Sep 17 00:00:00 2001
From: "Brad Payne (Vir Linden)" <vir@lindenlab.com>
Date: Thu, 19 Nov 2009 12:03:11 -0500
Subject: [PATCH] For EXT-2623 - object missing wearables and attachments on
 initial login

--HG--
branch : avatar-pipeline
---
 indra/newview/llagentwearables.cpp    | 57 +++++++++++++++++++++++++--
 indra/newview/llinventoryobserver.cpp |  3 +-
 2 files changed, 55 insertions(+), 5 deletions(-)

diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp
index 6b2033fc6f9..e78ea88b94f 100644
--- a/indra/newview/llagentwearables.cpp
+++ b/indra/newview/llagentwearables.cpp
@@ -2196,11 +2196,48 @@ void LLInitialWearablesFetch::processContents()
 	delete this;
 }
 
+class LLFetchAndLinkObserver: public LLInventoryFetchObserver
+{
+public:
+	LLFetchAndLinkObserver(LLInventoryFetchObserver::item_ref_t& ids):
+		m_ids(ids)
+	{
+		llwarns << "LLFetchAndLinkObserver" << llendl;
+	}
+	~LLFetchAndLinkObserver()
+	{
+		llwarns << "~LLFetchAndLinkObserver" << llendl;
+	}
+	virtual void done()
+	{
+		gInventory.removeObserver(this);
+		// Link to all fetched items in COF.
+		for (LLInventoryFetchObserver::item_ref_t::iterator it = m_ids.begin();
+			 it != m_ids.end();
+			 ++it)
+		{
+			LLUUID id = *it;
+			LLViewerInventoryItem *item = gInventory.getItem(*it);
+			if (!item)
+			{
+				llwarns << "LLFetchAndLinkObserver fetch failed!" << llendl;
+				continue;
+			}
+			link_inventory_item(gAgent.getID(), item->getLinkedUUID(), LLAppearanceManager::instance().getCOF(), item->getName(),
+								LLAssetType::AT_LINK, LLPointer<LLInventoryCallback>(NULL));
+		}
+
+	}
+private:
+	LLInventoryFetchObserver::item_ref_t m_ids;
+};
+
 void LLInitialWearablesFetch::processWearablesMessage()
 {
 	if (!mAgentInitialWearables.empty()) // We have an empty current outfit folder, use the message data instead.
 	{
-		const LLUUID current_outfit_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT);
+		const LLUUID current_outfit_id = LLAppearanceManager::instance().getCOF();
+		LLInventoryFetchObserver::item_ref_t ids;
 		for (U8 i = 0; i < mAgentInitialWearables.size(); ++i)
 		{
 			// Populate the current outfit folder with links to the wearables passed in the message
@@ -2209,9 +2246,7 @@ void LLInitialWearablesFetch::processWearablesMessage()
 			if (wearable_data->mAssetID.notNull())
 			{
 #ifdef USE_CURRENT_OUTFIT_FOLDER
-				const std::string link_name = "WearableLink"; // Unimportant what this is named, it isn't exposed.
-				link_inventory_item(gAgent.getID(), wearable_data->mItemID, current_outfit_id, link_name,
-									LLAssetType::AT_LINK, LLPointer<LLInventoryCallback>(NULL));
+				ids.push_back(wearable_data->mItemID);
 #endif
 				// Fetch the wearables
 				LLWearableList::instance().getAsset(wearable_data->mAssetID,
@@ -2225,6 +2260,20 @@ void LLInitialWearablesFetch::processWearablesMessage()
 				<< wearable_data->mItemID << " assetID " << wearable_data->mAssetID << llendl;
 			}
 		}
+
+		// Need to fetch the inventory items for ids, then create links to them after they arrive.
+		LLFetchAndLinkObserver *fetcher = new LLFetchAndLinkObserver(ids);
+		fetcher->fetchItems(ids);
+		// If no items to be fetched, done will never be triggered.
+		// TODO: Change LLInventoryFetchObserver::fetchItems to trigger done() on this condition.
+		if (fetcher->isEverythingComplete())
+		{
+			fetcher->done();
+		}
+		else
+		{
+			gInventory.addObserver(fetcher);
+		}
 	}
 	else
 	{
diff --git a/indra/newview/llinventoryobserver.cpp b/indra/newview/llinventoryobserver.cpp
index 3ccf593d278..e904fb6c921 100644
--- a/indra/newview/llinventoryobserver.cpp
+++ b/indra/newview/llinventoryobserver.cpp
@@ -115,7 +115,8 @@ void LLInventoryFetchObserver::changed(U32 mask)
 				// BUG: This can cause done() to get called prematurely below.
 				// This happens with the LLGestureInventoryFetchObserver that
 				// loads gestures at startup. JC
-				it = mIncomplete.erase(it);
+				//it = mIncomplete.erase(it);
+				++it;
 				continue;
 			}
 			if(item->isComplete())
-- 
GitLab