diff options
| author | Loren Shih <seraph@lindenlab.com> | 2010-01-04 13:44:48 -0500 | 
|---|---|---|
| committer | Loren Shih <seraph@lindenlab.com> | 2010-01-04 13:44:48 -0500 | 
| commit | 6703cbc8af55cb70410d99ae38aa739bff2e692a (patch) | |
| tree | b91de32249ddc2a738f8bd9df3f6a57c2da1aa15 | |
| parent | 3726d3bda8d359216a683c93c155c1463da7348e (diff) | |
EXT-3827 : Some accounts have no library outfits
EXT-3616 : My Outfits folders don't always auto-populate on first login
EXT-3796 : Sidepanel not picking up changes to "My Outfits" from autopopulation
EXT-3915 : Memory leak in autopopulation code
Largely rewrote the autopopulation code because it was buggy, was causing llwarns messages, and had a memory leak.  My approach to this should fix everything.
| -rw-r--r-- | indra/newview/llagentwearables.cpp | 86 | 
1 files changed, 34 insertions, 52 deletions
| diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index b221c28dcd..dc1598aacd 100644 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -100,6 +100,7 @@ public:  	LLLibraryOutfitsFetch() : mCurrFetchStep(LOFS_FOLDER), mOutfitsPopulated(false) {}  	~LLLibraryOutfitsFetch() {}  	virtual void done();	 +	void doneIdle();  protected:  	void folderDone(void);  	void outfitsDone(void); @@ -2084,52 +2085,50 @@ void LLAgentWearables::populateMyOutfitsFolder(void)  {	  	LLLibraryOutfitsFetch* outfits = new LLLibraryOutfitsFetch(); -	// What we do here is get the complete information on the items in -	// the inventory, and set up an observer that will wait for that to -	// happen. +	// Get the complete information on the items in the inventory and  +	// setup an observer that will wait for that to happen.  	LLInventoryFetchDescendentsObserver::folder_ref_t folders;  	const LLUUID my_outfits_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS);  	folders.push_back(my_outfits_id); +	gInventory.addObserver(outfits);  	outfits->fetchDescendents(folders); -	if(outfits->isEverythingComplete()) -	{ -		// everything is already here - call done. -		outfits->done(); -	} -	else -	{ -		// it's all on it's way - add an observer, and the inventory -		// will call done for us when everything is here. -		gInventory.addObserver(outfits); -	}  }  void LLLibraryOutfitsFetch::done()  { -	switch (mCurrFetchStep){ +	// Delay this until idle() routine, since it's a heavy operation and +	// we also can't have it run within notifyObservers. +	doOnIdle(boost::bind(&LLLibraryOutfitsFetch::doneIdle,this)); +	gInventory.removeObserver(this); // Prevent doOnIdle from being added twice. +} + +void LLLibraryOutfitsFetch::doneIdle() +{ +	gInventory.addObserver(this); // Add this back in since it was taken out during ::done() +	switch (mCurrFetchStep) +	{  		case LOFS_FOLDER: -			mCurrFetchStep = LOFS_OUTFITS;  			folderDone();  			break;  		case LOFS_OUTFITS: -			mCurrFetchStep = LOFS_CONTENTS;  			outfitsDone();  			break;  		case LOFS_CONTENTS: -			// No longer need this observer hanging around. -			gInventory.removeObserver(this);  			contentsDone();  			break;  		default: -			gInventory.removeObserver(this); -			delete this; -			return; +			llwarns << "Got invalid state for outfit fetch: " << mCurrFetchStep << llendl; +			mOutfitsPopulated = TRUE; +			break;  	} + +	// We're completely done.  Cleanup.  	if (mOutfitsPopulated)  	{ -		gInventory.notifyObservers(); +		gInventory.removeObserver(this);  		delete this; +		return;  	}  } @@ -2143,7 +2142,6 @@ void LLLibraryOutfitsFetch::folderDone(void)  	if (cat_array.count() > 0 || wearable_array.count() > 0)  	{  		mOutfitsPopulated = true; -		gInventory.removeObserver(this);  		return;  	} @@ -2152,22 +2150,11 @@ void LLLibraryOutfitsFetch::folderDone(void)  	mCompleteFolders.clear(); -	// What we do here is get the complete information on the items in -	// the inventory, and set up an observer that will wait for that to -	// happen. +	// Get the complete information on the items in the inventory.  	LLInventoryFetchDescendentsObserver::folder_ref_t folders;  	folders.push_back(library_clothing_id); +	mCurrFetchStep = LOFS_OUTFITS;  	fetchDescendents(folders); -	if(isEverythingComplete()) -	{ -		// everything is already here - call done. -		outfitsDone(); -	} -	else  -	{ -		gInventory.removeObserver(this); -		gInventory.addObserver(this); -	}  }  void LLLibraryOutfitsFetch::outfitsDone(void) @@ -2180,25 +2167,21 @@ void LLLibraryOutfitsFetch::outfitsDone(void)  	LLInventoryFetchDescendentsObserver::folder_ref_t folders;  	llassert(cat_array.count() > 0); -	for(S32 i = 0; i < cat_array.count(); ++i) +	for (LLInventoryModel::cat_array_t::const_iterator iter = cat_array.begin(); +		 iter != cat_array.end(); +		 ++iter)  	{ -		if (cat_array.get(i)->getName() != "More Outfits" && cat_array.get(i)->getName() != "Ruth"){ -			folders.push_back(cat_array.get(i)->getUUID()); -			mOutfits.push_back( std::make_pair(cat_array.get(i)->getUUID(), cat_array.get(i)->getName() )); +		const LLViewerInventoryCategory *cat = iter->get(); +		if (cat->getName() != "More Outfits" && cat->getName() != "Ruth") +		{ +			folders.push_back(cat->getUUID()); +			mOutfits.push_back(std::make_pair(cat->getUUID(), cat->getName()));  		}  	}  	mCompleteFolders.clear(); + +	mCurrFetchStep = LOFS_CONTENTS;  	fetchDescendents(folders); -	if(isEverythingComplete()) -	{ -		// everything is already here - call done. -		contentsDone(); -	} -	else -	{ -		gInventory.removeObserver(this); -		gInventory.addObserver(this); -	}  }  void LLLibraryOutfitsFetch::contentsDone(void) @@ -2210,7 +2193,6 @@ void LLLibraryOutfitsFetch::contentsDone(void)  		LLUUID folder_id = gInventory.createNewCategory(parent_id,  														LLFolderType::FT_OUTFIT,  														mOutfits[i].second); -		  		LLAppearanceManager::getInstance()->shallowCopyCategory(mOutfits[i].first, folder_id, NULL);  	}  	mOutfitsPopulated = true; | 
