diff options
| -rwxr-xr-x | indra/llcommon/llsdutil.cpp | 2 | ||||
| -rwxr-xr-x | indra/llinventory/llinventory.cpp | 6 | ||||
| -rwxr-xr-x | indra/newview/llappearancemgr.cpp | 90 | ||||
| -rwxr-xr-x | indra/newview/llappearancemgr.h | 4 | ||||
| -rwxr-xr-x | indra/newview/llinventorymodel.cpp | 172 | ||||
| -rwxr-xr-x | indra/newview/llinventorymodel.h | 2 | ||||
| -rwxr-xr-x | indra/newview/llviewerinventory.cpp | 78 | ||||
| -rwxr-xr-x | indra/newview/llviewerinventory.h | 7 | ||||
| -rwxr-xr-x | indra/newview/llviewerregion.cpp | 2 | ||||
| -rwxr-xr-x | indra/newview/llviewerstats.cpp | 40 | ||||
| -rwxr-xr-x | indra/newview/llviewerstats.h | 5 | ||||
| -rwxr-xr-x | indra/newview/llvoavatar.cpp | 27 | ||||
| -rwxr-xr-x | indra/newview/llvoavatar.h | 1 | ||||
| -rwxr-xr-x | indra/newview/llvoavatarself.cpp | 12 | 
14 files changed, 348 insertions, 100 deletions
| diff --git a/indra/llcommon/llsdutil.cpp b/indra/llcommon/llsdutil.cpp index 803417d368..562fd26658 100755 --- a/indra/llcommon/llsdutil.cpp +++ b/indra/llcommon/llsdutil.cpp @@ -182,7 +182,7 @@ char* ll_pretty_print_sd_ptr(const LLSD* sd)  char* ll_pretty_print_sd(const LLSD& sd)  { -	const U32 bufferSize = 10 * 1024; +	const U32 bufferSize = 100 * 1024;  	static char buffer[bufferSize];  	std::ostringstream stream;  	//stream.rdbuf()->pubsetbuf(buffer, bufferSize); diff --git a/indra/llinventory/llinventory.cpp b/indra/llinventory/llinventory.cpp index a529aa3af3..77b837f8ac 100755 --- a/indra/llinventory/llinventory.cpp +++ b/indra/llinventory/llinventory.cpp @@ -50,6 +50,7 @@ static const std::string INV_DESC_LABEL("desc");  static const std::string INV_PERMISSIONS_LABEL("permissions");  static const std::string INV_SHADOW_ID_LABEL("shadow_id");  static const std::string INV_ASSET_ID_LABEL("asset_id"); +static const std::string INV_LINKED_ID_LABEL("linked_id");  static const std::string INV_SALE_INFO_LABEL("sale_info");  static const std::string INV_FLAGS_LABEL("flags");  static const std::string INV_CREATION_DATE_LABEL("created_at"); @@ -1109,6 +1110,11 @@ bool LLInventoryItem::fromLLSD(const LLSD& sd)  	{  		mAssetUUID = sd[w];  	} +	w = INV_LINKED_ID_LABEL; +	if (sd.has(w)) +	{ +		mAssetUUID = sd[w]; +	}  	w = INV_ASSET_TYPE_LABEL;  	if (sd.has(w))  	{ diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index d817f10aee..722587ec0e 100755 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -397,6 +397,12 @@ public:  		LLCallAfterInventoryBatchMgr(dst_cat_id, phase_name, on_completion_func, on_failure_func, retry_after, max_retries)  	{  		addItems(src_items); +		sInstanceCount++; +	} + +	~LLCallAfterInventoryCopyMgr() +	{ +		sInstanceCount--;  	}  	virtual bool requestOperation(const LLUUID& item_id) @@ -419,8 +425,15 @@ public:  			);  		return true;  	} + +	static S32 getInstanceCount() { return sInstanceCount; } +	 +private: +	static S32 sInstanceCount;  }; +S32 LLCallAfterInventoryCopyMgr::sInstanceCount = 0; +  LLUpdateAppearanceOnDestroy::LLUpdateAppearanceOnDestroy(bool update_base_outfit_ordering,  														 bool enforce_item_restrictions,  														 bool enforce_ordering): @@ -1609,25 +1622,6 @@ void LLAppearanceMgr::purgeBaseOutfitLink(const LLUUID& category, LLPointer<LLIn  	}  } -void LLAppearanceMgr::removeCategoryContents(const LLUUID& category, bool keep_outfit_links, -											 LLPointer<LLInventoryCallback> cb) -{ -	LLInventoryModel::cat_array_t cats; -	LLInventoryModel::item_array_t items; -	gInventory.collectDescendents(category, cats, items, -								  LLInventoryModel::EXCLUDE_TRASH); -	for (S32 i = 0; i < items.count(); ++i) -	{ -		LLViewerInventoryItem *item = items.get(i); -		if (keep_outfit_links && (item->getActualType() == LLAssetType::AT_LINK_FOLDER)) -			continue; -		if (item->getIsLinkType()) -		{ -			remove_inventory_item(item->getUUID(), cb); -		} -	} -} -  // Keep the last N wearables of each type.  For viewer 2.0, N is 1 for  // both body parts and clothing items.  void LLAppearanceMgr::filterWearableItems( @@ -1691,6 +1685,11 @@ void LLAppearanceMgr::removeAll(LLInventoryModel::item_array_t& items_to_kill,  void LLAppearanceMgr::updateCOF(const LLUUID& category, bool append)  {  	LLViewerInventoryCategory *pcat = gInventory.getCategory(category); +	if (!pcat) +	{ +		llwarns << "no category found for id " << category << llendl; +		return; +	}  	LL_INFOS("Avatar") << self_av_string() << "starting, cat '" << (pcat ? pcat->getName() : "[UNKNOWN]") << "'" << LL_ENDL;  	const LLUUID cof = getCOF(); @@ -1756,6 +1755,7 @@ void LLAppearanceMgr::updateCOF(const LLUUID& category, bool append)  	// Will link all the above items.  	LLPointer<LLInventoryCallback> link_waiter = new LLUpdateAppearanceOnDestroy; +#if 0  	linkAll(cof,all_items,link_waiter);  	// Add link to outfit if category is an outfit.  @@ -1772,7 +1772,37 @@ void LLAppearanceMgr::updateCOF(const LLUUID& category, bool append)  	// even in the non-append case, createBaseOutfitLink() already  	// deletes the existing link, don't need to do it again here.  	bool keep_outfit_links = true; -	removeCategoryContents(cof, keep_outfit_links, link_waiter); +	remove_folder_contents(cof, keep_outfit_links, link_waiter); +#else +	LLSD contents = LLSD::emptyArray(); +	for (LLInventoryModel::item_array_t::const_iterator it = all_items.begin(); +		 it != all_items.end(); ++it) +	{ +		LLSD item_contents; +		LLInventoryItem *item = *it; +		item_contents["name"] = item->getName(); +		item_contents["desc"] = item->getActualDescription(); +		item_contents["linked_id"] = item->getLinkedUUID(); +		item_contents["type"] = LLAssetType::AT_LINK;  +		contents.append(item_contents); +	} +	const LLUUID& base_id = append ? getBaseOutfitUUID() : category; +	LLViewerInventoryCategory *base_cat = gInventory.getCategory(base_id); +	if (base_cat) +	{ +		LLSD base_contents; +		base_contents["name"] = base_cat->getName(); +		base_contents["desc"] = ""; +		base_contents["linked_id"] = base_cat->getLinkedUUID(); +		base_contents["type"] = LLAssetType::AT_LINK_FOLDER;  +		contents.append(base_contents); +	} +	if (gSavedSettings.getBOOL("DebugAvatarAppearanceMessage")) +	{ +		dump_sequential_xml(gAgentAvatarp->getFullname() + "_slam_request", contents); +	} +	slam_inventory_folder(getCOF(), contents, link_waiter); +#endif  	LL_DEBUGS("Avatar") << self_av_string() << "waiting for LLUpdateAppearanceOnDestroy" << LL_ENDL;  } @@ -2154,6 +2184,11 @@ void LLAppearanceMgr::wearInventoryCategory(LLInventoryCategory* category, bool  														   category->getUUID(), copy, append));  } +S32 LLAppearanceMgr::getActiveCopyOperations() const +{ +	return LLCallAfterInventoryCopyMgr::getInstanceCount();  +} +  void LLAppearanceMgr::wearCategoryFinal(LLUUID& cat_id, bool copy_items, bool append)  {  	LL_INFOS("Avatar") << self_av_string() << "starting" << LL_ENDL; @@ -2758,7 +2793,7 @@ bool LLAppearanceMgr::updateBaseOutfit()  	updateClothingOrderingInfo();  	// in a Base Outfit we do not remove items, only links -	removeCategoryContents(base_outfit_id, false, NULL); +	remove_folder_contents(base_outfit_id, false, NULL);  	LLPointer<LLInventoryCallback> dirty_state_updater =  		new LLBoostFuncInventoryCallback(no_op_inventory_func, appearance_mgr_update_dirty_state); @@ -2918,7 +2953,7 @@ protected:  			//LL_DEBUGS("Avatar") << dumpResponse() << LL_ENDL;  			if (gSavedSettings.getBOOL("DebugAvatarAppearanceMessage"))  			{ -				dumpContents(gAgentAvatarp->getFullname() + "_appearance_request_ok", content); +				dump_sequential_xml(gAgentAvatarp->getFullname() + "_appearance_request_ok", content);  			}  		}  		else @@ -2936,7 +2971,7 @@ protected:  		if (gSavedSettings.getBOOL("DebugAvatarAppearanceMessage"))  		{  			const LLSD& content = getContent(); -			dumpContents(gAgentAvatarp->getFullname() + "_appearance_request_error", content); +			dump_sequential_xml(gAgentAvatarp->getFullname() + "_appearance_request_error", content);  			debugCOF(content);  		}  		onFailure(); @@ -2960,15 +2995,6 @@ protected:  		}  	}	 -	void dumpContents(const std::string outprefix, const LLSD& content) -	{ -		std::string outfilename = get_sequential_numbered_file_name(outprefix,".xml"); -		std::string fullpath = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,outfilename); -		std::ofstream ofs(fullpath.c_str(), std::ios_base::out); -		ofs << LLSDOStreamer<LLSDXMLFormatter>(content, LLSDFormatter::OPTIONS_PRETTY); -		LL_DEBUGS("Avatar") << "results saved to: " << fullpath << LL_ENDL; -	} -  	void debugCOF(const LLSD& content)  	{  		LL_INFOS("Avatar") << "AIS COF, version received: " << content["expected"].asInteger() diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h index b63e883426..9eb26767c4 100755 --- a/indra/newview/llappearancemgr.h +++ b/indra/newview/llappearancemgr.h @@ -71,6 +71,8 @@ public:  									  LLInventoryModel::item_array_t& items_to_kill);  	void enforceCOFItemRestrictions(LLPointer<LLInventoryCallback> cb); +	S32 getActiveCopyOperations() const; +	  	// Copy all items and the src category itself.  	void shallowCopyCategory(const LLUUID& src_id, const LLUUID& dst_id,  							 LLPointer<LLInventoryCallback> cb); @@ -235,8 +237,6 @@ private:  								   LLInventoryModel::item_array_t& obj_items,  								   LLInventoryModel::item_array_t& gest_items); -	void removeCategoryContents(const LLUUID& category, bool keep_outfit_links, -								LLPointer<LLInventoryCallback> cb);  	static void onOutfitRename(const LLSD& notification, const LLSD& response);  	void setOutfitLocked(bool locked); diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index 38fa3c36e3..c0c48d6695 100755 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -1170,79 +1170,193 @@ void parse_llsd_uuid_array(const LLSD& content, const std::string& name, uuid_ve  void LLInventoryModel::onAISUpdateReceived(const std::string& context, const LLSD& update)  { -	LL_DEBUGS("Inventory") << "ais update " << context << ":" << ll_pretty_print_sd(update) << llendl; +	if (gSavedSettings.getBOOL("DebugAvatarAppearanceMessage")) +	{ +		dump_sequential_xml(gAgentAvatarp->getFullname() + "_ais_update", update); +	} +	// Track changes to descendent counts for accounting. +	std::map<LLUUID,S32> cat_deltas; +	typedef std::map<LLUUID,LLPointer<LLViewerInventoryItem> > deferred_item_map_t; +	deferred_item_map_t items_created; +	deferred_item_map_t items_updated; +	std::set<LLUUID> objects_deleted; + +	// parse _categories_removed -> objects_deleted  	uuid_vec_t cat_ids;  	parse_llsd_uuid_array(update,"_categories_removed",cat_ids);  	for (uuid_vec_t::const_iterator it = cat_ids.begin();  		 it != cat_ids.end(); ++it)  	{ -		onObjectDeletedFromServer(*it, false); +		LLViewerInventoryCategory *cat = getCategory(*it); +		cat_deltas[cat->getParentUUID()]--; +		objects_deleted.insert(*it);  	} +	// parse _categories_items_removed -> objects_deleted  	uuid_vec_t item_ids;  	parse_llsd_uuid_array(update,"_category_items_removed",item_ids);  	for (uuid_vec_t::const_iterator it = item_ids.begin();  		 it != item_ids.end(); ++it)  	{ -		onObjectDeletedFromServer(*it, false); +		LLViewerInventoryItem *item = getItem(*it); +		cat_deltas[item->getParentUUID()]--; +		objects_deleted.insert(*it);  	} +	// parse _broken_links_removed -> objects_deleted  	uuid_vec_t broken_link_ids;  	parse_llsd_uuid_array(update,"_broken_links_removed",broken_link_ids);  	for (uuid_vec_t::const_iterator it = broken_link_ids.begin();  		 it != broken_link_ids.end(); ++it)  	{ -		onObjectDeletedFromServer(*it, false); +		LLViewerInventoryItem *item = getItem(*it); +		cat_deltas[item->getParentUUID()]--; +		objects_deleted.insert(*it);  	} -	if (update.has("item_id")) +	// parse _created_items +	uuid_vec_t created_item_ids; +	parse_llsd_uuid_array(update,"_created_items",created_item_ids); + +	if (update.has("_embedded"))  	{ -		// item has been modified or possibly created (would be better if we could distinguish these cases directly) -		LLUUID item_id = update["item_id"].asUUID(); -		LLViewerInventoryItem *item = gInventory.getItem(item_id); -		LLViewerInventoryCategory *cat = gInventory.getCategory(item_id); -		if (item) +		const LLSD& embedded = update["_embedded"]; +		for(LLSD::map_const_iterator it = embedded.beginMap(), +				end = embedded.endMap(); +				it != end; ++it)  		{ -			LLSD changes; -			if (update.has("name") && update["name"] != item->getName()) +			const std::string& field = (*it).first; + +			// parse created links +			if (field == "link")  			{ -				changes["name"] = update["name"]; -			} -			if (update.has("desc") && update["desc"] != item->getActualDescription()) +				const LLSD& links = embedded["link"]; +				for(LLSD::map_const_iterator linkit = links.beginMap(), +						linkend = links.endMap(); +					linkit != linkend; ++linkit) +				{ +					const LLUUID link_id((*linkit).first); +					const LLSD& link_map = (*linkit).second; +					uuid_vec_t::const_iterator pos = +						std::find(created_item_ids.begin(), +								  created_item_ids.end(),link_id); +					if (pos != created_item_ids.end()) +					{ +						LLPointer<LLViewerInventoryItem> new_link(new LLViewerInventoryItem); +						BOOL rv = new_link->unpackMessage(link_map); +						if (rv) +						{ +							items_created[link_id] = new_link; +							const LLUUID& parent_id = new_link->getParentUUID(); +							cat_deltas[parent_id]++; +						} +						else +						{ +							llwarns << "failed to unpack" << llendl; +						} +					} +					else +					{ +						LL_DEBUGS("Inventory") << "Ignoring link not in created items list " << link_id << llendl; +					} +				} +		} +			else  			{ -				changes["desc"] = update["desc"]; +				llwarns << "unrecognized embedded field " << field << llendl;  			} -			onItemUpdated(item_id,changes,true);  		} -		else if (cat) +		 +	} + +	// Parse item update at the top level. +	if (update.has("item_id")) +	{ +		LLUUID item_id = update["item_id"].asUUID(); +		LLPointer<LLViewerInventoryItem> new_item(new LLViewerInventoryItem); +		BOOL rv = new_item->unpackMessage(update); +		if (rv)  		{ -			llerrs << "don't handle cat update yet" << llendl; +			items_updated[item_id] = new_item; +			// This statement is here to cause a new entry with 0 +			// delta to be created if it does not already exist; +			// otherwise has no effect. +			cat_deltas[new_item->getParentUUID()];  		}  		else  		{ -			llerrs << "don't handle creation case yet" << llendl; +			llerrs << "unpack failed" << llendl;  		} -	  	} +	// Do descendent/version accounting. +	// Can remove this if/when we use the version info directly. +	for (std::map<LLUUID,S32>::const_iterator catit = cat_deltas.begin(); +		 catit != cat_deltas.end(); ++catit) +	{ +		const LLUUID cat_id(catit->first); +		S32 delta = catit->second; +		LLInventoryModel::LLCategoryUpdate up(cat_id, delta); +		gInventory.accountForUpdate(up); +	} +	  	// TODO - how can we use this version info? Need to be sure all  	// changes are going through AIS first, or at least through  	// something with a reliable responder. -#if 0  	const std::string& ucv = "_updated_category_versions";  	if (update.has(ucv))  	{  		for(LLSD::map_const_iterator it = update[ucv].beginMap(),  				end = update[ucv].endMap(); -				it != end; ++it) +			it != end; ++it)  		{  			const LLUUID id((*it).first);  			S32 version = (*it).second.asInteger(); +			LLViewerInventoryCategory *cat = gInventory.getCategory(id); +			if (cat->getVersion() != version) +			{ +				llwarns << "Possible version mismatch, viewer " << cat->getVersion() +						<< " server " << version << llendl; +			}  		}  	} -#endif + +	// CREATE ITEMS +	for (deferred_item_map_t::const_iterator create_it = items_created.begin(); +		 create_it != items_created.end(); ++create_it) +	{ +		LLUUID item_id(create_it->first); +		LLPointer<LLViewerInventoryItem> new_item = create_it->second; + +		// FIXME risky function since it calls updateServer() in some +		// cases.  Maybe break out the update/create cases, in which +		// case this is create. +		LL_DEBUGS("Inventory") << "created item " << item_id << llendl; +		gInventory.updateItem(new_item); +	} +	// UPDATE ITEMS +	for (deferred_item_map_t::const_iterator update_it = items_updated.begin(); +		 update_it != items_updated.end(); ++update_it) +	{ +		LLUUID item_id(update_it->first); +		LLPointer<LLViewerInventoryItem> new_item = update_it->second; +		// FIXME risky function since it calls updateServer() in some +		// cases.  Maybe break out the update/create cases, in which +		// case this is update. +		LL_DEBUGS("Inventory") << "updated item " << item_id << llendl; +		gInventory.updateItem(new_item); +	} + +	// DELETE OBJECTS +	for (std::set<LLUUID>::const_iterator del_it = objects_deleted.begin(); +		 del_it != objects_deleted.end(); ++del_it) +	{ +		LL_DEBUGS("Inventory") << "deleted item " << *del_it << llendl; +		onObjectDeletedFromServer(*del_it, false, false); +	} +  }  void LLInventoryModel::onItemUpdated(const LLUUID& item_id, const LLSD& updates, bool update_parent_version) @@ -1395,7 +1509,7 @@ void LLInventoryModel::onDescendentsPurgedFromServer(const LLUUID& object_id, bo  // Update model after an item is confirmed as removed from  // server. Works for categories or items. -void LLInventoryModel::onObjectDeletedFromServer(const LLUUID& object_id, bool fix_broken_links) +void LLInventoryModel::onObjectDeletedFromServer(const LLUUID& object_id, bool fix_broken_links, bool update_parent_version)  {  	LLPointer<LLInventoryObject> obj = getObject(object_id);  	if(obj) @@ -1406,9 +1520,13 @@ void LLInventoryModel::onObjectDeletedFromServer(const LLUUID& object_id, bool f  			onDescendentsPurgedFromServer(object_id, fix_broken_links);  		} +  		// From item/cat removeFromServer() -		LLInventoryModel::LLCategoryUpdate up(obj->getParentUUID(), -1); -		accountForUpdate(up); +		if (update_parent_version) +		{ +			LLInventoryModel::LLCategoryUpdate up(obj->getParentUUID(), -1); +			accountForUpdate(up); +		}  		// From purgeObject()  		LLPreview::hide(object_id); diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h index fd2481b531..a41a824906 100755 --- a/indra/newview/llinventorymodel.h +++ b/indra/newview/llinventorymodel.h @@ -334,7 +334,7 @@ public:  	// Update model after an item is confirmed as removed from  	// server. Works for categories or items. -	void onObjectDeletedFromServer(const LLUUID& item_id, bool fix_broken_links = true); +	void onObjectDeletedFromServer(const LLUUID& item_id, bool fix_broken_links = true, bool update_parent_version = true);  	// Update model after all descendents removed from server.  	void onDescendentsPurgedFromServer(const LLUUID& object_id, bool fix_broken_links = true); diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index 465a49d004..0608c46051 100755 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -493,6 +493,34 @@ private:  	LLSD mUpdates;  }; +class SlamFolderCommand: public AISCommand +{ +public: +	SlamFolderCommand(const LLUUID& folder_id, const LLSD& contents, LLPointer<LLInventoryCallback> callback): +		mContents(contents), +		AISCommand(callback) +	{ +		std::string cap; +		if (!getCap(cap)) +		{ +			llwarns << "No cap found" << llendl; +			return; +		} +		LLUUID tid; +		tid.generate(); +		std::string url = cap + std::string("/category/") + folder_id.asString() + "/links?tid=" + tid.asString(); +		llinfos << url << llendl; +		LLCurl::ResponderPtr responder = this; +		LLSD headers; +		headers["Content-Type"] = "application/llsd+xml"; +		F32 timeout = HTTP_REQUEST_EXPIRY_SECS; +		command_func_type cmd = boost::bind(&LLHTTPClient::put, url, mContents, responder, headers, timeout); +		setCommandFunc(cmd); +	} +private: +	LLSD mContents; +}; +  ///----------------------------------------------------------------------------  /// Class LLViewerInventoryItem  ///---------------------------------------------------------------------------- @@ -1828,6 +1856,54 @@ void create_new_item(const std::string& name,  }	 +void slam_inventory_folder(const LLUUID& folder_id, +						   const LLSD& contents, +						   LLPointer<LLInventoryCallback> cb) +{ +	std::string cap; +	if (AISCommand::getCap(cap)) +	{ +		LLPointer<AISCommand> cmd_ptr = new SlamFolderCommand(folder_id, contents, cb); +		cmd_ptr->run_command(); +	} +	else // no cap +	{ +		for (LLSD::array_const_iterator it = contents.beginArray(); +			 it != contents.endArray(); +			 ++it) +		{ +			const LLSD& item_contents = *it; +			link_inventory_item(gAgent.getID(), +								item_contents["linked_id"].asUUID(), +								folder_id, +								item_contents["name"].asString(), +								item_contents["desc"].asString(), +								LLAssetType::EType(item_contents["type"].asInteger()), +								cb); +		} +		remove_folder_contents(folder_id,false,cb); +	} +} + +void remove_folder_contents(const LLUUID& category, bool keep_outfit_links, +							LLPointer<LLInventoryCallback> cb) +{ +	LLInventoryModel::cat_array_t cats; +	LLInventoryModel::item_array_t items; +	gInventory.collectDescendents(category, cats, items, +								  LLInventoryModel::EXCLUDE_TRASH); +	for (S32 i = 0; i < items.count(); ++i) +	{ +		LLViewerInventoryItem *item = items.get(i); +		if (keep_outfit_links && (item->getActualType() == LLAssetType::AT_LINK_FOLDER)) +			continue; +		if (item->getIsLinkType()) +		{ +			remove_inventory_item(item->getUUID(), cb); +		} +	} +} +  const std::string NEW_LSL_NAME = "New Script"; // *TODO:Translate? (probably not)  const std::string NEW_NOTECARD_NAME = "New Note"; // *TODO:Translate? (probably not)  const std::string NEW_GESTURE_NAME = "New Gesture"; // *TODO:Translate? (probably not) @@ -2263,3 +2339,5 @@ BOOL LLViewerInventoryItem::regenerateLink()  	gInventory.notifyObservers();  	return TRUE;  } + + diff --git a/indra/newview/llviewerinventory.h b/indra/newview/llviewerinventory.h index c52b0c2d9d..9af71dfc9c 100755 --- a/indra/newview/llviewerinventory.h +++ b/indra/newview/llviewerinventory.h @@ -407,4 +407,11 @@ void menu_create_inventory_item(LLInventoryPanel* root,  								const LLSD& userdata,  								const LLUUID& default_parent_uuid = LLUUID::null); +void slam_inventory_folder(const LLUUID& folder_id, +						   const LLSD& contents, +						   LLPointer<LLInventoryCallback> cb); + +void remove_folder_contents(const LLUUID& folder_id, bool keep_outfit_links, +							  LLPointer<LLInventoryCallback> cb); +  #endif // LL_LLVIEWERINVENTORY_H diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index e77b29aca4..b635087d66 100755 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -1877,7 +1877,7 @@ std::string LLViewerRegion::getCapability(const std::string& name) const  {  	if (!capabilitiesReceived() && (name!=std::string("Seed")) && (name!=std::string("ObjectMedia")))  	{ -		llwarns << "getCapability called before caps received" << llendl; +		llwarns << "getCapability called before caps received for " << name << llendl;  	}  	CapabilityMap::const_iterator iter = mImpl->mCapabilities.find(name); diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp index b73411080a..68633fba6e 100755 --- a/indra/newview/llviewerstats.cpp +++ b/indra/newview/llviewerstats.cpp @@ -734,44 +734,28 @@ void send_stats()  	LLHTTPClient::post(url, body, new ViewerStatsResponder());  } -LLFrameTimer& LLViewerStats::PhaseMap::getPhaseTimer(const std::string& phase_name) +LLTimer& LLViewerStats::PhaseMap::getPhaseTimer(const std::string& phase_name)  {  	phase_map_t::iterator iter = mPhaseMap.find(phase_name);  	if (iter == mPhaseMap.end())  	{ -		LLFrameTimer timer; +		LLTimer timer;  		mPhaseMap[phase_name] = timer;  	} -	LLFrameTimer& timer = mPhaseMap[phase_name]; +	LLTimer& timer = mPhaseMap[phase_name];  	return timer;  }  void LLViewerStats::PhaseMap::startPhase(const std::string& phase_name)  { -	LLFrameTimer& timer = getPhaseTimer(phase_name); -	lldebugs << "startPhase " << phase_name << llendl; -	timer.unpause(); -} - -void LLViewerStats::PhaseMap::stopAllPhases() -{ -	for (phase_map_t::iterator iter = mPhaseMap.begin(); -		 iter != mPhaseMap.end(); ++iter) -	{ -		const std::string& phase_name = iter->first; -		if (iter->second.getStarted()) -		{ -			// Going from started to paused state - record stats. -			recordPhaseStat(phase_name,iter->second.getElapsedTimeF32()); -		} -		lldebugs << "stopPhase (all) " << phase_name << llendl; -		iter->second.pause(); -	} +	LLTimer& timer = getPhaseTimer(phase_name); +	timer.start(); +	LL_DEBUGS("Avatar") << "startPhase " << phase_name << llendl;  }  void LLViewerStats::PhaseMap::clearPhases()  { -	lldebugs << "clearPhases" << llendl; +	LL_DEBUGS("Avatar") << "clearPhases" << llendl;  	mPhaseMap.clear();  } @@ -796,7 +780,6 @@ LLViewerStats::PhaseMap::PhaseMap()  {  } -  void LLViewerStats::PhaseMap::stopPhase(const std::string& phase_name)  {  	phase_map_t::iterator iter = mPhaseMap.find(phase_name); @@ -809,6 +792,7 @@ void LLViewerStats::PhaseMap::stopPhase(const std::string& phase_name)  		}  	}  } +  // static  LLViewerStats::StatsAccumulator& LLViewerStats::PhaseMap::getPhaseStats(const std::string& phase_name)  { @@ -832,14 +816,18 @@ void LLViewerStats::PhaseMap::recordPhaseStat(const std::string& phase_name, F32  bool LLViewerStats::PhaseMap::getPhaseValues(const std::string& phase_name, F32& elapsed, bool& completed)  {  	phase_map_t::iterator iter = mPhaseMap.find(phase_name); +	bool found = false;  	if (iter != mPhaseMap.end())  	{ +		found = true;  		elapsed =  iter->second.getElapsedTimeF32();  		completed = !iter->second.getStarted(); -		return true; +		LL_DEBUGS("Avatar") << " phase_name " << phase_name << " elapsed " << elapsed << " completed " << completed << " timer addr " << (S32)(&iter->second) << llendl;  	}  	else  	{ -		return false; +		LL_DEBUGS("Avatar") << " phase_name " << phase_name << " NOT FOUND"  << llendl;  	} + +	return found;  } diff --git a/indra/newview/llviewerstats.h b/indra/newview/llviewerstats.h index 6b2461be41..eaa0b6beff 100755 --- a/indra/newview/llviewerstats.h +++ b/indra/newview/llviewerstats.h @@ -279,7 +279,7 @@ public:  	// Phase tracking (originally put in for avatar rezzing), tracking  	// progress of active/completed phases for activities like outfit changing. -	typedef std::map<std::string,LLFrameTimer>	phase_map_t; +	typedef std::map<std::string,LLTimer>	phase_map_t;  	typedef std::map<std::string,StatsAccumulator>	phase_stats_t;  	class PhaseMap  	{ @@ -288,11 +288,10 @@ public:  		static phase_stats_t sStats;  	public:  		PhaseMap(); -		LLFrameTimer& 	getPhaseTimer(const std::string& phase_name); +		LLTimer& 		getPhaseTimer(const std::string& phase_name);  		bool 			getPhaseValues(const std::string& phase_name, F32& elapsed, bool& completed);  		void			startPhase(const std::string& phase_name);  		void			stopPhase(const std::string& phase_name); -		void			stopAllPhases();  		void			clearPhases();  		LLSD			dumpPhases();  		static StatsAccumulator& getPhaseStats(const std::string& phase_name); diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 310ff47cf5..4593541f35 100755 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -6049,9 +6049,12 @@ void LLVOAvatar::clearPhases()  void LLVOAvatar::startPhase(const std::string& phase_name)  { -	F32 elapsed; -	bool completed; -	if (getPhases().getPhaseValues(phase_name, elapsed, completed)) +	F32 elapsed = 0.0; +	bool completed = false; +	bool found = getPhases().getPhaseValues(phase_name, elapsed, completed); +	//LL_DEBUGS("Avatar") << avString() << " phase state " << phase_name +	//					<< " found " << found << " elapsed " << elapsed << " completed " << completed << llendl; +	if (found)  	{  		if (!completed)  		{ @@ -6065,9 +6068,12 @@ void LLVOAvatar::startPhase(const std::string& phase_name)  void LLVOAvatar::stopPhase(const std::string& phase_name, bool err_check)  { -	F32 elapsed; -	bool completed; -	if (getPhases().getPhaseValues(phase_name, elapsed, completed)) +	F32 elapsed = 0.0; +	bool completed = false; +	bool found = getPhases().getPhaseValues(phase_name, elapsed, completed); +	//LL_DEBUGS("Avatar") << avString() << " phase state " << phase_name +	//					<< " found " << found << " elapsed " << elapsed << " completed " << completed << llendl; +	if (found)  	{  		if (!completed)  		{ @@ -7446,6 +7452,15 @@ std::string get_sequential_numbered_file_name(const std::string& prefix,  	return outfilename;  } +void dump_sequential_xml(const std::string outprefix, const LLSD& content) +{ +	std::string outfilename = get_sequential_numbered_file_name(outprefix,".xml"); +	std::string fullpath = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,outfilename); +	std::ofstream ofs(fullpath.c_str(), std::ios_base::out); +	ofs << LLSDOStreamer<LLSDXMLFormatter>(content, LLSDFormatter::OPTIONS_PRETTY); +	LL_DEBUGS("Avatar") << "results saved to: " << fullpath << LL_ENDL; +} +  void LLVOAvatar::dumpArchetypeXML(const std::string& prefix, bool group_by_wearables )  {  	std::string outprefix(prefix); diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 19ad49d3a1..fad2fd962c 100755 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -998,6 +998,7 @@ extern const S32 MAX_TEXTURE_VIRTUAL_SIZE_RESET_INTERVAL;  std::string get_sequential_numbered_file_name(const std::string& prefix,  											  const std::string& suffix); +void dump_sequential_xml(const std::string outprefix, const LLSD& content);  void dump_visual_param(apr_file_t* file, LLVisualParam* viewer_param, F32 value);  #endif // LL_VOAVATAR_H diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index 5b6fcc5d27..232bf3e478 100755 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -239,6 +239,9 @@ void LLVOAvatarSelf::initInstance()  bool LLVOAvatarSelf::checkStuckAppearance()  { +	const F32 CONDITIONAL_UNSTICK_INTERVAL = 300.0; +	const F32 UNCONDITIONAL_UNSTICK_INTERVAL = 600.0; +	  	if (gAgentWearables.isCOFChangeInProgress())  	{  		LL_DEBUGS("Avatar") << "checking for stuck appearance" << llendl; @@ -246,6 +249,14 @@ bool LLVOAvatarSelf::checkStuckAppearance()  		LL_DEBUGS("Avatar") << "change in progress for " << change_time << " seconds" << llendl;  		S32 active_hp = LLAppearanceMgr::instance().countActiveHoldingPatterns();  		LL_DEBUGS("Avatar") << "active holding patterns " << active_hp << " seconds" << llendl; +		S32 active_copies = LLAppearanceMgr::instance().getActiveCopyOperations(); +		LL_DEBUGS("Avatar") << "active copy operations " << active_copies << llendl; + +		if ((change_time > CONDITIONAL_UNSTICK_INTERVAL && active_copies == 0) || +			(change_time > UNCONDITIONAL_UNSTICK_INTERVAL)) +		{ +			gAgentWearables.notifyLoadingFinished(); +		}  	}  	// Return false to continue running check periodically. @@ -2369,7 +2380,6 @@ LLSD summarize_by_buckets(std::vector<LLSD> in_records,  void LLVOAvatarSelf::sendViewerAppearanceChangeMetrics()  { -	// gAgentAvatarp->stopAllPhases();  	static volatile bool reporting_started(false);  	static volatile S32 report_sequence(0); | 
