EXT-6571 WIP - adding ability to handle late-arriving assets

master
Brad Payne (Vir Linden) 2010-06-11 08:26:18 -04:00
parent 52194cac67
commit 17520c17b1
2 changed files with 127 additions and 26 deletions

View File

@ -3534,6 +3534,28 @@
<key>Value</key>
<real>9.0</real>
</map>
<key>ForceAssetFail</key>
<map>
<key>Comment</key>
<string>Force wearable fetches to fail for this asset type.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>U32</string>
<key>Value</key>
<integer>255</integer>
</map>
<key>MaxWearableWaitTime</key>
<map>
<key>Comment</key>
<string>Max seconds to wait for wearable assets to fetch.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>60.0</real>
</map>
<key>ForceShowGrid</key>
<map>
<key>Comment</key>

View File

@ -223,8 +223,16 @@ public:
void onWearableAssetFetch(LLWearable *wearable);
void onAllComplete();
typedef std::list<LLFoundData> found_list_t;
found_list_t& getFoundList();
void eraseTypeToLink(LLWearableType::EType type);
void eraseTypeToRecover(LLWearableType::EType type);
void setObjItems(const LLInventoryModel::item_array_t& items);
void setGestItems(const LLInventoryModel::item_array_t& items);
bool isValid();
private:
found_list_t mFoundList;
LLInventoryModel::item_array_t mObjItems;
LLInventoryModel::item_array_t mGestItems;
@ -234,34 +242,89 @@ public:
S32 mResolved;
LLTimer mWaitTime;
bool mFired;
typedef std::set<LLWearableHoldingPattern*> type_set_hp;
static type_set_hp sActiveHoldingPatterns;
bool mIsValid;
};
LLWearableHoldingPattern::type_set_hp LLWearableHoldingPattern::sActiveHoldingPatterns;
LLWearableHoldingPattern::LLWearableHoldingPattern():
mResolved(0),
mFired(false)
mFired(false),
mIsValid(true)
{
if (sActiveHoldingPatterns.size()>0)
{
llinfos << "Creating LLWearableHoldingPattern when "
<< sActiveHoldingPatterns.size()
<< " other attempts are active."
<< " Flagging others as invalid."
<< llendl;
for (type_set_hp::iterator it = sActiveHoldingPatterns.begin();
it != sActiveHoldingPatterns.end();
++it)
{
(*it)->mIsValid = false;
}
}
sActiveHoldingPatterns.insert(this);
}
LLWearableHoldingPattern::~LLWearableHoldingPattern()
{
sActiveHoldingPatterns.erase(this);
}
bool LLWearableHoldingPattern::isValid()
{
return mIsValid;
}
LLWearableHoldingPattern::found_list_t& LLWearableHoldingPattern::getFoundList()
{
return mFoundList;
}
void LLWearableHoldingPattern::eraseTypeToLink(LLWearableType::EType type)
{
mTypesToLink.erase(type);
}
void LLWearableHoldingPattern::eraseTypeToRecover(LLWearableType::EType type)
{
mTypesToRecover.erase(type);
}
void LLWearableHoldingPattern::setObjItems(const LLInventoryModel::item_array_t& items)
{
mObjItems = items;
}
void LLWearableHoldingPattern::setGestItems(const LLInventoryModel::item_array_t& items)
{
mGestItems = items;
}
bool LLWearableHoldingPattern::isFetchCompleted()
{
return (mResolved >= (S32)mFoundList.size()); // have everything we were waiting for?
return (mResolved >= (S32)getFoundList().size()); // have everything we were waiting for?
}
bool LLWearableHoldingPattern::isTimedOut()
{
static F32 max_wait_time = 60.0; // give up if wearable fetches haven't completed in max_wait_time seconds.
F32 max_wait_time = gSavedSettings.getF32("MaxWearableWaitTime"); // give up if wearable fetches haven't completed in max_wait_time seconds.
return mWaitTime.getElapsedTimeF32() > max_wait_time;
}
void LLWearableHoldingPattern::checkMissingWearables()
{
llassert(isValid()); // TODO: handle not valid case
std::vector<S32> found_by_type(LLWearableType::WT_COUNT,0);
std::vector<S32> requested_by_type(LLWearableType::WT_COUNT,0);
for (found_list_t::iterator it = mFoundList.begin(); it != mFoundList.end(); ++it)
for (found_list_t::iterator it = getFoundList().begin(); it != getFoundList().end(); ++it)
{
LLFoundData &data = *it;
if (data.mWearableType < LLWearableType::WT_COUNT)
@ -301,6 +364,8 @@ void LLWearableHoldingPattern::checkMissingWearables()
void LLWearableHoldingPattern::onAllComplete()
{
llassert(isValid()); // TODO: handle not valid case
// Activate all gestures in this folder
if (mGestItems.count() > 0)
{
@ -340,12 +405,16 @@ void LLWearableHoldingPattern::onAllComplete()
void LLWearableHoldingPattern::onFetchCompletion()
{
llassert(isValid()); // TODO: handle not valid case
checkMissingWearables();
}
// Runs as an idle callback until all wearables are fetched (or we time out).
bool LLWearableHoldingPattern::pollFetchCompletion()
{
llassert(isValid()); // TODO: handle not valid case
bool completed = isFetchCompleted();
bool timed_out = isTimedOut();
bool done = completed || timed_out;
@ -378,8 +447,10 @@ public:
}
void fire(const LLUUID& item_id)
{
llassert(mHolder->isValid()); // TODO: handle not valid case
llinfos << "Recovered item link for type " << mType << llendl;
mHolder->mTypesToLink.erase(mType);
mHolder->eraseTypeToLink(mType);
// Add wearable to FoundData for actual wearing
LLViewerInventoryItem *item = gInventory.getItem(item_id);
LLViewerInventoryItem *linked_item = item ? item->getLinkedItem() : NULL;
@ -397,7 +468,7 @@ public:
linked_item->isWearableType() ? linked_item->getWearableType() : LLWearableType::WT_INVALID
);
found.mWearable = mWearable;
mHolder->mFoundList.push_front(found);
mHolder->getFoundList().push_front(found);
}
else
{
@ -426,11 +497,13 @@ public:
}
void fire(const LLUUID& item_id)
{
llassert(mHolder->isValid()); // TODO: handle not valid case
llinfos << "Recovered item for type " << mType << llendl;
LLViewerInventoryItem *itemp = gInventory.getItem(item_id);
mWearable->setItemID(item_id);
LLPointer<LLInventoryCallback> cb = new RecoveredItemLinkCB(mType,mWearable,mHolder);
mHolder->mTypesToRecover.erase(mType);
mHolder->eraseTypeToRecover(mType);
llassert(itemp);
if (itemp)
{
@ -451,6 +524,8 @@ private:
void LLWearableHoldingPattern::recoverMissingWearable(LLWearableType::EType type)
{
llassert(isValid()); // TODO: handle not valid case
// Try to recover by replacing missing wearable with a new one.
LLNotificationsUtil::add("ReplacedMissingWearable");
lldebugs << "Wearable " << LLWearableType::getTypeLabel(type)
@ -481,7 +556,7 @@ bool LLWearableHoldingPattern::isMissingCompleted()
void LLWearableHoldingPattern::clearCOFLinksForMissingWearables()
{
for (found_list_t::iterator it = mFoundList.begin(); it != mFoundList.end(); ++it)
for (found_list_t::iterator it = getFoundList().begin(); it != getFoundList().end(); ++it)
{
LLFoundData &data = *it;
if ((data.mWearableType < LLWearableType::WT_COUNT) && (!data.mWearable))
@ -495,6 +570,8 @@ void LLWearableHoldingPattern::clearCOFLinksForMissingWearables()
bool LLWearableHoldingPattern::pollMissingWearables()
{
llassert(isValid()); // TODO: handle not valid case
bool timed_out = isTimedOut();
bool missing_completed = isMissingCompleted();
bool done = timed_out || missing_completed;
@ -516,8 +593,10 @@ bool LLWearableHoldingPattern::pollMissingWearables()
void LLWearableHoldingPattern::onWearableAssetFetch(LLWearable *wearable)
{
llassert(isValid()); // TODO: handle not valid case
mResolved += 1; // just counting callbacks, not successes.
llinfos << "onWearableAssetFetch, resolved count " << mResolved << " of requested " << mFoundList.size() << llendl;
llinfos << "onWearableAssetFetch, resolved count " << mResolved << " of requested " << getFoundList().size() << llendl;
if (wearable)
{
llinfos << "wearable found, type " << wearable->getType() << " asset " << wearable->getAssetID() << llendl;
@ -538,8 +617,8 @@ void LLWearableHoldingPattern::onWearableAssetFetch(LLWearable *wearable)
return;
}
for (LLWearableHoldingPattern::found_list_t::iterator iter = mFoundList.begin();
iter != mFoundList.end(); ++iter)
for (LLWearableHoldingPattern::found_list_t::iterator iter = getFoundList().begin();
iter != getFoundList().end(); ++iter)
{
LLFoundData& data = *iter;
if(wearable->getAssetID() == data.mAssetID)
@ -1143,8 +1222,8 @@ void LLAppearanceMgr::updateAgentWearables(LLWearableHoldingPattern* holder, boo
// that we recursed through.
for( S32 i = 0; i < LLWearableType::WT_COUNT; i++ )
{
for (LLWearableHoldingPattern::found_list_t::iterator iter = holder->mFoundList.begin();
iter != holder->mFoundList.end(); ++iter)
for (LLWearableHoldingPattern::found_list_t::iterator iter = holder->getFoundList().begin();
iter != holder->getFoundList().end(); ++iter)
{
LLFoundData& data = *iter;
LLWearable* wearable = data.mWearable;
@ -1236,8 +1315,8 @@ void LLAppearanceMgr::updateAppearanceFromCOF()
LLWearableHoldingPattern* holder = new LLWearableHoldingPattern;
holder->mObjItems = obj_items;
holder->mGestItems = gest_items;
holder->setObjItems(obj_items);
holder->setGestItems(gest_items);
// Note: can't do normal iteration, because if all the
// wearables can be resolved immediately, then the
@ -1248,6 +1327,12 @@ void LLAppearanceMgr::updateAppearanceFromCOF()
{
LLViewerInventoryItem *item = wear_items.get(i);
LLViewerInventoryItem *linked_item = item ? item->getLinkedItem() : NULL;
// Fault injection: use debug setting to test asset
// fetch failures (should be replaced by new defaults in
// lost&found).
U32 skip_type = gSavedSettings.getU32("ForceAssetFail");
if (item && item->getIsLinkType() && linked_item)
{
LLFoundData found(linked_item->getUUID(),
@ -1257,18 +1342,12 @@ void LLAppearanceMgr::updateAppearanceFromCOF()
linked_item->isWearableType() ? linked_item->getWearableType() : LLWearableType::WT_INVALID
);
#if 0
// Fault injection: uncomment this block to test asset
// fetch failures (should be replaced by new defaults in
// lost&found).
if (found.mWearableType == LLWearableType::WT_SHAPE || found.mWearableType == LLWearableType::WT_JACKET)
if (skip_type != LLWearableType::WT_INVALID && found.mWearableType == skip_type)
{
found.mAssetID.generate(); // Replace with new UUID, guaranteed not to exist in DB
}
#endif
//pushing back, not front, to preserve order of wearables for LLAgentWearables
holder->mFoundList.push_back(found);
holder->getFoundList().push_back(found);
}
else
{
@ -1283,8 +1362,8 @@ void LLAppearanceMgr::updateAppearanceFromCOF()
}
}
for (LLWearableHoldingPattern::found_list_t::iterator it = holder->mFoundList.begin();
it != holder->mFoundList.end(); ++it)
for (LLWearableHoldingPattern::found_list_t::iterator it = holder->getFoundList().begin();
it != holder->getFoundList().end(); ++it)
{
LLFoundData& found = *it;