diff options
| author | Tofu Linden <tofu.linden@lindenlab.com> | 2010-02-08 16:08:15 +0000 | 
|---|---|---|
| committer | Tofu Linden <tofu.linden@lindenlab.com> | 2010-02-08 16:08:15 +0000 | 
| commit | aa20ba337ec0cb06fa1f36c2aa418e07bc2ae2d1 (patch) | |
| tree | 16ed3722df194b55a042ed3118753f4a97a6586b | |
| parent | a4c32f6322d43029abcf4a477657a1985fd04ae0 (diff) | |
| parent | 5dda2516ad599d3c295930fb3fc0c6cdbe8c2ce5 (diff) | |
merge.
| -rw-r--r-- | indra/newview/llagentwearables.cpp | 4 | ||||
| -rw-r--r-- | indra/newview/llappearancemgr.cpp | 49 | ||||
| -rw-r--r-- | indra/newview/llappearancemgr.h | 108 | ||||
| -rw-r--r-- | indra/newview/llstartup.cpp | 50 | 
4 files changed, 196 insertions, 15 deletions
| diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index 7cbd7e46a9..d560331392 100644 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -1412,7 +1412,7 @@ LLUUID LLAgentWearables::makeNewOutfitLinks(const std::string& new_folder_name)  		new_folder_name);  	LLPointer<LLInventoryCallback> cb = new LLShowCreatedOutfit(folder_id); -	LLAppearanceManager::instance().shallowCopyCategory(LLAppearanceManager::instance().getCOF(),folder_id, cb); +	LLAppearanceManager::instance().shallowCopyCategoryContents(LLAppearanceManager::instance().getCOF(),folder_id, cb);  	LLAppearanceManager::instance().createBaseOutfitLink(folder_id, cb);  	return folder_id; @@ -2329,7 +2329,7 @@ void LLLibraryOutfitsFetch::libraryDone(void)  			LLUUID folder_id = gInventory.createNewCategory(mImportedClothingID,  															LLFolderType::FT_NONE,  															iter->second); -			LLAppearanceManager::getInstance()->shallowCopyCategory(iter->first, folder_id, copy_waiter); +			LLAppearanceManager::getInstance()->shallowCopyCategoryContents(iter->first, folder_id, copy_waiter);  		}  	}  	else diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 326fc41c1e..0cceba6cb0 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -48,6 +48,31 @@  #include "llviewerregion.h"  #include "llwearablelist.h" +LLUUID findDescendentCategoryIDByName(const LLUUID& parent_id,const std::string& name) +{ +	LLInventoryModel::cat_array_t cat_array; +	LLInventoryModel::item_array_t item_array; +	LLNameCategoryCollector has_name(name); +	gInventory.collectDescendentsIf(parent_id, +									cat_array, +									item_array, +									LLInventoryModel::EXCLUDE_TRASH, +									has_name); +	if (0 == cat_array.count()) +		return LLUUID(); +	else +	{ +		LLViewerInventoryCategory *cat = cat_array.get(0); +		if (cat) +			return cat->getUUID(); +		else +		{ +			llwarns << "null cat" << llendl; +			return LLUUID(); +		} +	} +} +  // support for secondlife:///app/appearance SLapps  class LLAppearanceHandler : public LLCommandHandler  { @@ -519,9 +544,33 @@ void LLAppearanceManager::changeOutfit(bool proceed, const LLUUID& category, boo  	LLAppearanceManager::instance().updateCOF(category,append);  } +// Create a copy of src_id + contents as a subfolder of dst_id.  void LLAppearanceManager::shallowCopyCategory(const LLUUID& src_id, const LLUUID& dst_id,  											  LLPointer<LLInventoryCallback> cb)  { +	LLInventoryCategory *src_cat = gInventory.getCategory(src_id); +	if (!src_cat) +	{ +		llwarns << "folder not found for src " << src_id.asString() << llendl; +		return; +	} +	LLUUID parent_id = dst_id; +	if(parent_id.isNull()) +	{ +		parent_id = gInventory.getRootFolderID(); +	} +	LLUUID subfolder_id = gInventory.createNewCategory( parent_id, +														LLFolderType::FT_NONE, +														src_cat->getName()); +	shallowCopyCategoryContents(src_id, subfolder_id, cb); + +	gInventory.notifyObservers(); +} + +// Copy contents of src_id to dst_id. +void LLAppearanceManager::shallowCopyCategoryContents(const LLUUID& src_id, const LLUUID& dst_id, +													  LLPointer<LLInventoryCallback> cb) +{  	LLInventoryModel::cat_array_t cats;  	LLInventoryModel::item_array_t items;  	gInventory.collectDescendents(src_id, cats, items, diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h index 38d1e01d08..8ea52fb4af 100644 --- a/indra/newview/llappearancemgr.h +++ b/indra/newview/llappearancemgr.h @@ -35,6 +35,7 @@  #include "llsingleton.h"  #include "llinventorymodel.h" +#include "llinventoryobserver.h"  #include "llcallbacklist.h"  class LLWearable; @@ -54,10 +55,14 @@ public:  	void wearOutfitByName(const std::string& name);  	void changeOutfit(bool proceed, const LLUUID& category, bool append); -	// Copy all items in a category. +	// Copy all items and the src category itself.  	void shallowCopyCategory(const LLUUID& src_id, const LLUUID& dst_id,  							 LLPointer<LLInventoryCallback> cb); +	// Copy all items in a category. +	void shallowCopyCategoryContents(const LLUUID& src_id, const LLUUID& dst_id, +									 LLPointer<LLInventoryCallback> cb); +  	// Find the Current Outfit folder.  	const LLUUID getCOF() const; @@ -144,6 +149,8 @@ public:  #define SUPPORT_ENSEMBLES 0 +LLUUID findDescendentCategoryIDByName(const LLUUID& parent_id,const std::string& name); +  // Shim class and template function to allow arbitrary boost::bind  // expressions to be run as one-time idle callbacks.  template <typename T> @@ -212,4 +219,103 @@ void doOnIdleRepeating(T callable)  	gIdleCallbacks.addFunction(&OnIdleCallbackRepeating<T>::onIdle,cb_functor);  } +template <class T> +class CallAfterCategoryFetchStage2: public LLInventoryFetchObserver +{ +public: +	CallAfterCategoryFetchStage2(T callable): +		mCallable(callable) +	{ +	} +	~CallAfterCategoryFetchStage2() +	{ +	} +	virtual void done() +	{ +		gInventory.removeObserver(this); +		doOnIdle(mCallable); +		delete this; +	} +protected: +	T mCallable; +}; + +template <class T> +class CallAfterCategoryFetchStage1: public LLInventoryFetchDescendentsObserver +{ +public: +	CallAfterCategoryFetchStage1(T callable): +		mCallable(callable) +	{ +	} +	~CallAfterCategoryFetchStage1() +	{ +	} +	virtual void done() +	{ +		// What we do here is get the complete information on the items in +		// the library, and set up an observer that will wait for that to +		// happen. +		LLInventoryModel::cat_array_t cat_array; +		LLInventoryModel::item_array_t item_array; +		gInventory.collectDescendents(mCompleteFolders.front(), +									  cat_array, +									  item_array, +									  LLInventoryModel::EXCLUDE_TRASH); +		S32 count = item_array.count(); +		if(!count) +		{ +			llwarns << "Nothing fetched in category " << mCompleteFolders.front() +					<< llendl; +			//dec_busy_count(); +			gInventory.removeObserver(this); +			delete this; +			return; +		} + +		CallAfterCategoryFetchStage2<T> *stage2 = new CallAfterCategoryFetchStage2<T>(mCallable); +		LLInventoryFetchObserver::item_ref_t ids; +		for(S32 i = 0; i < count; ++i) +		{ +			ids.push_back(item_array.get(i)->getUUID()); +		} +		 +		gInventory.removeObserver(this); +		 +		// do the fetch +		stage2->fetchItems(ids); +		if(stage2->isEverythingComplete()) +		{ +			// everything is already here - call done. +			stage2->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(stage2); +		} +		delete this; +	} +protected: +	T mCallable; +}; + +template <class T>  +void callAfterCategoryFetch(const LLUUID& cat_id, T callable) +{ +	CallAfterCategoryFetchStage1<T> *stage1 = new CallAfterCategoryFetchStage1<T>(callable); +	LLInventoryFetchDescendentsObserver::folder_ref_t folders; +	folders.push_back(cat_id); +	stage1->fetchDescendents(folders); +	if (stage1->isEverythingComplete()) +	{ +		stage1->done(); +	} +	else +	{ +		gInventory.addObserver(stage1); +	} +} +  #endif diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index e58cdfc6b1..d1b91df6e9 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -2564,27 +2564,53 @@ void LLStartUp::loadInitialOutfit( const std::string& outfit_folder_name,  	// try to find the outfit - if not there, create some default  	// wearables. -	LLInventoryModel::cat_array_t cat_array; -	LLInventoryModel::item_array_t item_array; -	LLNameCategoryCollector has_name(outfit_folder_name); -	gInventory.collectDescendentsIf(gInventory.getLibraryRootFolderID(), -									cat_array, -									item_array, -									LLInventoryModel::EXCLUDE_TRASH, -									has_name); -	if (0 == cat_array.count()) +	LLUUID cat_id = findDescendentCategoryIDByName( +		gInventory.getLibraryRootFolderID(), +		outfit_folder_name); +	if (cat_id.isNull())  	{  		gAgentWearables.createStandardWearables(gender);  	}  	else  	{ -		LLInventoryCategory* cat = cat_array.get(0);  		bool do_copy = true;  		bool do_append = false; +		LLViewerInventoryCategory *cat = gInventory.getCategory(cat_id);  		LLAppearanceManager::instance().wearInventoryCategory(cat, do_copy, do_append);  	} -	LLAppearanceManager::instance().wearOutfitByName(gestures); -	LLAppearanceManager::instance().wearOutfitByName(COMMON_GESTURES_FOLDER); + +	// Copy gestures +	LLUUID dst_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_GESTURE); +	LLPointer<LLInventoryCallback> cb(NULL); +	LLAppearanceManager *app_mgr = &(LLAppearanceManager::instance()); + +	// - Copy gender-specific gestures. +	LLUUID gestures_cat_id = findDescendentCategoryIDByName(  +		gInventory.getLibraryRootFolderID(), +		gestures); +	if (gestures_cat_id.notNull()) +	{ +		callAfterCategoryFetch(gestures_cat_id, +							   boost::bind(&LLAppearanceManager::shallowCopyCategory, +										   app_mgr, +										   gestures_cat_id, +										   dst_id, +										   cb)); +	} + +	// - Copy common gestures. +	LLUUID common_gestures_cat_id = findDescendentCategoryIDByName(  +		gInventory.getLibraryRootFolderID(), +		COMMON_GESTURES_FOLDER); +	if (common_gestures_cat_id.notNull()) +	{ +		callAfterCategoryFetch(common_gestures_cat_id, +							   boost::bind(&LLAppearanceManager::shallowCopyCategory, +										   app_mgr, +										   common_gestures_cat_id, +										   dst_id, +										   cb)); +	}  	// This is really misnamed -- it means we have started loading  	// an outfit/shape that will give the avatar a gender eventually. JC | 
