diff options
| -rw-r--r-- | indra/newview/llagentwearables.cpp | 80 | ||||
| -rw-r--r-- | indra/newview/llappearancemgr.cpp | 3 | ||||
| -rw-r--r-- | indra/newview/llinventoryobserver.cpp | 18 | ||||
| -rw-r--r-- | indra/newview/llinventoryobserver.h | 3 | 
4 files changed, 90 insertions, 14 deletions
diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index 538dcb6f3d..cfa3f4ae02 100644 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -2155,7 +2155,6 @@ void LLLibraryOutfitsFetch::contentsDone(void)  LLInitialWearablesFetch::~LLInitialWearablesFetch()  { -	llinfos << "~LLInitialWearablesFetch" << llendl;  }  // virtual @@ -2185,17 +2184,50 @@ void LLInitialWearablesFetch::processContents()  	else  	{  		processWearablesMessage(); -		// Create links for attachments that may have arrived before the COF existed. -		LLAppearanceManager::instance().linkRegisteredAttachments();  	}  	delete this;  } +class LLFetchAndLinkObserver: public LLInventoryFetchObserver +{ +public: +	LLFetchAndLinkObserver(LLInventoryFetchObserver::item_ref_t& ids): +		m_ids(ids), +		LLInventoryFetchObserver(true) +	{ +	} +	~LLFetchAndLinkObserver() +	{ +	} +	virtual void done() +	{ +		gInventory.removeObserver(this); +		// Link to all fetched items in COF. +		for (LLInventoryFetchObserver::item_ref_t::iterator it = m_ids.begin(); +			 it != m_ids.end(); +			 ++it) +		{ +			LLUUID id = *it; +			LLViewerInventoryItem *item = gInventory.getItem(*it); +			if (!item) +			{ +				llwarns << "fetch failed!" << llendl; +				continue; +			} +			link_inventory_item(gAgent.getID(), item->getLinkedUUID(), LLAppearanceManager::instance().getCOF(), item->getName(), +								LLAssetType::AT_LINK, LLPointer<LLInventoryCallback>(NULL)); +		} +	} +private: +	LLInventoryFetchObserver::item_ref_t m_ids; +}; +  void LLInitialWearablesFetch::processWearablesMessage()  {  	if (!mAgentInitialWearables.empty()) // We have an empty current outfit folder, use the message data instead.  	{ -		const LLUUID current_outfit_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT); +		const LLUUID current_outfit_id = LLAppearanceManager::instance().getCOF(); +		LLInventoryFetchObserver::item_ref_t ids;  		for (U8 i = 0; i < mAgentInitialWearables.size(); ++i)  		{  			// Populate the current outfit folder with links to the wearables passed in the message @@ -2204,9 +2236,7 @@ void LLInitialWearablesFetch::processWearablesMessage()  			if (wearable_data->mAssetID.notNull())  			{  #ifdef USE_CURRENT_OUTFIT_FOLDER -				const std::string link_name = "WearableLink"; // Unimportant what this is named, it isn't exposed. -				link_inventory_item(gAgent.getID(), wearable_data->mItemID, current_outfit_id, link_name, -									LLAssetType::AT_LINK, LLPointer<LLInventoryCallback>(NULL)); +				ids.push_back(wearable_data->mItemID);  #endif  				// Fetch the wearables  				LLWearableList::instance().getAsset(wearable_data->mAssetID, @@ -2220,6 +2250,42 @@ void LLInitialWearablesFetch::processWearablesMessage()  				<< wearable_data->mItemID << " assetID " << wearable_data->mAssetID << llendl;  			}  		} + +		// Add all current attachments to the requested items as well. +		LLVOAvatarSelf* avatar = gAgent.getAvatarObject(); +		if( avatar ) +		{ +			for (LLVOAvatar::attachment_map_t::const_iterator iter = avatar->mAttachmentPoints.begin();  +				 iter != avatar->mAttachmentPoints.end(); ++iter) +			{ +				LLViewerJointAttachment* attachment = iter->second; +				if (!attachment) continue; +				for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); +					 attachment_iter != attachment->mAttachedObjects.end(); +					 ++attachment_iter) +				{ +					LLViewerObject* attached_object = (*attachment_iter); +					if (!attached_object) continue; +					const LLUUID& item_id = attached_object->getItemID(); +					if (item_id.isNull()) continue; +					ids.push_back(item_id); +				} +			} +		} + +		// Need to fetch the inventory items for ids, then create links to them after they arrive. +		LLFetchAndLinkObserver *fetcher = new LLFetchAndLinkObserver(ids); +		fetcher->fetchItems(ids); +		// If no items to be fetched, done will never be triggered. +		// TODO: Change LLInventoryFetchObserver::fetchItems to trigger done() on this condition. +		if (fetcher->isEverythingComplete()) +		{ +			fetcher->done(); +		} +		else +		{ +			gInventory.addObserver(fetcher); +		}  	}  	else  	{ diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index e5e27dedba..bdb3c6e24e 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -827,7 +827,7 @@ bool areMatchingWearables(const LLViewerInventoryItem *a, const LLViewerInventor  void LLAppearanceManager::addCOFItemLink(const LLUUID &item_id, bool do_update )  {  	const LLInventoryItem *item = gInventory.getItem(item_id); -	addCOFItemLink(item); +	addCOFItemLink(item, do_update);  }  void LLAppearanceManager::addCOFItemLink(const LLInventoryItem *item, bool do_update ) @@ -998,7 +998,6 @@ void LLAppearanceManager::registerAttachment(const LLUUID& item_id)  	   if (mAttachmentInvLinkEnabled)  	   { -		   //LLAppearanceManager::dumpCat(LLAppearanceManager::getCOF(),"Adding attachment link:");  		   LLAppearanceManager::addCOFItemLink(item_id, false);  // Add COF link for item.  	   }  	   else diff --git a/indra/newview/llinventoryobserver.cpp b/indra/newview/llinventoryobserver.cpp index 3ccf593d27..06f4b36df3 100644 --- a/indra/newview/llinventoryobserver.cpp +++ b/indra/newview/llinventoryobserver.cpp @@ -112,10 +112,20 @@ void LLInventoryFetchObserver::changed(U32 mask)  			LLViewerInventoryItem* item = gInventory.getItem(*it);  			if(!item)  			{ -				// BUG: This can cause done() to get called prematurely below. -				// This happens with the LLGestureInventoryFetchObserver that -				// loads gestures at startup. JC -				it = mIncomplete.erase(it); +				if (mRetryIfMissing) +				{ +					// BAP changed to skip these items, so we should keep retrying until they arrive. +					// Did not make this the default behavior because of uncertainty about impact - +					// could cause some observers that currently complete to wait forever. +					++it; +				} +				else +				{ +					// BUG: This can cause done() to get called prematurely below. +					// This happens with the LLGestureInventoryFetchObserver that +					// loads gestures at startup. JC +					it = mIncomplete.erase(it); +				}  				continue;  			}  			if(item->isComplete()) diff --git a/indra/newview/llinventoryobserver.h b/indra/newview/llinventoryobserver.h index 384e6292e8..3a083e913b 100644 --- a/indra/newview/llinventoryobserver.h +++ b/indra/newview/llinventoryobserver.h @@ -106,7 +106,7 @@ protected:  class LLInventoryFetchObserver : public LLInventoryObserver  {  public: -	LLInventoryFetchObserver() {} +	LLInventoryFetchObserver(bool retry_if_missing = false): mRetryIfMissing(retry_if_missing) {}  	virtual void changed(U32 mask);  	typedef std::vector<LLUUID> item_ref_t; @@ -116,6 +116,7 @@ public:  	virtual void done() = 0;  protected: +	bool mRetryIfMissing;  	item_ref_t mComplete;  	item_ref_t mIncomplete;  };  | 
