From 8e5d95cba8a65d01ea605ebbfba7d6065cd5bd40 Mon Sep 17 00:00:00 2001
From: "Brad Payne (Vir Linden)" <vir@lindenlab.com>
Date: Thu, 25 Feb 2010 10:59:59 -0500
Subject: [PATCH] For EXT-5333: Bodyparts missing from appearance and COF. 
 createStandardWearables() now COF-based

---
 indra/newview/llagentwearables.cpp | 117 +++++++++++++++++++++++++----
 indra/newview/llappearancemgr.cpp  |   1 +
 indra/newview/llstartup.cpp        |   2 +-
 3 files changed, 103 insertions(+), 17 deletions(-)

diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp
index 08cd101b01d..11ac103b3a1 100644
--- a/indra/newview/llagentwearables.cpp
+++ b/indra/newview/llagentwearables.cpp
@@ -245,6 +245,7 @@ void LLAgentWearables::setAvatarObject(LLVOAvatarSelf *avatar)
 // wearables
 LLAgentWearables::createStandardWearablesAllDoneCallback::~createStandardWearablesAllDoneCallback()
 {
+	llinfos << "destructor - all done?" << llendl;
 	gAgentWearables.createStandardWearablesAllDone();
 }
 
@@ -271,10 +272,16 @@ LLAgentWearables::addWearableToAgentInventoryCallback::addWearableToAgentInvento
 	mTodo(todo),
 	mCB(cb)
 {
+	llinfos << "constructor" << llendl;
 }
 
 void LLAgentWearables::addWearableToAgentInventoryCallback::fire(const LLUUID& inv_item)
 {
+	if (mTodo & CALL_CREATESTANDARDDONE)
+	{
+		llinfos << "callback fired, inv_item " << inv_item.asString() << llendl;
+	}
+
 	if (inv_item.isNull())
 		return;
 
@@ -294,6 +301,7 @@ void LLAgentWearables::addWearableToAgentInventoryCallback::fire(const LLUUID& i
 	 */
 	if (mTodo & CALL_CREATESTANDARDDONE)
 	{
+		LLAppearanceManager::instance().addCOFItemLink(inv_item,false);
 		gAgentWearables.createStandardWearablesDone(mType, mIndex);
 	}
 	if (mTodo & CALL_MAKENEWOUTFITDONE)
@@ -311,6 +319,8 @@ void LLAgentWearables::addWearabletoAgentInventoryDone(const S32 type,
 													   const LLUUID& item_id,
 													   LLWearable* wearable)
 {
+	llinfos << "type " << type << " index " << index << " item " << item_id.asString() << llendl;
+
 	if (item_id.isNull())
 		return;
 
@@ -1140,6 +1150,80 @@ void LLAgentWearables::addLocalTextureObject(const EWearableType wearable_type,
 	wearable->setLocalTextureObject(texture_type, lto);
 }
 
+class OnWearableItemCreatedCB: public LLInventoryCallback
+{
+public:
+	OnWearableItemCreatedCB():
+		mWearablesAwaitingItems(WT_COUNT,NULL)
+	{
+		llinfos << "created callback" << llendl;
+	}
+	/* virtual */ void fire(const LLUUID& inv_item)
+	{
+		llinfos << "One item created " << inv_item.asString() << llendl;
+		LLViewerInventoryItem *item = gInventory.getItem(inv_item);
+		mItemsToLink.put(item);
+		updatePendingWearable(inv_item);
+	}
+	~OnWearableItemCreatedCB()
+	{
+		llinfos << "All items created" << llendl;
+		LLPointer<LLInventoryCallback> link_waiter = new LLUpdateAppearanceOnDestroy;
+		LLAppearanceManager::instance().linkAll(LLAppearanceManager::instance().getCOF(),
+												mItemsToLink,
+												link_waiter);
+	}
+	void addPendingWearable(LLWearable *wearable)
+	{
+		if (!wearable)
+		{
+			llwarns << "no wearable" << llendl;
+			return;
+		}
+		EWearableType type = wearable->getType();
+		if (type<WT_COUNT)
+		{
+			mWearablesAwaitingItems[type] = wearable;
+		}
+		else
+		{
+			llwarns << "invalid type " << type << llendl;
+		}
+	}
+	void updatePendingWearable(const LLUUID& inv_item)
+	{
+		LLViewerInventoryItem *item = gInventory.getItem(inv_item);
+		if (!item)
+		{
+			llwarns << "no item found" << llendl;
+			return;
+		}
+		if (!item->isWearableType())
+		{
+			llwarns << "non-wearable item found" << llendl;
+			return;
+		}
+		if (item && item->isWearableType())
+		{
+			EWearableType type = item->getWearableType();
+			if (type < WT_COUNT)
+			{
+				LLWearable *wearable = mWearablesAwaitingItems[type];
+				if (wearable)
+					wearable->setItemID(inv_item);
+			}
+			else
+			{
+				llwarns << "invalid wearable type " << type << llendl;
+			}
+		}
+	}
+	
+private:
+	LLInventoryModel::item_array_t mItemsToLink;
+	std::vector<LLWearable*> mWearablesAwaitingItems;
+};
+
 void LLAgentWearables::createStandardWearables(BOOL female)
 {
 	llwarns << "Creating Standard " << (female ? "female" : "male")
@@ -1169,35 +1253,34 @@ void LLAgentWearables::createStandardWearables(BOOL female)
 			FALSE  //WT_SKIRT
 		};
 
+	LLPointer<LLInventoryCallback> cb = new OnWearableItemCreatedCB;
 	for (S32 i=0; i < WT_COUNT; i++)
 	{
-		bool once = false;
-		LLPointer<LLRefCount> donecb = NULL;
 		if (create[i])
 		{
-			if (!once)
-			{
-				once = true;
-				donecb = new createStandardWearablesAllDoneCallback;
-			}
 			llassert(getWearableCount((EWearableType)i) == 0);
 			LLWearable* wearable = LLWearableList::instance().createNewWearable((EWearableType)i);
-			U32 index = pushWearable((EWearableType)i,wearable);
+			((OnWearableItemCreatedCB*)(&(*cb)))->addPendingWearable(wearable);
 			// no need to update here...
-			LLPointer<LLInventoryCallback> cb =
-				new addWearableToAgentInventoryCallback(
-					donecb,
-					i,
-					index,
-					wearable,
-					addWearableToAgentInventoryCallback::CALL_CREATESTANDARDDONE);
-			addWearableToAgentInventory(cb, wearable, LLUUID::null, FALSE);
+			LLUUID category_id = LLUUID::null;
+			create_inventory_item(gAgent.getID(),
+								  gAgent.getSessionID(),
+								  category_id,
+								  wearable->getTransactionID(),
+								  wearable->getName(),
+								  wearable->getDescription(),
+								  wearable->getAssetType(),
+								  LLInventoryType::IT_WEARABLE,
+								  wearable->getType(),
+								  wearable->getPermissions().getMaskNextOwner(),
+								  cb);
 		}
 	}
 }
 
 void LLAgentWearables::createStandardWearablesDone(S32 type, U32 index)
 {
+	llinfos << "type " << type << " index " << index << llendl;
 	if (mAvatarObject)
 	{
 		mAvatarObject->updateVisualParams();
@@ -1208,6 +1291,8 @@ void LLAgentWearables::createStandardWearablesAllDone()
 {
 	// ... because sendAgentWearablesUpdate will notify inventory
 	// observers.
+	llinfos << "all done?" << llendl;
+
 	mWearablesLoaded = TRUE; 
 	checkWearablesLoaded();
 	
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index c9da08701d7..71df0642367 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -565,6 +565,7 @@ class RecoveredItemCB: public LLInventoryCallback
 	{
 		llinfos << "Recovered item for type " << mType << llendl;
 		LLViewerInventoryItem *itemp = gInventory.getItem(item_id);
+		mWearable->setItemID(item_id);
 		LLPointer<LLInventoryCallback> cb = new RecoveredItemLinkCB(mType,mWearable,mHolder);
 		mHolder->mTypesToRecover.erase(mType);
 		link_inventory_item( gAgent.getID(),
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 83f773fadcd..1f829458e91 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -2554,7 +2554,7 @@ void LLStartUp::loadInitialOutfit( const std::string& outfit_folder_name,
 	LLUUID cat_id = findDescendentCategoryIDByName(
 		gInventory.getLibraryRootFolderID(),
 		outfit_folder_name);
-	if (cat_id.isNull())
+	if (true || (cat_id.isNull()))
 	{
 		gAgentWearables.createStandardWearables(gender);
 	}
-- 
GitLab