From 0d66c6870406578819465033a9e312c8e4eaad43 Mon Sep 17 00:00:00 2001
From: Aaron Stone <stone@lindenlab.com>
Date: Tue, 11 Oct 2011 15:46:40 -0700
Subject: EXP-625 No longer stuck as a cloud on initial login by fixing logic
 around fetching library items from the Inventory capabilities.

---
 indra/newview/llinventoryobserver.cpp | 19 ++++++++++++-------
 indra/newview/llstartup.cpp           | 16 ++++++++++++----
 2 files changed, 24 insertions(+), 11 deletions(-)

diff --git a/indra/newview/llinventoryobserver.cpp b/indra/newview/llinventoryobserver.cpp
index ceba4a0191..9db175ec2e 100644
--- a/indra/newview/llinventoryobserver.cpp
+++ b/indra/newview/llinventoryobserver.cpp
@@ -202,6 +202,7 @@ void LLInventoryFetchItemsObserver::changed(U32 mask)
 void fetch_items_from_llsd(const LLSD& items_llsd)
 {
 	if (!items_llsd.size() || gDisconnected) return;
+
 	LLSD body;
 	body[0]["cap_name"] = "FetchInventory2";
 	body[1]["cap_name"] = "FetchLib2";
@@ -212,7 +213,7 @@ void fetch_items_from_llsd(const LLSD& items_llsd)
 			body[0]["items"].append(items_llsd[i]);
 			continue;
 		}
-		if (items_llsd[i]["owner_id"].asString() == ALEXANDRIA_LINDEN_ID.asString())
+		else if (items_llsd[i]["owner_id"].asString() == ALEXANDRIA_LINDEN_ID.asString())
 		{
 			body[1]["items"].append(items_llsd[i]);
 			continue;
@@ -221,19 +222,23 @@ void fetch_items_from_llsd(const LLSD& items_llsd)
 		
 	for (S32 i=0; i<body.size(); i++)
 	{
-		if(!gAgent.getRegion())
+		if (!gAgent.getRegion())
 		{
-			llwarns<<"Agent's region is null"<<llendl;
+			llwarns << "Agent's region is null" << llendl;
 			break;
 		}
-		if (0 >= body[i].size()) continue;
-		std::string url = gAgent.getRegion()->getCapability(body[i]["cap_name"].asString());
 
+		if (0 == body[i]["items"].size()) {
+			lldebugs << "Skipping body with no items to fetch" << llendl;
+			continue;
+		}
+
+		std::string url = gAgent.getRegion()->getCapability(body[i]["cap_name"].asString());
 		if (!url.empty())
 		{
 			body[i]["agent_id"]	= gAgent.getID();
 			LLHTTPClient::post(url, body[i], new LLInventoryModel::fetchInventoryResponder(body[i]));
-			break;
+			continue;
 		}
 
 		LLMessageSystem* msg = gMessageSystem;
@@ -303,7 +308,7 @@ void LLInventoryFetchItemsObserver::startFetch()
 		// It's incomplete, so put it on the incomplete container, and
 		// pack this on the message.
 		mIncomplete.push_back(*it);
-		
+
 		// Prepare the data to fetch
 		LLSD item_entry;
 		item_entry["owner_id"] = owner_id;
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 749acea6c1..de2afac0b8 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -2480,7 +2480,7 @@ void LLStartUp::copyLibraryGestures(const std::string& same_gender_gestures)
 void LLStartUp::loadInitialOutfit( const std::string& outfit_folder_name,
 								   const std::string& gender_name )
 {
-	llinfos << "starting" << llendl;
+	lldebugs << "starting" << llendl;
 
 	// Not going through the processAgentInitialWearables path, so need to set this here.
 	LLAppearanceMgr::instance().setAttachmentInvLinkEnable(true);
@@ -2491,11 +2491,13 @@ void LLStartUp::loadInitialOutfit( const std::string& outfit_folder_name,
 	std::string same_gender_gestures;
 	if (gender_name == "male")
 	{
+		lldebugs << "male" << llendl;
 		gender = OPT_MALE;
 		same_gender_gestures = MALE_GESTURES_FOLDER;
 	}
 	else
 	{
+		lldebugs << "female" << llendl;
 		gender = OPT_FEMALE;
 		same_gender_gestures = FEMALE_GESTURES_FOLDER;
 	}
@@ -2507,6 +2509,7 @@ void LLStartUp::loadInitialOutfit( const std::string& outfit_folder_name,
 		outfit_folder_name);
 	if (cat_id.isNull())
 	{
+		lldebugs << "standard wearables" << llendl;
 		gAgentWearables.createStandardWearables(gender);
 	}
 	else
@@ -2517,26 +2520,31 @@ void LLStartUp::loadInitialOutfit( const std::string& outfit_folder_name,
 		bool do_append = false;
 		LLViewerInventoryCategory *cat = gInventory.getCategory(cat_id);
 		LLAppearanceMgr::instance().wearInventoryCategory(cat, do_copy, do_append);
+		lldebugs << "initial outfit category id: " << cat_id << llendl;
 	}
 
 	// Copy gestures
 	copyLibraryGestures(same_gender_gestures);
-	
+
 	// This is really misnamed -- it means we have started loading
 	// an outfit/shape that will give the avatar a gender eventually. JC
 	gAgent.setGenderChosen(TRUE);
-
 }
 
 //static
 void LLStartUp::saveInitialOutfit()
 {
-	if (sInitialOutfit.empty()) return;
+	if (sInitialOutfit.empty()) {
+		lldebugs << "sInitialOutfit is empty" << llendl;
+		return;
+	}
 	
 	if (sWearablesLoadedCon.connected())
 	{
+		lldebugs << "sWearablesLoadedCon is connected, disconnecting" << llendl;
 		sWearablesLoadedCon.disconnect();
 	}
+	lldebugs << "calling makeNewOutfitLinks( \"" << sInitialOutfit << "\" )" << llendl;
 	LLAppearanceMgr::getInstance()->makeNewOutfitLinks(sInitialOutfit,false);
 }
 
-- 
cgit v1.2.3


From 0d6a14a32c2f0896c2965030560db54d8c7f2570 Mon Sep 17 00:00:00 2001
From: Aaron Stone <stone@lindenlab.com>
Date: Tue, 11 Oct 2011 16:18:40 -0700
Subject: EXP-625 Subtle change to get the initial avatar on the screen a
 little faster, then get to the gestures.

---
 indra/newview/llstartup.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index de2afac0b8..a8d58a857b 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -2523,12 +2523,12 @@ void LLStartUp::loadInitialOutfit( const std::string& outfit_folder_name,
 		lldebugs << "initial outfit category id: " << cat_id << llendl;
 	}
 
-	// Copy gestures
-	copyLibraryGestures(same_gender_gestures);
-
 	// This is really misnamed -- it means we have started loading
 	// an outfit/shape that will give the avatar a gender eventually. JC
 	gAgent.setGenderChosen(TRUE);
+
+	// Copy gestures
+	copyLibraryGestures(same_gender_gestures);
 }
 
 //static
-- 
cgit v1.2.3


From cddc9e58dd543b772e14557343e5b2a4ac3c68f6 Mon Sep 17 00:00:00 2001
From: Aaron Stone <stone@lindenlab.com>
Date: Wed, 12 Oct 2011 17:36:03 -0700
Subject: EXP-625 Speed up initial outfit copy and avatar bake by moving
 initial gesture copy to LLAppearangeMgr::onFirstFullyVisible().

---
 indra/newview/llagentwearables.cpp |  7 +---
 indra/newview/llagentwearables.h   |  2 +-
 indra/newview/llappearancemgr.cpp  | 86 ++++++++++++++++++++++++++++++++++++++
 indra/newview/llappearancemgr.h    |  3 ++
 indra/newview/llstartup.cpp        | 80 +++--------------------------------
 indra/newview/llstartup.h          |  2 -
 6 files changed, 98 insertions(+), 82 deletions(-)

diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp
index b9125ec8d3..729eb92e94 100644
--- a/indra/newview/llagentwearables.cpp
+++ b/indra/newview/llagentwearables.cpp
@@ -1168,15 +1168,12 @@ private:
 	std::vector<LLWearable*> mWearablesAwaitingItems;
 };
 
-void LLAgentWearables::createStandardWearables(BOOL female)
+void LLAgentWearables::createStandardWearables()
 {
-	llwarns << "Creating Standard " << (female ? "female" : "male")
-			<< " Wearables" << llendl;
+	llwarns << "Creating standard wearables" << llendl;
 
 	if (!isAgentAvatarValid()) return;
 
-	gAgentAvatarp->setSex(female ? SEX_FEMALE : SEX_MALE);
-
 	const BOOL create[LLWearableType::WT_COUNT] = 
 		{
 			TRUE,  //LLWearableType::WT_SHAPE
diff --git a/indra/newview/llagentwearables.h b/indra/newview/llagentwearables.h
index 252b812c27..01cae3ffd8 100644
--- a/indra/newview/llagentwearables.h
+++ b/indra/newview/llagentwearables.h
@@ -56,7 +56,7 @@ public:
 	LLAgentWearables();
 	virtual ~LLAgentWearables();
 	void 			setAvatarObject(LLVOAvatarSelf *avatar);
-	void			createStandardWearables(BOOL female); 
+	void			createStandardWearables(); 
 	void			cleanup();
 	void			dump();
 
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index 3cb9b77010..0666d22f10 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -2264,6 +2264,85 @@ void LLAppearanceMgr::updateIsDirty()
 	}
 }
 
+// *HACK: Must match name in Library or agent inventory
+const std::string ROOT_GESTURES_FOLDER = "Gestures";
+const std::string COMMON_GESTURES_FOLDER = "Common Gestures";
+const std::string MALE_GESTURES_FOLDER = "Male Gestures";
+const std::string FEMALE_GESTURES_FOLDER = "Female Gestures";
+const std::string SPEECH_GESTURES_FOLDER = "Speech Gestures";
+const std::string OTHER_GESTURES_FOLDER = "Other Gestures";
+
+void LLAppearanceMgr::copyLibraryGestures()
+{
+	llinfos << "Copying library gestures" << llendl;
+
+	// Copy gestures
+	LLUUID lib_gesture_cat_id =
+		gInventory.findCategoryUUIDForType(LLFolderType::FT_GESTURE,false,true);
+	if (lib_gesture_cat_id.isNull())
+	{
+		llwarns << "Unable to copy gestures, source category not found" << llendl;
+	}
+	LLUUID dst_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_GESTURE);
+
+	std::vector<std::string> gesture_folders_to_copy;
+	gesture_folders_to_copy.push_back(MALE_GESTURES_FOLDER);
+	gesture_folders_to_copy.push_back(FEMALE_GESTURES_FOLDER);
+	gesture_folders_to_copy.push_back(COMMON_GESTURES_FOLDER);
+	gesture_folders_to_copy.push_back(SPEECH_GESTURES_FOLDER);
+	gesture_folders_to_copy.push_back(OTHER_GESTURES_FOLDER);
+
+	for(std::vector<std::string>::iterator it = gesture_folders_to_copy.begin();
+		it != gesture_folders_to_copy.end();
+		++it)
+	{
+		std::string& folder_name = *it;
+
+		LLPointer<LLInventoryCallback> cb(NULL);
+
+		// After copying gestures, activate Common, Other, plus
+		// Male and/or Female, depending upon the initial outfit gender.
+		ESex gender = gAgentAvatarp->getSex();
+
+		std::string activate_male_gestures;
+		std::string activate_female_gestures;
+		switch (gender) {
+			case SEX_MALE:
+				activate_male_gestures = MALE_GESTURES_FOLDER;
+				break;
+			case SEX_FEMALE:
+				activate_female_gestures = FEMALE_GESTURES_FOLDER;
+				break;
+			case SEX_BOTH:
+				activate_male_gestures = MALE_GESTURES_FOLDER;
+				activate_female_gestures = FEMALE_GESTURES_FOLDER;
+				break;
+		}
+
+		if (folder_name == activate_male_gestures ||
+			folder_name == activate_female_gestures ||
+			folder_name == COMMON_GESTURES_FOLDER ||
+			folder_name == OTHER_GESTURES_FOLDER)
+		{
+			cb = new ActivateGestureCallback;
+		}
+
+		LLUUID cat_id = findDescendentCategoryIDByName(lib_gesture_cat_id,folder_name);
+		if (cat_id.isNull())
+		{
+			llwarns << "failed to find gesture folder for " << folder_name << llendl;
+		}
+		else
+		{
+			llinfos << "initiating fetch and copy for " << folder_name << " cat_id " << cat_id << llendl;
+			callAfterCategoryFetch(cat_id,
+								   boost::bind(&LLAppearanceMgr::shallowCopyCategory,
+											   &LLAppearanceMgr::instance(),
+											   cat_id, dst_id, cb));
+		}
+	}
+}
+
 void LLAppearanceMgr::autopopulateOutfits()
 {
 	// If this is the very first time the user has logged into viewer2+ (from a legacy viewer, or new account)
@@ -2285,9 +2364,16 @@ void LLAppearanceMgr::autopopulateOutfits()
 void LLAppearanceMgr::onFirstFullyVisible()
 {
 	gAgentAvatarp->debugAvatarVisible();
+
 	// The auto-populate is failing at the point of generating outfits
 	// folders, so don't do the library copy until that is resolved.
 	// autopopulateOutfits();
+
+	// If this is the first time we've ever logged in,
+	// then copy default gestures from the library.
+	if (gAgent.isFirstLogin()) {
+		copyLibraryGestures();
+	}
 }
 
 bool LLAppearanceMgr::updateBaseOutfit()
diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h
index 4b1d95cf25..c1d561781d 100644
--- a/indra/newview/llappearancemgr.h
+++ b/indra/newview/llappearancemgr.h
@@ -151,6 +151,9 @@ public:
 
 	// Create initial outfits from library.
 	void autopopulateOutfits();
+
+	// Copy initial gestures from library.
+	void copyLibraryGestures();
 	
 	void wearBaseOutfit();
 
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index a8d58a857b..1795be91b9 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -2387,13 +2387,6 @@ void asset_callback_nothing(LLVFS*, const LLUUID&, LLAssetType::EType, void*, S3
 	// nothing
 }
 
-// *HACK: Must match name in Library or agent inventory
-const std::string ROOT_GESTURES_FOLDER = "Gestures";
-const std::string COMMON_GESTURES_FOLDER = "Common Gestures";
-const std::string MALE_GESTURES_FOLDER = "Male Gestures";
-const std::string FEMALE_GESTURES_FOLDER = "Female Gestures";
-const std::string SPEECH_GESTURES_FOLDER = "Speech Gestures";
-const std::string OTHER_GESTURES_FOLDER = "Other Gestures";
 const S32 OPT_CLOSED_WINDOW = -1;
 const S32 OPT_MALE = 0;
 const S32 OPT_FEMALE = 1;
@@ -2422,61 +2415,6 @@ bool callback_choose_gender(const LLSD& notification, const LLSD& response)
 	return false;
 }
 
-void LLStartUp::copyLibraryGestures(const std::string& same_gender_gestures)
-{
-	llinfos << "Copying library gestures" << llendl;
-
-	// Copy gestures
-	LLUUID lib_gesture_cat_id =
-		gInventory.findCategoryUUIDForType(LLFolderType::FT_GESTURE,false,true);
-	if (lib_gesture_cat_id.isNull())
-	{
-		llwarns << "Unable to copy gestures, source category not found" << llendl;
-	}
-	LLUUID dst_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_GESTURE);
-
-	std::vector<std::string> gesture_folders_to_copy;
-	gesture_folders_to_copy.push_back(MALE_GESTURES_FOLDER);
-	gesture_folders_to_copy.push_back(FEMALE_GESTURES_FOLDER);
-	gesture_folders_to_copy.push_back(COMMON_GESTURES_FOLDER);
-	gesture_folders_to_copy.push_back(SPEECH_GESTURES_FOLDER);
-	gesture_folders_to_copy.push_back(OTHER_GESTURES_FOLDER);
-
-	for(std::vector<std::string>::iterator it = gesture_folders_to_copy.begin();
-		it != gesture_folders_to_copy.end();
-		++it)
-	{
-		std::string& folder_name = *it;
-
-		LLPointer<LLInventoryCallback> cb(NULL);
-
-		if (folder_name == same_gender_gestures ||
-			folder_name == COMMON_GESTURES_FOLDER ||
-			folder_name == OTHER_GESTURES_FOLDER)
-		{
-			cb = new ActivateGestureCallback;
-		}
-
-
-		LLUUID cat_id = findDescendentCategoryIDByName(lib_gesture_cat_id,folder_name);
-		if (cat_id.isNull())
-		{
-			llwarns << "failed to find gesture folder for " << folder_name << llendl;
-		}
-		else
-		{
-			llinfos << "initiating fetch and copy for " << folder_name << " cat_id " << cat_id << llendl;
-			LLAppearanceMgr* app_mgr = LLAppearanceMgr::getInstance();
-			callAfterCategoryFetch(cat_id,
-								   boost::bind(&LLAppearanceMgr::shallowCopyCategory,
-											   app_mgr,
-											   cat_id,
-											   dst_id,
-											   cb));
-		}
-	}
-}
-
 void LLStartUp::loadInitialOutfit( const std::string& outfit_folder_name,
 								   const std::string& gender_name )
 {
@@ -2487,21 +2425,20 @@ void LLStartUp::loadInitialOutfit( const std::string& outfit_folder_name,
 	// Initiate creation of COF, since we're also bypassing that.
 	gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT);
 	
-	S32 gender = 0;
-	std::string same_gender_gestures;
+	ESex gender;
 	if (gender_name == "male")
 	{
 		lldebugs << "male" << llendl;
-		gender = OPT_MALE;
-		same_gender_gestures = MALE_GESTURES_FOLDER;
+		gender = SEX_MALE;
 	}
 	else
 	{
 		lldebugs << "female" << llendl;
-		gender = OPT_FEMALE;
-		same_gender_gestures = FEMALE_GESTURES_FOLDER;
+		gender = SEX_FEMALE;
 	}
 
+	gAgentAvatarp->setSex(gender);
+
 	// try to find the outfit - if not there, create some default
 	// wearables.
 	LLUUID cat_id = findDescendentCategoryIDByName(
@@ -2510,7 +2447,7 @@ void LLStartUp::loadInitialOutfit( const std::string& outfit_folder_name,
 	if (cat_id.isNull())
 	{
 		lldebugs << "standard wearables" << llendl;
-		gAgentWearables.createStandardWearables(gender);
+		gAgentWearables.createStandardWearables();
 	}
 	else
 	{
@@ -2526,9 +2463,6 @@ void LLStartUp::loadInitialOutfit( const std::string& outfit_folder_name,
 	// This is really misnamed -- it means we have started loading
 	// an outfit/shape that will give the avatar a gender eventually. JC
 	gAgent.setGenderChosen(TRUE);
-
-	// Copy gestures
-	copyLibraryGestures(same_gender_gestures);
 }
 
 //static
@@ -3348,8 +3282,6 @@ bool process_login_success_response()
 	}
 	
 	// Initial outfit for the user.
-	// QUESTION: Why can't we simply simply set the users outfit directly
-	// from a web page into the user info on the server? - Roxie
 	LLSD initial_outfit = response["initial-outfit"][0];
 	if(initial_outfit.size())
 	{
diff --git a/indra/newview/llstartup.h b/indra/newview/llstartup.h
index 99a644eb9c..0a18ef1b2d 100644
--- a/indra/newview/llstartup.h
+++ b/indra/newview/llstartup.h
@@ -90,8 +90,6 @@ public:
 
 	static void initNameCache();
 	
-	static void copyLibraryGestures(const std::string& same_gender_gestures);
-
 	static void cleanupNameCache();
 
 	// outfit_folder_name can be a folder anywhere in your inventory, 
-- 
cgit v1.2.3