diff options
Diffstat (limited to 'indra')
| -rw-r--r-- | indra/newview/llappearancemgr.cpp | 128 | 
1 files changed, 111 insertions, 17 deletions
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 1c2bdf07df..c19b3b50c1 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -261,6 +261,7 @@ public:  	void setObjItems(const LLInventoryModel::item_array_t& items);  	void setGestItems(const LLInventoryModel::item_array_t& items);  	bool isValid(); +	void handleLateArrivals();  private:  	found_list_t mFoundList; @@ -275,6 +276,8 @@ private:  	typedef std::set<LLWearableHoldingPattern*> type_set_hp;  	static type_set_hp sActiveHoldingPatterns;  	bool mIsValid; +	std::set<LLWearable*> mLateArrivals; +	bool mIsAllComplete;  };  LLWearableHoldingPattern::type_set_hp LLWearableHoldingPattern::sActiveHoldingPatterns; @@ -282,7 +285,8 @@ LLWearableHoldingPattern::type_set_hp LLWearableHoldingPattern::sActiveHoldingPa  LLWearableHoldingPattern::LLWearableHoldingPattern():  	mResolved(0),  	mFired(false), -	mIsValid(true) +	mIsValid(true), +	mIsAllComplete(false)  {  	if (sActiveHoldingPatterns.size()>0)  	{ @@ -350,7 +354,10 @@ bool LLWearableHoldingPattern::isTimedOut()  void LLWearableHoldingPattern::checkMissingWearables()  { -	llassert(isValid()); // TODO: handle not valid case +	if (!isValid()) +	{ +		llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; +	}  	std::vector<S32> found_by_type(LLWearableType::WT_COUNT,0);  	std::vector<S32> requested_by_type(LLWearableType::WT_COUNT,0); @@ -394,7 +401,10 @@ void LLWearableHoldingPattern::checkMissingWearables()  void LLWearableHoldingPattern::onAllComplete()  { -	llassert(isValid()); // TODO: handle not valid case +	if (!isValid()) +	{ +		llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; +	}  	// Activate all gestures in this folder  	if (mGestItems.count() > 0) @@ -431,11 +441,19 @@ void LLWearableHoldingPattern::onAllComplete()  		// Only safe to delete if all wearable callbacks and all missing wearables completed.  		delete this;  	} +	else +	{ +		mIsAllComplete = true; +		handleLateArrivals(); +	}  }  void LLWearableHoldingPattern::onFetchCompletion()  { -	llassert(isValid()); // TODO: handle not valid case +	if (!isValid()) +	{ +		llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; +	}  	checkMissingWearables();  } @@ -443,7 +461,10 @@ void LLWearableHoldingPattern::onFetchCompletion()  // Runs as an idle callback until all wearables are fetched (or we time out).  bool LLWearableHoldingPattern::pollFetchCompletion()  { -	llassert(isValid()); // TODO: handle not valid case +	if (!isValid()) +	{ +		llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; +	}  	bool completed = isFetchCompleted();  	bool timed_out = isTimedOut(); @@ -477,7 +498,10 @@ public:  	}  	void fire(const LLUUID& item_id)  	{ -		llassert(mHolder->isValid()); // TODO: handle not valid case +		if (!mHolder->isValid()) +		{ +			llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; +		}  		llinfos << "Recovered item link for type " << mType << llendl;  		mHolder->eraseTypeToLink(mType); @@ -492,11 +516,11 @@ public:  			if (item)  			{  				LLFoundData found(linked_item->getUUID(), -						  linked_item->getAssetUUID(), -						  linked_item->getName(), -						  linked_item->getType(), -						  linked_item->isWearableType() ? linked_item->getWearableType() : LLWearableType::WT_INVALID -						  ); +								  linked_item->getAssetUUID(), +								  linked_item->getName(), +								  linked_item->getType(), +								  linked_item->isWearableType() ? linked_item->getWearableType() : LLWearableType::WT_INVALID +					);  				found.mWearable = mWearable;  				mHolder->getFoundList().push_front(found);  			} @@ -527,7 +551,10 @@ public:  	}  	void fire(const LLUUID& item_id)  	{ -		llassert(mHolder->isValid()); // TODO: handle not valid case +		if (!mHolder->isValid()) +		{ +			llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; +		}  		llinfos << "Recovered item for type " << mType << llendl;  		LLViewerInventoryItem *itemp = gInventory.getItem(item_id); @@ -554,7 +581,10 @@ private:  void LLWearableHoldingPattern::recoverMissingWearable(LLWearableType::EType type)  { -	llassert(isValid()); // TODO: handle not valid case +	if (!isValid()) +	{ +		llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; +	}  		// Try to recover by replacing missing wearable with a new one.  	LLNotificationsUtil::add("ReplacedMissingWearable"); @@ -600,7 +630,10 @@ void LLWearableHoldingPattern::clearCOFLinksForMissingWearables()  bool LLWearableHoldingPattern::pollMissingWearables()  { -	llassert(isValid()); // TODO: handle not valid case +	if (!isValid()) +	{ +		llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; +	}  	bool timed_out = isTimedOut();  	bool missing_completed = isMissingCompleted(); @@ -621,9 +654,63 @@ bool LLWearableHoldingPattern::pollMissingWearables()  	return done;  } +// Handle wearables that arrived after the timeout period expired. +void LLWearableHoldingPattern::handleLateArrivals() +{ +	// Only safe to run if we have previously finished the missing +	// wearables and other processing - otherwise we could be in some +	// intermediate state - but have not been superceded by a later +	// outfit change request. +	if (mLateArrivals.size() == 0) +	{ +		// Nothing to process. +		return; +	} +	if (!isValid()) +	{ +		llwarns << "Late arrivals not handled - outfit change no longer valid" << llendl; +	} +	if (!mIsAllComplete) +	{ +		llwarns << "Late arrivals not handled - in middle of missing wearables processing" << llendl; +	} + +	llinfos << "Need to handle " << mLateArrivals.size() << " late arriving wearables" << llendl; + +	// Update mFoundList using late-arriving wearables. +	for (LLWearableHoldingPattern::found_list_t::iterator iter = getFoundList().begin(); +		 iter != getFoundList().end(); ++iter) +	{ +		LLFoundData& data = *iter; +		for (std::set<LLWearable*>::iterator wear_it = mLateArrivals.begin(); +			 wear_it != mLateArrivals.end(); +			 ++wear_it) +		{ +			LLWearable *wearable = *wear_it; +			 +			if(wearable->getAssetID() == data.mAssetID) +			{ +				data.mWearable = wearable; +				// BAP failing this means inventory or asset server +				// are corrupted in a way we don't handle. +				llassert((data.mWearableType < LLWearableType::WT_COUNT) && (wearable->getType() == data.mWearableType)); +				break; +			} +		} +	} + +	// TODO: handle corresponding default wearable links? + +	// Update appearance based on mFoundList +	LLAppearanceMgr::instance().updateAgentWearables(this, false); +} +  void LLWearableHoldingPattern::onWearableAssetFetch(LLWearable *wearable)  { -	llassert(isValid()); // TODO: handle not valid case +	if (!isValid()) +	{ +		llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; +	}  	mResolved += 1;  // just counting callbacks, not successes.  	llinfos << "onWearableAssetFetch, resolved count " << mResolved << " of requested " << getFoundList().size() << llendl; @@ -639,6 +726,14 @@ void LLWearableHoldingPattern::onWearableAssetFetch(LLWearable *wearable)  	if (mFired)  	{  		llwarns << "called after holder fired" << llendl; +		if (wearable) +		{ +			mLateArrivals.insert(wearable); +			if (mIsAllComplete) +			{ +				handleLateArrivals(); +			} +		}  		return;  	} @@ -1269,8 +1364,7 @@ void LLAppearanceMgr::updateAgentWearables(LLWearableHoldingPattern* holder, boo  	LLInventoryItem::item_array_t items;  	LLDynamicArray< LLWearable* > wearables; -	// For each wearable type, find the first instance in the category -	// that we recursed through. +	// For each wearable type, find the wearables of that type.  	for( S32 i = 0; i < LLWearableType::WT_COUNT; i++ )  	{  		for (LLWearableHoldingPattern::found_list_t::iterator iter = holder->getFoundList().begin();  | 
