1. simon_linden
  2. viewer-rabbit

Commits

Seth ProductEngine  committed 4eb0535

EXT-8636 FIXED updating wearables (worn) prefix in 'My Outfits' list.
- Fixed LLOutfitsList COF changes handler to update worn status of items removed from COF. Now they are updated based on the differences in original items' ids in COF.
- Fixed 'My Outfits' items worn status check to update depending on whether the item is linked in COF or not.
This is a kind of workaround to fix updating attachments' worn status because LLAppearanceMgr::updateAppearanceFromCOF is triggered erlier than new attachment links are fetched. When dumpItemArray(obj_items,"asset_dump: obj_item") is called from LLAppearanceMgr::updateAppearanceFromCOF, all attachment links have empty asset ids.

Reviewed by Vadim Savchuk at https://codereview.productengine.com/secondlife/r/859/.

  • Participants
  • Parent commits 84846ef
  • Branches product-engine

Comments (0)

Files changed (4)

File indra/newview/lloutfitslist.cpp

View file
 
 void LLOutfitsList::onCOFChanged()
 {
-	LLInventoryModel::changed_items_t changed_linked_items;
+	LLInventoryModel::cat_array_t cat_array;
+	LLInventoryModel::item_array_t item_array;
 
-	const LLInventoryModel::changed_items_t& changed_items = gInventory.getChangedIDs();
-	for (LLInventoryModel::changed_items_t::const_iterator iter = changed_items.begin();
-		 iter != changed_items.end();
-		 ++iter)
+	// Collect current COF items
+	gInventory.collectDescendents(
+		LLAppearanceMgr::instance().getCOF(),
+		cat_array,
+		item_array,
+		LLInventoryModel::EXCLUDE_TRASH);
+
+	uuid_vec_t vnew;
+	uuid_vec_t vadded;
+	uuid_vec_t vremoved;
+
+	// From gInventory we get the UUIDs of links that are currently in COF.
+	// These links UUIDs are not the same UUIDs that we have in each wearable items list.
+	// So we collect base items' UUIDs to find them or links that point to them in wearable
+	// items lists and update their worn state there.
+	for (LLInventoryModel::item_array_t::const_iterator iter = item_array.begin();
+		iter != item_array.end();
+		++iter)
 	{
-		LLViewerInventoryItem* item = gInventory.getItem(*iter);
-		if (item)
-		{
-			// From gInventory we get the UUIDs of new links added to COF
-			// or removed from COF. These links UUIDs are not the same UUIDs
-			// that we have in each wearable items list. So we collect base items
-			// UUIDs to find all items or links that point to same base items in wearable
-			// items lists and update their worn state there.
-			changed_linked_items.insert(item->getLinkedUUID());
-		}
+		vnew.push_back((*iter)->getLinkedUUID());
 	}
 
+	// We need to update only items that were added or removed from COF.
+	LLCommonUtils::computeDifference(vnew, mCOFLinkedItems, vadded, vremoved);
+
+	// Store the ids of items currently linked from COF.
+	mCOFLinkedItems = vnew;
+
 	for (outfits_map_t::iterator iter = mOutfitsMap.begin();
 			iter != mOutfitsMap.end();
 			++iter)
 		LLWearableItemsList* list = dynamic_cast<LLWearableItemsList*>(tab->getAccordionView());
 		if (!list) continue;
 
+		// Append removed ids to added ids because we should update all of them.
+		vadded.reserve(vadded.size() + vremoved.size());
+		vadded.insert(vadded.end(), vremoved.begin(), vremoved.end());
+
 		// Every list updates the labels of changed items  or
 		// the links that point to these items.
-		list->updateChangedItems(changed_linked_items);
+		list->updateChangedItems(vadded);
 	}
 }
 

File indra/newview/lloutfitslist.h

View file
 	typedef outfits_map_t::value_type					outfits_map_value_t;
 	outfits_map_t					mOutfitsMap;
 
+	// IDs of original items which are worn and linked in COF.
+	// Used to monitor COF changes for updating items worn state. See EXT-8636.
+	uuid_vec_t						mCOFLinkedItems;
+
 	LLOutfitListGearMenu*			mGearMenu;
 	LLListContextMenu*				mOutfitMenu;
 

File indra/newview/llwearableitemslist.cpp

View file
 {
 	std::string search_label = name;
 
-	if (mWornIndicationEnabled && get_is_item_worn(mInventoryItemUUID))
+	// Updating item's worn status depending on whether it is linked in COF or not.
+	// We don't use get_is_item_worn() here because this update is triggered by
+	// an inventory observer upon link in COF beind added or removed so actual
+	// worn status of a linked item may still remain unchanged.
+	if (mWornIndicationEnabled && LLAppearanceMgr::instance().isLinkInCOF(mInventoryItemUUID))
 	{
 		search_label += LLTrans::getString("worn");
 		item_state = IS_WORN;
 	refreshList(item_array);
 }
 
-void LLWearableItemsList::updateChangedItems(const LLInventoryModel::changed_items_t& changed_items_uuids)
+void LLWearableItemsList::updateChangedItems(const uuid_vec_t& changed_items_uuids)
 {
 	// nothing to update
 	if (changed_items_uuids.empty()) return;
 
 		LLUUID linked_uuid = inv_item->getLinkedUUID();
 
-		for (LLInventoryModel::changed_items_t::const_iterator iter = changed_items_uuids.begin();
+		for (uuid_vec_t::const_iterator iter = changed_items_uuids.begin();
 				iter != changed_items_uuids.end();
 				++iter)
 		{

File indra/newview/llwearableitemslist.h

View file
 // newview
 #include "llinventoryitemslist.h"
 #include "llinventorylistitem.h"
-#include "llinventorymodel.h"
 #include "lllistcontextmenu.h"
 #include "llwearabletype.h"
 
 	 * Update items that match UUIDs from changed_items_uuids
 	 * or links that point at such items.
 	 */
-	void updateChangedItems(const LLInventoryModel::changed_items_t& changed_items_uuids);
+	void updateChangedItems(const uuid_vec_t& changed_items_uuids);
 
 	bool isStandalone() const { return mIsStandalone; }