summaryrefslogtreecommitdiff
path: root/indra/newview/llagentwearables.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llagentwearables.cpp')
-rwxr-xr-xindra/newview/llagentwearables.cpp228
1 files changed, 132 insertions, 96 deletions
diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp
index 1edbbe2a2e..8501436b5b 100755
--- a/indra/newview/llagentwearables.cpp
+++ b/indra/newview/llagentwearables.cpp
@@ -62,15 +62,15 @@ using namespace LLAvatarAppearanceDefines;
// Callback to wear and start editing an item that has just been created.
void wear_and_edit_cb(const LLUUID& inv_item)
- {
- if (inv_item.isNull()) return;
-
- // Request editing the item after it gets worn.
- gAgentWearables.requestEditingWearable(inv_item);
-
- // Wear it.
- LLAppearanceMgr::instance().wearItemOnAvatar(inv_item);
- }
+{
+ if (inv_item.isNull()) return;
+
+ // Request editing the item after it gets worn.
+ gAgentWearables.requestEditingWearable(inv_item);
+
+ // Wear it.
+ LLAppearanceMgr::instance().wearItemOnAvatar(inv_item,true);
+}
///////////////////////////////////////////////////////////////////////////////
@@ -180,10 +180,10 @@ void LLAgentWearables::initClass()
}
void LLAgentWearables::setAvatarObject(LLVOAvatarSelf *avatar)
-{
+{
llassert(avatar);
- avatar->outputRezTiming("Sending wearables request");
- sendAgentWearablesRequest();
+ avatar->outputRezTiming("Sending wearables request");
+ sendAgentWearablesRequest();
setAvatarAppearance(avatar);
}
@@ -209,7 +209,7 @@ LLAgentWearables::sendAgentWearablesUpdateCallback::~sendAgentWearablesUpdateCal
* @param wearable The wearable data.
* @param todo Bitmask of actions to take on completion.
*/
-LLAgentWearables::addWearableToAgentInventoryCallback::addWearableToAgentInventoryCallback(
+LLAgentWearables::AddWearableToAgentInventoryCallback::AddWearableToAgentInventoryCallback(
LLPointer<LLRefCount> cb, LLWearableType::EType type, U32 index, LLViewerWearable* wearable, U32 todo, const std::string description) :
mType(type),
mIndex(index),
@@ -221,7 +221,7 @@ LLAgentWearables::addWearableToAgentInventoryCallback::addWearableToAgentInvento
llinfos << "constructor" << llendl;
}
-void LLAgentWearables::addWearableToAgentInventoryCallback::fire(const LLUUID& inv_item)
+void LLAgentWearables::AddWearableToAgentInventoryCallback::fire(const LLUUID& inv_item)
{
if (mTodo & CALL_CREATESTANDARDDONE)
{
@@ -239,7 +239,7 @@ void LLAgentWearables::addWearableToAgentInventoryCallback::fire(const LLUUID& i
}
if (mTodo & CALL_RECOVERDONE)
{
- LLAppearanceMgr::instance().addCOFItemLink(inv_item,false);
+ LLAppearanceMgr::instance().addCOFItemLink(inv_item);
gAgentWearables.recoverMissingWearableDone();
}
/*
@@ -247,7 +247,7 @@ void LLAgentWearables::addWearableToAgentInventoryCallback::fire(const LLUUID& i
*/
if (mTodo & CALL_CREATESTANDARDDONE)
{
- LLAppearanceMgr::instance().addCOFItemLink(inv_item,false);
+ LLAppearanceMgr::instance().addCOFItemLink(inv_item);
gAgentWearables.createStandardWearablesDone(mType, mIndex);
}
if (mTodo & CALL_MAKENEWOUTFITDONE)
@@ -256,7 +256,8 @@ void LLAgentWearables::addWearableToAgentInventoryCallback::fire(const LLUUID& i
}
if (mTodo & CALL_WEARITEM)
{
- LLAppearanceMgr::instance().addCOFItemLink(inv_item, true, NULL, mDescription);
+ LLAppearanceMgr::instance().addCOFItemLink(inv_item,
+ new LLUpdateAppearanceAndEditWearableOnDestroy(inv_item), mDescription);
}
}
@@ -316,12 +317,12 @@ void LLAgentWearables::sendAgentWearablesUpdate()
if (wearable->getItemID().isNull())
{
LLPointer<LLInventoryCallback> cb =
- new addWearableToAgentInventoryCallback(
+ new AddWearableToAgentInventoryCallback(
LLPointer<LLRefCount>(NULL),
(LLWearableType::EType)type,
index,
wearable,
- addWearableToAgentInventoryCallback::CALL_NONE);
+ AddWearableToAgentInventoryCallback::CALL_NONE);
addWearableToAgentInventory(cb, wearable);
}
else
@@ -418,23 +419,18 @@ void LLAgentWearables::saveWearable(const LLWearableType::EType type, const U32
item->getFlags(),
item->getCreationDate());
template_item->setTransactionID(new_wearable->getTransactionID());
- template_item->updateServer(FALSE);
- gInventory.updateItem(template_item);
- if (name_changed)
- {
- gInventory.notifyObservers();
- }
+ update_inventory_item(template_item, gAgentAvatarp->mEndCustomizeCallback);
}
else
{
// Add a new inventory item (shouldn't ever happen here)
- U32 todo = addWearableToAgentInventoryCallback::CALL_NONE;
+ U32 todo = AddWearableToAgentInventoryCallback::CALL_NONE;
if (send_update)
{
- todo |= addWearableToAgentInventoryCallback::CALL_UPDATE;
+ todo |= AddWearableToAgentInventoryCallback::CALL_UPDATE;
}
LLPointer<LLInventoryCallback> cb =
- new addWearableToAgentInventoryCallback(
+ new AddWearableToAgentInventoryCallback(
LLPointer<LLRefCount>(NULL),
type,
index,
@@ -483,12 +479,12 @@ void LLAgentWearables::saveWearableAs(const LLWearableType::EType type,
old_wearable,
trunc_name);
LLPointer<LLInventoryCallback> cb =
- new addWearableToAgentInventoryCallback(
+ new AddWearableToAgentInventoryCallback(
LLPointer<LLRefCount>(NULL),
type,
index,
new_wearable,
- addWearableToAgentInventoryCallback::CALL_WEARITEM,
+ AddWearableToAgentInventoryCallback::CALL_WEARITEM,
description
);
LLUUID category_id;
@@ -706,7 +702,7 @@ LLViewerWearable* LLAgentWearables::getViewerWearable(const LLWearableType::ETyp
}
const LLViewerWearable* LLAgentWearables::getViewerWearable(const LLWearableType::EType type, U32 index /*= 0*/) const
- {
+{
return dynamic_cast<const LLViewerWearable*> (getWearable(type, index));
}
@@ -714,39 +710,39 @@ const LLViewerWearable* LLAgentWearables::getViewerWearable(const LLWearableType
BOOL LLAgentWearables::selfHasWearable(LLWearableType::EType type)
{
return (gAgentWearables.getWearableCount(type) > 0);
- }
-
+}
+
// virtual
void LLAgentWearables::wearableUpdated(LLWearable *wearable, BOOL removed)
- {
+{
if (isAgentAvatarValid())
{
const BOOL upload_result = removed;
gAgentAvatarp->wearableUpdated(wearable->getType(), upload_result);
-}
+ }
LLWearableData::wearableUpdated(wearable, removed);
if (!removed)
-{
+ {
LLViewerWearable* viewer_wearable = dynamic_cast<LLViewerWearable*>(wearable);
viewer_wearable->refreshName();
- // Hack pt 2. If the wearable we just loaded has definition version 24,
- // then force a re-save of this wearable after slamming the version number to 22.
- // This number was incorrectly incremented for internal builds before release, and
- // this fix will ensure that the affected wearables are re-saved with the right version number.
- // the versions themselves are compatible. This code can be removed before release.
- if( wearable->getDefinitionVersion() == 24 )
- {
- wearable->setDefinitionVersion(22);
- U32 index = getWearableIndex(wearable);
+ // Hack pt 2. If the wearable we just loaded has definition version 24,
+ // then force a re-save of this wearable after slamming the version number to 22.
+ // This number was incorrectly incremented for internal builds before release, and
+ // this fix will ensure that the affected wearables are re-saved with the right version number.
+ // the versions themselves are compatible. This code can be removed before release.
+ if( wearable->getDefinitionVersion() == 24 )
+ {
+ wearable->setDefinitionVersion(22);
+ U32 index = getWearableIndex(wearable);
llinfos << "forcing wearable type " << wearable->getType() << " to version 22 from 24" << llendl;
- saveWearable(wearable->getType(),index,TRUE);
- }
+ saveWearable(wearable->getType(),index,TRUE);
+ }
checkWearableAgainstInventory(viewer_wearable);
-}
+ }
}
BOOL LLAgentWearables::itemUpdatePending(const LLUUID& item_id) const
@@ -908,12 +904,12 @@ void LLAgentWearables::recoverMissingWearable(const LLWearableType::EType type,
// destory content.) JC
const LLUUID lost_and_found_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND);
LLPointer<LLInventoryCallback> cb =
- new addWearableToAgentInventoryCallback(
+ new AddWearableToAgentInventoryCallback(
LLPointer<LLRefCount>(NULL),
type,
index,
new_wearable,
- addWearableToAgentInventoryCallback::CALL_RECOVERDONE);
+ AddWearableToAgentInventoryCallback::CALL_RECOVERDONE);
addWearableToAgentInventory(cb, new_wearable, lost_and_found_id, TRUE);
}
@@ -956,17 +952,17 @@ public:
/* virtual */ void fire(const LLUUID& inv_item)
{
llinfos << "One item created " << inv_item.asString() << llendl;
- LLViewerInventoryItem *item = gInventory.getItem(inv_item);
- mItemsToLink.put(item);
+ LLConstPointer<LLInventoryObject> item = gInventory.getItem(inv_item);
+ mItemsToLink.push_back(item);
updatePendingWearable(inv_item);
}
~OnWearableItemCreatedCB()
{
llinfos << "All items created" << llendl;
LLPointer<LLInventoryCallback> link_waiter = new LLUpdateAppearanceOnDestroy;
- LLAppearanceMgr::instance().linkAll(LLAppearanceMgr::instance().getCOF(),
- mItemsToLink,
- link_waiter);
+ link_inventory_array(LLAppearanceMgr::instance().getCOF(),
+ mItemsToLink,
+ link_waiter);
}
void addPendingWearable(LLViewerWearable *wearable)
{
@@ -1015,7 +1011,7 @@ public:
}
private:
- LLInventoryModel::item_array_t mItemsToLink;
+ LLInventoryObject::const_object_list_t mItemsToLink;
std::vector<LLViewerWearable*> mWearablesAwaitingItems;
};
@@ -1234,30 +1230,86 @@ void LLAgentWearables::removeWearableFinal(const LLWearableType::EType type, boo
// Assumes existing wearables are not dirty.
void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& items,
- const LLDynamicArray< LLViewerWearable* >& wearables,
- BOOL remove)
+ const LLDynamicArray< LLViewerWearable* >& wearables)
{
llinfos << "setWearableOutfit() start" << llendl;
+ S32 count = wearables.count();
+ llassert(items.count() == count);
+
+ // Check for whether outfit already matches the one requested
+ S32 matched = 0, mismatched = 0;
+ const S32 arr_size = LLWearableType::WT_COUNT;
+ S32 type_counts[arr_size];
+ std::fill(type_counts,type_counts+arr_size,0);
+ for (S32 i = 0; i < count; i++)
+ {
+ LLViewerWearable* new_wearable = wearables[i];
+ LLPointer<LLInventoryItem> new_item = items[i];
+
+ const LLWearableType::EType type = new_wearable->getType();
+ if (type < 0 || type>=LLWearableType::WT_COUNT)
+ {
+ llwarns << "invalid type " << type << llendl;
+ mismatched++;
+ continue;
+ }
+ S32 index = type_counts[type];
+ type_counts[type]++;
+
+ LLViewerWearable *curr_wearable = dynamic_cast<LLViewerWearable*>(getWearable(type,index));
+ if (!new_wearable || !curr_wearable ||
+ new_wearable->getAssetID() != curr_wearable->getAssetID())
+ {
+ LL_DEBUGS("Avatar") << "mismatch, type " << type << " index " << index
+ << " names " << (curr_wearable ? curr_wearable->getName() : "NONE") << ","
+ << " names " << (new_wearable ? new_wearable->getName() : "NONE") << llendl;
+ mismatched++;
+ continue;
+ }
+
+ if (curr_wearable->getName() != new_item->getName() ||
+ curr_wearable->getItemID() != new_item->getUUID())
+ {
+ LL_DEBUGS("Avatar") << "mismatch on name or inventory id, names "
+ << curr_wearable->getName() << " vs " << new_item->getName()
+ << " item ids " << curr_wearable->getItemID() << " vs " << new_item->getUUID()
+ << llendl;
+ mismatched++;
+ continue;
+ }
+ // If we got here, everything matches.
+ matched++;
+ }
+ LL_DEBUGS("Avatar") << "matched " << matched << " mismatched " << mismatched << llendl;
+ for (S32 j=0; j<LLWearableType::WT_COUNT; j++)
+ {
+ LLWearableType::EType type = (LLWearableType::EType) j;
+ if (getWearableCount(type) != type_counts[j])
+ {
+ LL_DEBUGS("Avatar") << "count mismatch for type " << j << " current " << getWearableCount(j) << " requested " << type_counts[j] << llendl;
+ mismatched++;
+ }
+ }
+ if (mismatched == 0)
+ {
+ LL_DEBUGS("Avatar") << "no changes, bailing out" << llendl;
+ return;
+ }
+
+
// TODO: Removed check for ensuring that teens don't remove undershirt and underwear. Handle later
- if (remove)
+ // note: shirt is the first non-body part wearable item. Update if wearable order changes.
+ // This loop should remove all clothing, but not any body parts
+ for (S32 j = 0; j < (S32)LLWearableType::WT_COUNT; j++)
{
- // note: shirt is the first non-body part wearable item. Update if wearable order changes.
- // This loop should remove all clothing, but not any body parts
- for (S32 type = 0; type < (S32)LLWearableType::WT_COUNT; type++)
+ if (LLWearableType::getAssetType((LLWearableType::EType)j) == LLAssetType::AT_CLOTHING)
{
- if (LLWearableType::getAssetType((LLWearableType::EType)type) == LLAssetType::AT_CLOTHING)
- {
- removeWearable((LLWearableType::EType)type, true, 0);
- }
+ removeWearable((LLWearableType::EType)j, true, 0);
}
}
- S32 count = wearables.count();
- llassert(items.count() == count);
-
- S32 i;
- for (i = 0; i < count; i++)
+ for (S32 i = 0; i < count; i++)
{
LLViewerWearable* new_wearable = wearables[i];
LLPointer<LLInventoryItem> new_item = items[i];
@@ -1311,7 +1363,7 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it
gAgentAvatarp->dumpAvatarTEs("setWearableOutfit");
- lldebugs << "setWearableOutfit() end" << llendl;
+ LL_DEBUGS("Avatar") << "setWearableOutfit() end" << llendl;
}
@@ -1442,6 +1494,7 @@ void LLAgentWearables::queryWearableCache()
{
return;
}
+ gAgentAvatarp->setIsUsingServerBakes(false);
// Look up affected baked textures.
// If they exist:
@@ -1496,12 +1549,12 @@ void LLAgentWearables::queryWearableCache()
// virtual
void LLAgentWearables::invalidateBakedTextureHash(LLMD5& hash) const
{
- // Add some garbage into the hash so that it becomes invalid.
- if (isAgentAvatarValid())
- {
- hash.update((const unsigned char*)gAgentAvatarp->getID().mData, UUID_BYTES);
- }
- }
+ // Add some garbage into the hash so that it becomes invalid.
+ if (isAgentAvatarValid())
+ {
+ hash.update((const unsigned char*)gAgentAvatarp->getID().mData, UUID_BYTES);
+ }
+}
// User has picked "remove from avatar" from a menu.
// static
@@ -1860,24 +1913,6 @@ void LLAgentWearables::updateServer()
gAgent.sendAgentSetAppearance();
}
-void LLAgentWearables::populateMyOutfitsFolder(void)
-{
- llinfos << "starting outfit population" << llendl;
-
- const LLUUID& my_outfits_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS);
- LLLibraryOutfitsFetch* outfits = new LLLibraryOutfitsFetch(my_outfits_id);
- outfits->mMyOutfitsID = my_outfits_id;
-
- // Get the complete information on the items in the inventory and
- // setup an observer that will wait for that to happen.
- gInventory.addObserver(outfits);
- outfits->startFetch();
- if (outfits->isFinished())
- {
- outfits->done();
- }
-}
-
boost::signals2::connection LLAgentWearables::addLoadingStartedCallback(loading_started_callback_t cb)
{
return mLoadingStartedSignal.connect(cb);
@@ -1896,6 +1931,7 @@ bool LLAgentWearables::changeInProgress() const
void LLAgentWearables::notifyLoadingStarted()
{
mCOFChangeInProgress = true;
+ mCOFChangeTimer.reset();
mLoadingStartedSignal();
}