summaryrefslogtreecommitdiff
path: root/indra/newview/llagentwearables.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llagentwearables.cpp')
-rw-r--r--indra/newview/llagentwearables.cpp103
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
{