diff options
Diffstat (limited to 'indra/newview/llappearancemgr.cpp')
-rw-r--r-- | indra/newview/llappearancemgr.cpp | 104 |
1 files changed, 57 insertions, 47 deletions
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 17efc28a6a..a7d90ab8d3 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -403,7 +403,10 @@ void LLWearableHoldingPattern::checkMissingWearables() for (S32 type = 0; type < LLWearableType::WT_COUNT; ++type) { - llinfos << "type " << type << " requested " << requested_by_type[type] << " found " << found_by_type[type] << llendl; + if (requested_by_type[type] > found_by_type[type]) + { + llwarns << "got fewer wearables than requested, type " << type << ": requested " << requested_by_type[type] << ", found " << found_by_type[type] << llendl; + } if (found_by_type[type] > 0) continue; if ( @@ -670,12 +673,15 @@ bool LLWearableHoldingPattern::pollMissingWearables() bool timed_out = isTimedOut(); bool missing_completed = isMissingCompleted(); bool done = timed_out || missing_completed; - - llinfos << "polling missing wearables, waiting for items " << mTypesToRecover.size() - << " links " << mTypesToLink.size() - << " wearables, timed out " << timed_out - << " elapsed " << mWaitTime.getElapsedTimeF32() - << " done " << done << llendl; + + if (!done) + { + llinfos << "polling missing wearables, waiting for items " << mTypesToRecover.size() + << " links " << mTypesToLink.size() + << " wearables, timed out " << timed_out + << " elapsed " << mWaitTime.getElapsedTimeF32() + << " done " << done << llendl; + } if (done) { @@ -795,12 +801,8 @@ void LLWearableHoldingPattern::onWearableAssetFetch(LLWearable *wearable) } mResolved += 1; // just counting callbacks, not successes. - llinfos << "onWearableAssetFetch, resolved count " << mResolved << " of requested " << getFoundList().size() << llendl; - if (wearable) - { - llinfos << "wearable found, type " << wearable->getType() << " asset " << wearable->getAssetID() << llendl; - } - else + llinfos << "resolved " << mResolved << "/" << getFoundList().size() << llendl; + if (!wearable) { llwarns << "no wearable found" << llendl; } @@ -830,10 +832,14 @@ void LLWearableHoldingPattern::onWearableAssetFetch(LLWearable *wearable) LLFoundData& data = *iter; if(wearable->getAssetID() == data.mAssetID) { - data.mWearable = wearable; // 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; + if ((data.mWearableType >= LLWearableType::WT_COUNT) || (wearable->getType() != data.mWearableType)) + { + llwarns << "recovered wearable but type invalid. inventory wearable type: " << data.mWearableType << " asset wearable type: " << wearable->getType() << llendl; + break; + } + + data.mWearable = wearable; } } } @@ -945,7 +951,7 @@ const LLUUID LLAppearanceMgr::getBaseOutfitUUID() return outfit_cat->getUUID(); } -bool LLAppearanceMgr::wearItemOnAvatar(const LLUUID& item_id_to_wear, bool do_update, bool replace) +bool LLAppearanceMgr::wearItemOnAvatar(const LLUUID& item_id_to_wear, bool do_update, bool replace, LLPointer<LLInventoryCallback> cb) { if (item_id_to_wear.isNull()) return false; @@ -989,18 +995,17 @@ bool LLAppearanceMgr::wearItemOnAvatar(const LLUUID& item_id_to_wear, bool do_up { removeCOFItemLinks(gAgentWearables.getWearableItemID(item_to_wear->getWearableType(), wearable_count-1), false); } + addCOFItemLink(item_to_wear, do_update, cb); } + break; case LLAssetType::AT_BODYPART: // TODO: investigate wearables may not be loaded at this point EXT-8231 // Remove the existing wearables of the same type. // Remove existing body parts anyway because we must not be able to wear e.g. two skins. - if (item_to_wear->getType() == LLAssetType::AT_BODYPART) - { - removeCOFLinksOfType(item_to_wear->getWearableType(), false); - } + removeCOFLinksOfType(item_to_wear->getWearableType(), false); - addCOFItemLink(item_to_wear, do_update); + addCOFItemLink(item_to_wear, do_update, cb); break; case LLAssetType::AT_OBJECT: rez_attachment(item_to_wear, NULL); @@ -1636,7 +1641,7 @@ void LLAppearanceMgr::updateAppearanceFromCOF(bool update_base_outfit_ordering) // the saved outfit stored as a folder link updateIsDirty(); - dumpCat(getCOF(),"COF, start"); + //dumpCat(getCOF(),"COF, start"); bool follow_folder_links = true; LLUUID current_outfit_id = getCOF(); @@ -1719,7 +1724,7 @@ void LLAppearanceMgr::updateAppearanceFromCOF(bool update_base_outfit_ordering) { LLFoundData& found = *it; - llinfos << "waiting for onWearableAssetFetch callback, asset " << found.mAssetID.asString() << llendl; + lldebugs << "waiting for onWearableAssetFetch callback, asset " << found.mAssetID.asString() << llendl; // Fetch the wearables about to be worn. LLWearableList::instance().getAsset(found.mAssetID, @@ -1954,9 +1959,10 @@ bool areMatchingWearables(const LLViewerInventoryItem *a, const LLViewerInventor class LLDeferredCOFLinkObserver: public LLInventoryObserver { public: - LLDeferredCOFLinkObserver(const LLUUID& item_id, bool do_update): + LLDeferredCOFLinkObserver(const LLUUID& item_id, bool do_update, LLPointer<LLInventoryCallback> cb = NULL): mItemID(item_id), - mDoUpdate(do_update) + mDoUpdate(do_update), + mCallback(cb) { } @@ -1970,7 +1976,7 @@ public: if (item) { gInventory.removeObserver(this); - LLAppearanceMgr::instance().addCOFItemLink(item,mDoUpdate); + LLAppearanceMgr::instance().addCOFItemLink(item,mDoUpdate,mCallback); delete this; } } @@ -1978,26 +1984,27 @@ public: private: const LLUUID mItemID; bool mDoUpdate; + LLPointer<LLInventoryCallback> mCallback; }; // BAP - note that this runs asynchronously if the item is not already loaded from inventory. // Dangerous if caller assumes link will exist after calling the function. -void LLAppearanceMgr::addCOFItemLink(const LLUUID &item_id, bool do_update ) +void LLAppearanceMgr::addCOFItemLink(const LLUUID &item_id, bool do_update, LLPointer<LLInventoryCallback> cb) { const LLInventoryItem *item = gInventory.getItem(item_id); if (!item) { - LLDeferredCOFLinkObserver *observer = new LLDeferredCOFLinkObserver(item_id, do_update); + LLDeferredCOFLinkObserver *observer = new LLDeferredCOFLinkObserver(item_id, do_update, cb); gInventory.addObserver(observer); } else { - addCOFItemLink(item, do_update); + addCOFItemLink(item, do_update, cb); } } -void LLAppearanceMgr::addCOFItemLink(const LLInventoryItem *item, bool do_update ) +void LLAppearanceMgr::addCOFItemLink(const LLInventoryItem *item, bool do_update, LLPointer<LLInventoryCallback> cb) { const LLViewerInventoryItem *vitem = dynamic_cast<const LLViewerInventoryItem*>(item); if (!vitem) @@ -2058,7 +2065,10 @@ void LLAppearanceMgr::addCOFItemLink(const LLInventoryItem *item, bool do_update } else { - LLPointer<LLInventoryCallback> cb = do_update ? new ModifiedCOFCallback : 0; + if(do_update && cb.isNull()) + { + cb = new ModifiedCOFCallback; + } const std::string description = vitem->getIsLinkType() ? vitem->getDescription() : ""; link_inventory_item( gAgent.getID(), vitem->getLinkedUUID(), @@ -2169,17 +2179,19 @@ void LLAppearanceMgr::updateIsDirty() } else { + LLIsOfAssetType collector = LLIsOfAssetType(LLAssetType::AT_LINK); + LLInventoryModel::cat_array_t cof_cats; LLInventoryModel::item_array_t cof_items; - gInventory.collectDescendents(cof, cof_cats, cof_items, - LLInventoryModel::EXCLUDE_TRASH); + gInventory.collectDescendentsIf(cof, cof_cats, cof_items, + LLInventoryModel::EXCLUDE_TRASH, collector); LLInventoryModel::cat_array_t outfit_cats; LLInventoryModel::item_array_t outfit_items; - gInventory.collectDescendents(base_outfit, outfit_cats, outfit_items, - LLInventoryModel::EXCLUDE_TRASH); + gInventory.collectDescendentsIf(base_outfit, outfit_cats, outfit_items, + LLInventoryModel::EXCLUDE_TRASH, collector); - if(outfit_items.count() != cof_items.count() -1) + if(outfit_items.count() != cof_items.count()) { // Current outfit folder should have one more item than the outfit folder. // this one item is the link back to the outfit folder itself. @@ -2187,16 +2199,6 @@ void LLAppearanceMgr::updateIsDirty() return; } - //getting rid of base outfit folder link to simplify comparison - for (LLInventoryModel::item_array_t::iterator it = cof_items.begin(); it != cof_items.end(); ++it) - { - if (*it == base_outfit_item) - { - cof_items.erase(it); - break; - } - } - //"dirty" - also means a difference in linked UUIDs and/or a difference in wearables order (links' descriptions) std::sort(cof_items.begin(), cof_items.end(), sort_by_linked_uuid); std::sort(outfit_items.begin(), outfit_items.end(), sort_by_linked_uuid); @@ -2490,6 +2492,14 @@ void LLAppearanceMgr::removeItemFromAvatar(const LLUUID& id_to_remove) } default: break; } + + // *HACK: Force to remove garbage from COF. + // Unworn links or objects can't be processed by existed removing functionality + // since it is not designed for such cases. As example attachment object can't be removed + // since sever don't sends message _PREHASH_KillObject in that case. + // Also we can't check is link was successfully removed from COF since in case + // deleting attachment link removing performs asynchronously in process_kill_object callback. + removeCOFItemLinks(id_to_remove,false); } bool LLAppearanceMgr::moveWearable(LLViewerInventoryItem* item, bool closer_to_body) |