diff options
Diffstat (limited to 'indra/newview/llagentwearables.cpp')
-rw-r--r-- | indra/newview/llagentwearables.cpp | 103 |
1 files changed, 82 insertions, 21 deletions
diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index 6b2033fc6f..cfa3f4ae02 100644 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -653,11 +653,13 @@ LLWearable* LLAgentWearables::getWearable(const EWearableType type, U32 index) void LLAgentWearables::setWearable(const EWearableType type, U32 index, LLWearable *wearable) { - if (!getWearable(type,index)) + LLWearable *old_wearable = getWearable(type,index); + if (!old_wearable) { pushWearable(type,wearable); return; } + wearableentry_map_t::iterator wearable_iter = mWearableDatas.find(type); if (wearable_iter == mWearableDatas.end()) { @@ -672,6 +674,7 @@ void LLAgentWearables::setWearable(const EWearableType type, U32 index, LLWearab else { wearable_vec[index] = wearable; + old_wearable->setLabelUpdated(); mAvatarObject->wearableUpdated(wearable->getType()); } } @@ -688,6 +691,7 @@ U32 LLAgentWearables::pushWearable(const EWearableType type, LLWearable *wearabl { mWearableDatas[type].push_back(wearable); mAvatarObject->wearableUpdated(wearable->getType()); + wearable->setLabelUpdated(); return mWearableDatas[type].size()-1; } return MAX_WEARABLES_PER_TYPE; @@ -717,6 +721,7 @@ void LLAgentWearables::popWearable(const EWearableType type, U32 index) { mWearableDatas[type].erase(mWearableDatas[type].begin() + index); mAvatarObject->wearableUpdated(wearable->getType()); + wearable->setLabelUpdated(); } } @@ -1412,14 +1417,10 @@ void LLAgentWearables::removeWearableFinal(const EWearableType type, bool do_rem for (S32 i=max_entry; i>=0; i--) { LLWearable* old_wearable = getWearable(type,i); - const LLUUID &item_id = getWearableItemID(type,i); - popWearable(type,i); - gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id); - LLAppearanceManager::instance().removeItemLinks(item_id,false); - //queryWearableCache(); // moved below if (old_wearable) { + popWearable(old_wearable); old_wearable->removeFromAvatar(TRUE); } } @@ -1428,16 +1429,11 @@ void LLAgentWearables::removeWearableFinal(const EWearableType type, bool do_rem else { LLWearable* old_wearable = getWearable(type, index); - - const LLUUID &item_id = getWearableItemID(type,index); - popWearable(type, index); - gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id); - LLAppearanceManager::instance().removeItemLinks(item_id,false); - //queryWearableCache(); // moved below if (old_wearable) { + popWearable(old_wearable); old_wearable->removeFromAvatar(TRUE); } } @@ -1499,7 +1495,6 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it continue; } - gInventory.addChangedMask(LLInventoryObserver::LABEL, old_item_id); // Assumes existing wearables are not dirty. if (old_wearable->isDirty()) { @@ -1508,9 +1503,9 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it } } - setWearable(type,0,new_wearable); if (new_wearable) new_wearable->setItemID(new_item->getUUID()); + setWearable(type,0,new_wearable); } std::vector<LLWearable*> wearables_being_removed; @@ -2160,7 +2155,6 @@ void LLLibraryOutfitsFetch::contentsDone(void) LLInitialWearablesFetch::~LLInitialWearablesFetch() { - llinfos << "~LLInitialWearablesFetch" << llendl; } // virtual @@ -2190,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 @@ -2209,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, @@ -2225,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 { |