From 2caa710a46d3baa1e6a884961f1ff756d35ef5df Mon Sep 17 00:00:00 2001 From: "Nyx (Neal Orman)" Date: Thu, 3 Jun 2010 20:06:25 -0400 Subject: VWR-19699 WIP Correct operations for wear and replace on wearables Resident-submitted patch, cleaned up so it matches style and compiles/builds well. Appears to work for stated goals but will need some more UI work to ensure consistency. WIP checkin, will be code reviewed before pushing. --- indra/newview/llappearancemgr.cpp | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) (limited to 'indra/newview/llappearancemgr.cpp') diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index e6f363028a..5071b1c14a 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -656,15 +656,40 @@ bool LLAppearanceMgr::wearItemOnAvatar(const LLUUID& item_id_to_wear, bool do_up { if (item_id_to_wear.isNull()) return false; - //only the item from a user's inventory is allowed - if (!gInventory.isObjectDescendentOf(item_id_to_wear, gInventory.getRootFolderID())) return false; - LLViewerInventoryItem* item_to_wear = gInventory.getItem(item_id_to_wear); if (!item_to_wear) return false; + if (!item_to_wear->isFinished()) + { + LLNotificationsUtil::add("CannotWearInfoNotComplete"); + return false; + } + else if (gInventory.isObjectDescendentOf(item_to_wear->getUUID(), gInventory.getLibraryRootFolderID())) + { + LLPointer cb = new WearOnAvatarCallback(replace); + copy_inventory_item(gAgent.getID(), item_to_wear->getPermissions().getOwner(), item_to_wear->getUUID(), LLUUID::null, std::string(),cb); + return false; + } + else if (!gInventory.isObjectDescendentOf(item_to_wear->getUUID(), gInventory.getRootFolderID())) + { + return false; // not in library and not in agent's inventory + } + else if (gInventory.isObjectDescendentOf(item_to_wear->getUUID(), gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH))) + { + LLNotificationsUtil::add("CannotWearTrash"); + } + switch (item_to_wear->getType()) { case LLAssetType::AT_CLOTHING: + if (replace && gAgentWearables.areWearablesLoaded()) + { + S32 wearable_count = gAgentWearables.getWearableCount(item_to_wear->getWearableType()); + if (wearable_count != 0) + { + removeCOFItemLinks(gAgentWearables.getWearableItemID(item_to_wear->getWearableType(), wearable_count-1), false); + } + } case LLAssetType::AT_BODYPART: // Don't wear anything until initial wearables are loaded, can // destroy clothing items. @@ -676,7 +701,7 @@ bool LLAppearanceMgr::wearItemOnAvatar(const LLUUID& item_id_to_wear, bool do_up // 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 (replace || item_to_wear->getType() == LLAssetType::AT_BODYPART) + if (item_to_wear->getType() == LLAssetType::AT_BODYPART) { removeCOFLinksOfType(item_to_wear->getWearableType(), false); } -- cgit v1.2.3 From 47beb6dc9c4f7c1557536f8116cc98b8bbc24629 Mon Sep 17 00:00:00 2001 From: "Nyx (Neal Orman)" Date: Thu, 3 Jun 2010 21:09:49 -0400 Subject: AVP-44 WIP Multi-wearables architecture One step closer to full support of multi-wearables architecture code will be reviewed before pushing. --- indra/newview/llappearancemgr.cpp | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) (limited to 'indra/newview/llappearancemgr.cpp') diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 5071b1c14a..9da47c9214 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -682,14 +682,15 @@ bool LLAppearanceMgr::wearItemOnAvatar(const LLUUID& item_id_to_wear, bool do_up switch (item_to_wear->getType()) { case LLAssetType::AT_CLOTHING: - if (replace && gAgentWearables.areWearablesLoaded()) + if (gAgentWearables.areWearablesLoaded()) { S32 wearable_count = gAgentWearables.getWearableCount(item_to_wear->getWearableType()); - if (wearable_count != 0) + if ((replace && wearable_count != 0) || + (wearable_count >= LLAgentWearables::MAX_CLOTHING_PER_TYPE) ) { removeCOFItemLinks(gAgentWearables.getWearableItemID(item_to_wear->getWearableType(), wearable_count-1), false); } - } + } case LLAssetType::AT_BODYPART: // Don't wear anything until initial wearables are loaded, can // destroy clothing items. @@ -1584,6 +1585,7 @@ void LLAppearanceMgr::addCOFItemLink(const LLInventoryItem *item, bool do_update item_array, LLInventoryModel::EXCLUDE_TRASH); bool linked_already = false; + U32 count = 0; for (S32 i=0; iisWearableType()) && (vitem->getWearableType() == wearable_type)) + else if ((vitem->isWearableType()) && (vitem->getWearableType() == wearable_type)) { - if (inv_item->getIsLinkType() && (vitem->getWearableType() == wearable_type)) + if (is_body_part && inv_item->getIsLinkType() && (vitem->getWearableType() == wearable_type)) + { + gInventory.purgeObject(inv_item->getUUID()); + } + ++count; + + // MULTI-WEARABLES: make sure we don't go over MAX_CLOTHING_PER_TYPE + if (count >= LLAgentWearables::MAX_CLOTHING_PER_TYPE) { gInventory.purgeObject(inv_item->getUUID()); } } } + if (linked_already) { if (do_update) -- cgit v1.2.3 From 244321e70cf341ca0542a9963d9e1e68cafca8d5 Mon Sep 17 00:00:00 2001 From: "Nyx (Neal Orman)" Date: Fri, 4 Jun 2010 17:34:46 -0400 Subject: AVP-44 VWR-19699 FIX Multi-wearables and wearable replacement logic Cleaned up a few things upon code review. Code reviewed by vir for this checkin as well as following previous commits: a801af3728ee af42810b946c --- indra/newview/llappearancemgr.cpp | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) (limited to 'indra/newview/llappearancemgr.cpp') diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 9da47c9214..a899926938 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -659,12 +659,7 @@ bool LLAppearanceMgr::wearItemOnAvatar(const LLUUID& item_id_to_wear, bool do_up LLViewerInventoryItem* item_to_wear = gInventory.getItem(item_id_to_wear); if (!item_to_wear) return false; - if (!item_to_wear->isFinished()) - { - LLNotificationsUtil::add("CannotWearInfoNotComplete"); - return false; - } - else if (gInventory.isObjectDescendentOf(item_to_wear->getUUID(), gInventory.getLibraryRootFolderID())) + if (gInventory.isObjectDescendentOf(item_to_wear->getUUID(), gInventory.getLibraryRootFolderID())) { LLPointer cb = new WearOnAvatarCallback(replace); copy_inventory_item(gAgent.getID(), item_to_wear->getPermissions().getOwner(), item_to_wear->getUUID(), LLUUID::null, std::string(),cb); @@ -677,6 +672,7 @@ bool LLAppearanceMgr::wearItemOnAvatar(const LLUUID& item_id_to_wear, bool do_up else if (gInventory.isObjectDescendentOf(item_to_wear->getUUID(), gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH))) { LLNotificationsUtil::add("CannotWearTrash"); + return false; } switch (item_to_wear->getType()) @@ -1605,15 +1601,14 @@ void LLAppearanceMgr::addCOFItemLink(const LLInventoryItem *item, bool do_update // type? If so, new item will replace old. else if ((vitem->isWearableType()) && (vitem->getWearableType() == wearable_type)) { + ++count; if (is_body_part && inv_item->getIsLinkType() && (vitem->getWearableType() == wearable_type)) { gInventory.purgeObject(inv_item->getUUID()); } - ++count; - - // MULTI-WEARABLES: make sure we don't go over MAX_CLOTHING_PER_TYPE - if (count >= LLAgentWearables::MAX_CLOTHING_PER_TYPE) + else if (count >= LLAgentWearables::MAX_CLOTHING_PER_TYPE) { + // MULTI-WEARABLES: make sure we don't go over MAX_CLOTHING_PER_TYPE gInventory.purgeObject(inv_item->getUUID()); } } -- cgit v1.2.3 From 50eb27a04d193ef145f8879e12d8a82089a66891 Mon Sep 17 00:00:00 2001 From: Alexei Arabadji Date: Tue, 8 Jun 2010 15:36:48 +0300 Subject: EXT-7644 FIXED Implemented functionality for locking outfit modification controls and used it for 'save outfit' action. 1 Added functionality for locking outfit in LLAppearanceMgr. Outfit should be locked when outfit related operation is started(now it is used for updateBaseOutfit) and unlocked when operation completed or timeout is exceeded. 2 Added outfit saved and outfit lock changed signals to LLOutfitObserver. 3 Updated LLPanelOutfitsInventory and LLPanelOutfitEdit with functionality of controlling 'save outfit' controls state('save outfit' controls should be enabled only if outfit isn't locked and outfit is dirty). 4 Renamed action label of method LLPanelOutfitsInventory::isActionEnabled "make_outfit" to "save_outfit". --HG-- branch : product-engine --- indra/newview/llappearancemgr.cpp | 67 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) (limited to 'indra/newview/llappearancemgr.cpp') diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index a899926938..135629bb8d 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -38,11 +38,13 @@ #include "llagentwearables.h" #include "llappearancemgr.h" #include "llcommandhandler.h" +#include "lleventtimer.h" #include "llgesturemgr.h" #include "llinventorybridge.h" #include "llinventoryfunctions.h" #include "llinventoryobserver.h" #include "llnotificationsutil.h" +#include "lloutfitobserver.h" #include "llpaneloutfitsinventory.h" #include "llselectmgr.h" #include "llsidepanelappearance.h" @@ -55,6 +57,34 @@ char ORDER_NUMBER_SEPARATOR('@'); +class LLOutfitUnLockTimer: public LLEventTimer +{ +public: + LLOutfitUnLockTimer(F32 period) : LLEventTimer(period) + { + // restart timer on BOF changed event + LLOutfitObserver::instance().addBOFChangedCallback(boost::bind( + &LLOutfitUnLockTimer::reset, this)); + stop(); + } + + /*virtual*/ + BOOL tick() + { + if(mEventTimer.hasExpired()) + { + LLAppearanceMgr::instance().setOutfitLocked(false); + } + return FALSE; + } + void stop() { mEventTimer.stop(); } + void start() { mEventTimer.start(); } + void reset() { mEventTimer.reset(); } + BOOL getStarted() { return mEventTimer.getStarted(); } + + LLTimer& getEventTimer() { return mEventTimer;} +}; + // support for secondlife:///app/appearance SLapps class LLAppearanceHandler : public LLCommandHandler { @@ -762,6 +792,27 @@ void LLAppearanceMgr::onOutfitRename(const LLSD& notification, const LLSD& respo } } +void LLAppearanceMgr::setOutfitLocked(bool locked) +{ + if (mOutfitLocked == locked) + { + return; + } + + mOutfitLocked = locked; + if (locked) + { + mUnlockOutfitTimer->reset(); + mUnlockOutfitTimer->start(); + } + else + { + mUnlockOutfitTimer->stop(); + } + + LLOutfitObserver::instance().notifyOutfitLockChanged(); +} + void LLAppearanceMgr::addCategoryToCurrentOutfit(const LLUUID& cat_id) { LLViewerInventoryCategory* cat = gInventory.getCategory(cat_id); @@ -1810,6 +1861,14 @@ void LLAppearanceMgr::onFirstFullyVisible() bool LLAppearanceMgr::updateBaseOutfit() { + if (isOutfitLocked()) + { + // don't allow modify locked outfit + llassert(!isOutfitLocked()); + return false; + } + setOutfitLocked(true); + const LLUUID base_outfit_id = getBaseOutfitUUID(); if (base_outfit_id.isNull()) return false; @@ -2138,6 +2197,14 @@ LLAppearanceMgr::LLAppearanceMgr(): mAttachmentInvLinkEnabled(false), mOutfitIsDirty(false) { + LLOutfitObserver& outfit_observer = LLOutfitObserver::instance(); + + // unlock outfit on save operation completed + outfit_observer.addCOFSavedCallback(boost::bind( + &LLAppearanceMgr::setOutfitLocked, this, false)); + + mUnlockOutfitTimer.reset(new LLOutfitUnLockTimer(gSavedSettings.getS32( + "OutfitOperationsTimeout"))); } LLAppearanceMgr::~LLAppearanceMgr() -- cgit v1.2.3 From 56da8017d9622e092947b504813d8a40d21310a6 Mon Sep 17 00:00:00 2001 From: Leyla Farazha Date: Tue, 8 Jun 2010 14:52:22 -0700 Subject: EXT-7210 Baked textures should only be updated when outfit changes are saved or outfit editor is exited. reviewed and contributed to by Nyx --- indra/newview/llappearancemgr.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/newview/llappearancemgr.cpp') diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 135629bb8d..12d2752180 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -2139,7 +2139,7 @@ bool LLAppearanceMgr::moveWearable(LLViewerInventoryItem* item, bool closer_to_b bool result = false; if (result = gAgentWearables.moveWearable(item, closer_to_body)) { - gAgentAvatarp->wearableUpdated(item->getWearableType(), TRUE); + gAgentAvatarp->wearableUpdated(item->getWearableType(), FALSE); } setOutfitDirty(true); -- cgit v1.2.3 From 47211f0ed5c9dab26c512e59b0d8f54e9018f548 Mon Sep 17 00:00:00 2001 From: Vadim Savchuk Date: Fri, 11 Jun 2010 18:22:00 +0300 Subject: EXT-7716 FIXED Allowed removing an outfit containing links to worn wearables. Removed a redundant check disallowing removal of an outfit containing links to worn items. So now we use the same condition as in the inventory panel. Note that if an outfit that you're trying to remove contains originals of currently worn items, we still disallow removal. Reviewed by Mike Antipov at https://codereview.productengine.com/secondlife/r/559/ --HG-- branch : product-engine --- indra/newview/llappearancemgr.cpp | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) (limited to 'indra/newview/llappearancemgr.cpp') diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 12d2752180..3691d731ed 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -965,18 +965,10 @@ bool LLAppearanceMgr::getCanRemoveOutfit(const LLUUID& outfit_cat_id) return false; } - // Check if the folder contains worn items. - LLInventoryModel::cat_array_t cats; - LLInventoryModel::item_array_t items; - LLFindWorn filter_worn; - gInventory.collectDescendentsIf(outfit_cat_id, cats, items, false, filter_worn); - if (!items.empty()) - { - return false; - } - // Check for the folder's non-removable descendants. LLFindNonRemovableObjects filter_non_removable; + LLInventoryModel::cat_array_t cats; + LLInventoryModel::item_array_t items; LLInventoryModel::item_array_t::const_iterator it; gInventory.collectDescendentsIf(outfit_cat_id, cats, items, false, filter_non_removable); if (!cats.empty() || !items.empty()) -- cgit v1.2.3 From 17520c17b1eff7b26d264c8b6bd1f8ebbbde8d15 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Fri, 11 Jun 2010 08:26:18 -0400 Subject: EXT-6571 WIP - adding ability to handle late-arriving assets --- indra/newview/llappearancemgr.cpp | 131 ++++++++++++++++++++++++++++++-------- 1 file changed, 105 insertions(+), 26 deletions(-) (limited to 'indra/newview/llappearancemgr.cpp') diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index a899926938..28a0ba8817 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -223,8 +223,16 @@ public: void onWearableAssetFetch(LLWearable *wearable); void onAllComplete(); - + typedef std::list 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 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 found_by_type(LLWearableType::WT_COUNT,0); std::vector 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 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; -- cgit v1.2.3 From 5777824df41956fbb1c4592c08ce693f28182fdc Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Fri, 11 Jun 2010 18:08:59 -0400 Subject: EXT-6571 WIP - partial handling of late arriving assets --- indra/newview/llappearancemgr.cpp | 128 +++++++++++++++++++++++++++++++++----- 1 file changed, 111 insertions(+), 17 deletions(-) (limited to 'indra/newview/llappearancemgr.cpp') diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 1c2bdf07df..c19b3b50c1 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -261,6 +261,7 @@ public: void setObjItems(const LLInventoryModel::item_array_t& items); void setGestItems(const LLInventoryModel::item_array_t& items); bool isValid(); + void handleLateArrivals(); private: found_list_t mFoundList; @@ -275,6 +276,8 @@ private: typedef std::set type_set_hp; static type_set_hp sActiveHoldingPatterns; bool mIsValid; + std::set mLateArrivals; + bool mIsAllComplete; }; LLWearableHoldingPattern::type_set_hp LLWearableHoldingPattern::sActiveHoldingPatterns; @@ -282,7 +285,8 @@ LLWearableHoldingPattern::type_set_hp LLWearableHoldingPattern::sActiveHoldingPa LLWearableHoldingPattern::LLWearableHoldingPattern(): mResolved(0), mFired(false), - mIsValid(true) + mIsValid(true), + mIsAllComplete(false) { if (sActiveHoldingPatterns.size()>0) { @@ -350,7 +354,10 @@ bool LLWearableHoldingPattern::isTimedOut() void LLWearableHoldingPattern::checkMissingWearables() { - llassert(isValid()); // TODO: handle not valid case + if (!isValid()) + { + llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; + } std::vector found_by_type(LLWearableType::WT_COUNT,0); std::vector requested_by_type(LLWearableType::WT_COUNT,0); @@ -394,7 +401,10 @@ void LLWearableHoldingPattern::checkMissingWearables() void LLWearableHoldingPattern::onAllComplete() { - llassert(isValid()); // TODO: handle not valid case + if (!isValid()) + { + llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; + } // Activate all gestures in this folder if (mGestItems.count() > 0) @@ -431,11 +441,19 @@ void LLWearableHoldingPattern::onAllComplete() // Only safe to delete if all wearable callbacks and all missing wearables completed. delete this; } + else + { + mIsAllComplete = true; + handleLateArrivals(); + } } void LLWearableHoldingPattern::onFetchCompletion() { - llassert(isValid()); // TODO: handle not valid case + if (!isValid()) + { + llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; + } checkMissingWearables(); } @@ -443,7 +461,10 @@ void LLWearableHoldingPattern::onFetchCompletion() // Runs as an idle callback until all wearables are fetched (or we time out). bool LLWearableHoldingPattern::pollFetchCompletion() { - llassert(isValid()); // TODO: handle not valid case + if (!isValid()) + { + llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; + } bool completed = isFetchCompleted(); bool timed_out = isTimedOut(); @@ -477,7 +498,10 @@ public: } void fire(const LLUUID& item_id) { - llassert(mHolder->isValid()); // TODO: handle not valid case + if (!mHolder->isValid()) + { + llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; + } llinfos << "Recovered item link for type " << mType << llendl; mHolder->eraseTypeToLink(mType); @@ -492,11 +516,11 @@ public: if (item) { LLFoundData found(linked_item->getUUID(), - linked_item->getAssetUUID(), - linked_item->getName(), - linked_item->getType(), - linked_item->isWearableType() ? linked_item->getWearableType() : LLWearableType::WT_INVALID - ); + linked_item->getAssetUUID(), + linked_item->getName(), + linked_item->getType(), + linked_item->isWearableType() ? linked_item->getWearableType() : LLWearableType::WT_INVALID + ); found.mWearable = mWearable; mHolder->getFoundList().push_front(found); } @@ -527,7 +551,10 @@ public: } void fire(const LLUUID& item_id) { - llassert(mHolder->isValid()); // TODO: handle not valid case + if (!mHolder->isValid()) + { + llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; + } llinfos << "Recovered item for type " << mType << llendl; LLViewerInventoryItem *itemp = gInventory.getItem(item_id); @@ -554,7 +581,10 @@ private: void LLWearableHoldingPattern::recoverMissingWearable(LLWearableType::EType type) { - llassert(isValid()); // TODO: handle not valid case + if (!isValid()) + { + llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; + } // Try to recover by replacing missing wearable with a new one. LLNotificationsUtil::add("ReplacedMissingWearable"); @@ -600,7 +630,10 @@ void LLWearableHoldingPattern::clearCOFLinksForMissingWearables() bool LLWearableHoldingPattern::pollMissingWearables() { - llassert(isValid()); // TODO: handle not valid case + if (!isValid()) + { + llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; + } bool timed_out = isTimedOut(); bool missing_completed = isMissingCompleted(); @@ -621,9 +654,63 @@ bool LLWearableHoldingPattern::pollMissingWearables() return done; } +// Handle wearables that arrived after the timeout period expired. +void LLWearableHoldingPattern::handleLateArrivals() +{ + // Only safe to run if we have previously finished the missing + // wearables and other processing - otherwise we could be in some + // intermediate state - but have not been superceded by a later + // outfit change request. + if (mLateArrivals.size() == 0) + { + // Nothing to process. + return; + } + if (!isValid()) + { + llwarns << "Late arrivals not handled - outfit change no longer valid" << llendl; + } + if (!mIsAllComplete) + { + llwarns << "Late arrivals not handled - in middle of missing wearables processing" << llendl; + } + + llinfos << "Need to handle " << mLateArrivals.size() << " late arriving wearables" << llendl; + + // Update mFoundList using late-arriving wearables. + for (LLWearableHoldingPattern::found_list_t::iterator iter = getFoundList().begin(); + iter != getFoundList().end(); ++iter) + { + LLFoundData& data = *iter; + for (std::set::iterator wear_it = mLateArrivals.begin(); + wear_it != mLateArrivals.end(); + ++wear_it) + { + LLWearable *wearable = *wear_it; + + if(wearable->getAssetID() == data.mAssetID) + { + data.mWearable = wearable; + // BAP 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; + } + } + } + + // TODO: handle corresponding default wearable links? + + // Update appearance based on mFoundList + LLAppearanceMgr::instance().updateAgentWearables(this, false); +} + void LLWearableHoldingPattern::onWearableAssetFetch(LLWearable *wearable) { - llassert(isValid()); // TODO: handle not valid case + if (!isValid()) + { + llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; + } mResolved += 1; // just counting callbacks, not successes. llinfos << "onWearableAssetFetch, resolved count " << mResolved << " of requested " << getFoundList().size() << llendl; @@ -639,6 +726,14 @@ void LLWearableHoldingPattern::onWearableAssetFetch(LLWearable *wearable) if (mFired) { llwarns << "called after holder fired" << llendl; + if (wearable) + { + mLateArrivals.insert(wearable); + if (mIsAllComplete) + { + handleLateArrivals(); + } + } return; } @@ -1269,8 +1364,7 @@ void LLAppearanceMgr::updateAgentWearables(LLWearableHoldingPattern* holder, boo LLInventoryItem::item_array_t items; LLDynamicArray< LLWearable* > wearables; - // For each wearable type, find the first instance in the category - // that we recursed through. + // For each wearable type, find the wearables of that type. for( S32 i = 0; i < LLWearableType::WT_COUNT; i++ ) { for (LLWearableHoldingPattern::found_list_t::iterator iter = holder->getFoundList().begin(); -- cgit v1.2.3 From 664a07dd8d034a729992994ae1c29f47ad32d8f1 Mon Sep 17 00:00:00 2001 From: Yuri Chebotarev Date: Mon, 14 Jun 2010 14:59:56 +0300 Subject: EXT-7727 FIX reset sidetray tab to home_tab when login is complete. Aslo add parameter to callback to prevent showing appearance panel when creating initial outfit - _sometimes_ this callback was called _after_ login was finished. rewieved by Mike Antipov at https://codereview.productengine.com/secondlife/r/574/ --HG-- branch : product-engine --- indra/newview/llappearancemgr.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'indra/newview/llappearancemgr.cpp') diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 3691d731ed..dba8707423 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -1992,13 +1992,19 @@ void LLAppearanceMgr::updateClothingOrderingInfo(LLUUID cat_id) class LLShowCreatedOutfit: public LLInventoryCallback { public: - LLShowCreatedOutfit(LLUUID& folder_id): mFolderID(folder_id) + LLShowCreatedOutfit(LLUUID& folder_id, bool show_panel = true): mFolderID(folder_id), mShowPanel(show_panel) {} virtual ~LLShowCreatedOutfit() { LLSD key; - LLSideTray::getInstance()->showPanel("panel_outfits_inventory", key); + + //EXT-7727. For new accounts LLShowCreatedOutfit is created during login process + // add may be processed after login process is finished + if (mShowPanel) + { + LLSideTray::getInstance()->showPanel("panel_outfits_inventory", key); + } LLPanelOutfitsInventory *outfit_panel = dynamic_cast(LLSideTray::getInstance()->getPanel("panel_outfits_inventory")); if (outfit_panel) @@ -2022,9 +2028,10 @@ public: private: LLUUID mFolderID; + bool mShowPanel; }; -LLUUID LLAppearanceMgr::makeNewOutfitLinks(const std::string& new_folder_name) +LLUUID LLAppearanceMgr::makeNewOutfitLinks(const std::string& new_folder_name, bool show_panel) { if (!isAgentAvatarValid()) return LLUUID::null; @@ -2037,7 +2044,7 @@ LLUUID LLAppearanceMgr::makeNewOutfitLinks(const std::string& new_folder_name) updateClothingOrderingInfo(); - LLPointer cb = new LLShowCreatedOutfit(folder_id); + LLPointer cb = new LLShowCreatedOutfit(folder_id,show_panel); shallowCopyCategoryContents(getCOF(),folder_id, cb); createBaseOutfitLink(folder_id, cb); -- cgit v1.2.3 From 0ec92fb1c8a90d619d0102d0807a32abedc916f1 Mon Sep 17 00:00:00 2001 From: Alexei Arabadji Date: Mon, 14 Jun 2010 16:12:20 +0300 Subject: EXT-7783 FIXED Provided updating outfit label in My outfits and Edit outfit panels. 1 Corrected LLAppearanceMgr::getBaseOutfitLink() method to avoid returning link in case base outfit moved to trash. 2 Hooked up LLSidepanelAppearance::refreshCurrentOutfitName() method on BOFReplaced signal. reviewed by Mike Antipov at https://codereview.productengine.com/secondlife/r/571/ --HG-- branch : product-engine --- indra/newview/llappearancemgr.cpp | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'indra/newview/llappearancemgr.cpp') diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index dba8707423..bc17605202 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -644,6 +644,13 @@ const LLViewerInventoryItem* LLAppearanceMgr::getBaseOutfitLink() const LLViewerInventoryCategory *cat = item->getLinkedCategory(); if (cat && cat->getPreferredType() == LLFolderType::FT_OUTFIT) { + const LLUUID parent_id = cat->getParentUUID(); + LLViewerInventoryCategory* parent_cat = gInventory.getCategory(parent_id); + // if base outfit moved to trash it means that we don't have base outfit + if (parent_cat != NULL && parent_cat->getPreferredType() == LLFolderType::FT_TRASH) + { + return NULL; + } return item; } } -- cgit v1.2.3 From 8364708595a87e426bf348826698e674976b9e00 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Mon, 14 Jun 2010 13:15:58 -0400 Subject: EXT-6571 WIP - basic handling of late arriving assets --- indra/newview/llappearancemgr.cpp | 43 +++++++++++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 4 deletions(-) (limited to 'indra/newview/llappearancemgr.cpp') diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index c19b3b50c1..a164cfeaa1 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -216,13 +216,15 @@ struct LLFoundData const LLUUID& asset_id, const std::string& name, const LLAssetType::EType& asset_type, - const LLWearableType::EType& wearable_type + const LLWearableType::EType& wearable_type, + const bool is_replacement = false ) : mItemID(item_id), mAssetID(asset_id), mName(name), mAssetType(asset_type), mWearableType(wearable_type), + mIsReplacement(is_replacement), mWearable( NULL ) {} LLUUID mItemID; @@ -231,6 +233,7 @@ struct LLFoundData LLAssetType::EType mAssetType; LLWearableType::EType mWearableType; LLWearable* mWearable; + bool mIsReplacement; }; @@ -519,7 +522,8 @@ public: linked_item->getAssetUUID(), linked_item->getName(), linked_item->getType(), - linked_item->isWearableType() ? linked_item->getWearableType() : LLWearableType::WT_INVALID + linked_item->isWearableType() ? linked_item->getWearableType() : LLWearableType::WT_INVALID, + true // is replacement ); found.mWearable = mWearable; mHolder->getFoundList().push_front(found); @@ -678,6 +682,7 @@ void LLWearableHoldingPattern::handleLateArrivals() llinfos << "Need to handle " << mLateArrivals.size() << " late arriving wearables" << llendl; // Update mFoundList using late-arriving wearables. + std::set replaced_types; for (LLWearableHoldingPattern::found_list_t::iterator iter = getFoundList().begin(); iter != getFoundList().end(); ++iter) { @@ -687,10 +692,15 @@ void LLWearableHoldingPattern::handleLateArrivals() ++wear_it) { LLWearable *wearable = *wear_it; - + if(wearable->getAssetID() == data.mAssetID) { data.mWearable = wearable; + + replaced_types.insert(data.mWearableType); + + LLAppearanceMgr::instance().addCOFItemLink(data.mItemID,false); + // BAP 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)); @@ -699,7 +709,32 @@ void LLWearableHoldingPattern::handleLateArrivals() } } - // TODO: handle corresponding default wearable links? + // Remove COF links for any default wearables previously used to replace the late arrivals. + // All this pussyfooting around with a while loop and explicit + // iterator incrementing is to allow removing items from the list + // without clobbering the iterator we're using to navigate. + LLWearableHoldingPattern::found_list_t::iterator iter = getFoundList().begin(); + while (iter != getFoundList().end()) + { + LLFoundData& data = *iter; + + // If an item of this type has recently shown up, removed the corresponding replacement wearable from COF. + if (data.mWearable && data.mIsReplacement && + replaced_types.find(data.mWearableType) != replaced_types.end()) + { + LLAppearanceMgr::instance().removeCOFItemLinks(data.mItemID); + std::list::iterator clobber_ator = iter; + ++iter; + getFoundList().erase(clobber_ator); + } + else + { + ++iter; + } + } + + // Clear contents of late arrivals. + mLateArrivals.clear(); // Update appearance based on mFoundList LLAppearanceMgr::instance().updateAgentWearables(this, false); -- cgit v1.2.3 From 961656863a5e50e5f80e1e316811b884dd8a949f Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Mon, 14 Jun 2010 17:19:40 -0400 Subject: EXT-6571 WIP - fixes for handling of late arriving assets --- indra/newview/llappearancemgr.cpp | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'indra/newview/llappearancemgr.cpp') diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index a164cfeaa1..e54b9fe2ea 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -265,6 +265,7 @@ public: void setGestItems(const LLInventoryModel::item_array_t& items); bool isValid(); void handleLateArrivals(); + void resetTime(F32 timeout); private: found_list_t mFoundList; @@ -351,8 +352,7 @@ bool LLWearableHoldingPattern::isFetchCompleted() bool LLWearableHoldingPattern::isTimedOut() { - 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; + return mWaitTime.hasExpired(); } void LLWearableHoldingPattern::checkMissingWearables() @@ -395,7 +395,7 @@ void LLWearableHoldingPattern::checkMissingWearables() } } - mWaitTime.reset(); + resetTime(60.0F); if (!pollMissingWearables()) { doOnIdleRepeating(boost::bind(&LLWearableHoldingPattern::pollMissingWearables,this)); @@ -722,7 +722,7 @@ void LLWearableHoldingPattern::handleLateArrivals() if (data.mWearable && data.mIsReplacement && replaced_types.find(data.mWearableType) != replaced_types.end()) { - LLAppearanceMgr::instance().removeCOFItemLinks(data.mItemID); + LLAppearanceMgr::instance().removeCOFItemLinks(data.mItemID,false); std::list::iterator clobber_ator = iter; ++iter; getFoundList().erase(clobber_ator); @@ -740,6 +740,12 @@ void LLWearableHoldingPattern::handleLateArrivals() LLAppearanceMgr::instance().updateAgentWearables(this, false); } +void LLWearableHoldingPattern::resetTime(F32 timeout) +{ + mWaitTime.reset(); + mWaitTime.setTimerExpirySec(timeout); +} + void LLWearableHoldingPattern::onWearableAssetFetch(LLWearable *wearable) { if (!isValid()) @@ -1522,7 +1528,7 @@ void LLAppearanceMgr::updateAppearanceFromCOF() linked_item->isWearableType() ? linked_item->getWearableType() : LLWearableType::WT_INVALID ); - if (skip_type != LLWearableType::WT_INVALID && found.mWearableType == skip_type) + if (skip_type != LLWearableType::WT_INVALID && skip_type == found.mWearableType) { found.mAssetID.generate(); // Replace with new UUID, guaranteed not to exist in DB } @@ -1558,6 +1564,7 @@ void LLAppearanceMgr::updateAppearanceFromCOF() } + holder->resetTime(gSavedSettings.getF32("MaxWearableWaitTime")); if (!holder->pollFetchCompletion()) { doOnIdleRepeating(boost::bind(&LLWearableHoldingPattern::pollFetchCompletion,holder)); -- cgit v1.2.3 From 300cb342919b2bfa62e9c90af5cdb99afa9c962e Mon Sep 17 00:00:00 2001 From: Mike Antipov Date: Tue, 15 Jun 2010 12:38:30 +0300 Subject: EXT-7794 FIXED Implemented a common-used notification about wearing outfit to display loading indicator. Details: * Added signal "Wearable Loading Started" in AgentWearables (in parallel with "Wearables Loaded") * Now it is raised from the LLAppearanceMgr::wearInventoryCategory. Reviewed by Vadim Savchuk and Neal Orman at https://codereview.productengine.com/secondlife/r/583/ --HG-- branch : product-engine --- indra/newview/llappearancemgr.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'indra/newview/llappearancemgr.cpp') diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index bc17605202..a7206095d3 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -1407,6 +1407,7 @@ void LLAppearanceMgr::getUserDescendents(const LLUUID& category, void LLAppearanceMgr::wearInventoryCategory(LLInventoryCategory* category, bool copy, bool append) { + gAgentWearables.notifyLoadingStarted(); if(!category) return; llinfos << "wearInventoryCategory( " << category->getName() -- cgit v1.2.3 From 9b014886b0062a0d2c3ac9aa4a3cf3eb6a6488be Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Tue, 15 Jun 2010 14:36:32 -0400 Subject: merge --- indra/newview/llappearancemgr.cpp | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) (limited to 'indra/newview/llappearancemgr.cpp') diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 582c20c13f..d60db17d82 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -263,7 +263,7 @@ public: void eraseTypeToRecover(LLWearableType::EType type); void setObjItems(const LLInventoryModel::item_array_t& items); void setGestItems(const LLInventoryModel::item_array_t& items); - bool isValid(); + bool isMostRecent(); void handleLateArrivals(); void resetTime(F32 timeout); @@ -279,7 +279,7 @@ private: bool mFired; typedef std::set type_set_hp; static type_set_hp sActiveHoldingPatterns; - bool mIsValid; + bool mIsMostRecent; std::set mLateArrivals; bool mIsAllComplete; }; @@ -289,7 +289,7 @@ LLWearableHoldingPattern::type_set_hp LLWearableHoldingPattern::sActiveHoldingPa LLWearableHoldingPattern::LLWearableHoldingPattern(): mResolved(0), mFired(false), - mIsValid(true), + mIsMostRecent(true), mIsAllComplete(false) { if (sActiveHoldingPatterns.size()>0) @@ -303,7 +303,7 @@ LLWearableHoldingPattern::LLWearableHoldingPattern(): it != sActiveHoldingPatterns.end(); ++it) { - (*it)->mIsValid = false; + (*it)->mIsMostRecent = false; } } @@ -315,9 +315,9 @@ LLWearableHoldingPattern::~LLWearableHoldingPattern() sActiveHoldingPatterns.erase(this); } -bool LLWearableHoldingPattern::isValid() +bool LLWearableHoldingPattern::isMostRecent() { - return mIsValid; + return mIsMostRecent; } LLWearableHoldingPattern::found_list_t& LLWearableHoldingPattern::getFoundList() @@ -357,7 +357,7 @@ bool LLWearableHoldingPattern::isTimedOut() void LLWearableHoldingPattern::checkMissingWearables() { - if (!isValid()) + if (!isMostRecent()) { llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; } @@ -404,7 +404,7 @@ void LLWearableHoldingPattern::checkMissingWearables() void LLWearableHoldingPattern::onAllComplete() { - if (!isValid()) + if (!isMostRecent()) { llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; } @@ -453,7 +453,7 @@ void LLWearableHoldingPattern::onAllComplete() void LLWearableHoldingPattern::onFetchCompletion() { - if (!isValid()) + if (!isMostRecent()) { llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; } @@ -464,7 +464,7 @@ void LLWearableHoldingPattern::onFetchCompletion() // Runs as an idle callback until all wearables are fetched (or we time out). bool LLWearableHoldingPattern::pollFetchCompletion() { - if (!isValid()) + if (!isMostRecent()) { llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; } @@ -501,7 +501,7 @@ public: } void fire(const LLUUID& item_id) { - if (!mHolder->isValid()) + if (!mHolder->isMostRecent()) { llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; } @@ -555,7 +555,7 @@ public: } void fire(const LLUUID& item_id) { - if (!mHolder->isValid()) + if (!mHolder->isMostRecent()) { llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; } @@ -585,7 +585,7 @@ private: void LLWearableHoldingPattern::recoverMissingWearable(LLWearableType::EType type) { - if (!isValid()) + if (!isMostRecent()) { llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; } @@ -634,7 +634,7 @@ void LLWearableHoldingPattern::clearCOFLinksForMissingWearables() bool LLWearableHoldingPattern::pollMissingWearables() { - if (!isValid()) + if (!isMostRecent()) { llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; } @@ -670,7 +670,7 @@ void LLWearableHoldingPattern::handleLateArrivals() // Nothing to process. return; } - if (!isValid()) + if (!isMostRecent()) { llwarns << "Late arrivals not handled - outfit change no longer valid" << llendl; } @@ -748,7 +748,7 @@ void LLWearableHoldingPattern::resetTime(F32 timeout) void LLWearableHoldingPattern::onWearableAssetFetch(LLWearable *wearable) { - if (!isValid()) + if (!isMostRecent()) { llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; } -- cgit v1.2.3 From 0be5ce0a595ee582ee2bb7a0091e0424f908ddea Mon Sep 17 00:00:00 2001 From: Loren Shih Date: Tue, 15 Jun 2010 17:11:01 -0400 Subject: EXT-7468 FIXED Remove all 2.1 COF debugging code #ifdef'd a bunch of llinfos spam to not show up in release mode. Removed some other legacy comments. --- indra/newview/llappearancemgr.cpp | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) (limited to 'indra/newview/llappearancemgr.cpp') diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index d60db17d82..3c267b3308 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -1283,8 +1283,9 @@ void LLAppearanceMgr::linkAll(const LLUUID& cat_uuid, const LLViewerInventoryCategory *cat = gInventory.getCategory(cat_uuid); const std::string cat_name = cat ? cat->getName() : "CAT NOT FOUND"; - - llinfos << "Linking Item [ name:" << item->getName() << " UUID:" << item->getUUID() << " ] to Category [ name:" << cat_name << " UUID:" << cat_uuid << " ] " << llendl; // Seraph remove for 2.1 +#ifndef LL_RELEASE_FOR_DOWNLOAD + llinfos << "Linking Item [ name:" << item->getName() << " UUID:" << item->getUUID() << " ] to Category [ name:" << cat_name << " UUID:" << cat_uuid << " ] " << llendl; +#endif } } @@ -1353,13 +1354,24 @@ void LLAppearanceMgr::updateCOF(const LLUUID& category, bool append) llinfos << "creating LLUpdateAppearanceOnDestroy" << llendl; LLPointer link_waiter = new LLUpdateAppearanceOnDestroy; - llinfos << "Linking body items" << llendl; // Seraph remove for 2.1 +#ifndef LL_RELEASE_FOR_DOWNLOAD + llinfos << "Linking body items" << llendl; +#endif linkAll(cof, body_items, link_waiter); - llinfos << "Linking wear items" << llendl; // Seraph remove for 2.1 + +#ifndef LL_RELEASE_FOR_DOWNLOAD + llinfos << "Linking wear items" << llendl; +#endif linkAll(cof, wear_items, link_waiter); - llinfos << "Linking obj items" << llendl; // Seraph remove for 2.1 + +#ifndef LL_RELEASE_FOR_DOWNLOAD + llinfos << "Linking obj items" << llendl; +#endif linkAll(cof, obj_items, link_waiter); - llinfos << "Linking gesture items" << llendl; // Seraph remove for 2.1 + +#ifndef LL_RELEASE_FOR_DOWNLOAD + llinfos << "Linking gesture items" << llendl; +#endif linkAll(cof, gest_items, link_waiter); // Add link to outfit if category is an outfit. -- cgit v1.2.3 From 4ae0a0703b9cb8e3f44687e81e26555ef91d5559 Mon Sep 17 00:00:00 2001 From: Loren Shih Date: Tue, 15 Jun 2010 17:58:08 -0400 Subject: EXT-7468 FIXED Remove all 2.1 COF debugging code #ifdef'd a couple more llinfos spam to not show up in release mode. --- indra/newview/llappearancemgr.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'indra/newview/llappearancemgr.cpp') diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 3c267b3308..e19a1294c8 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -201,7 +201,9 @@ void LLUpdateAppearanceOnDestroy::fire(const LLUUID& inv_item) { LLViewerInventoryItem* item = (LLViewerInventoryItem*)gInventory.getItem(inv_item); const std::string item_name = item ? item->getName() : "ITEM NOT FOUND"; +#ifndef LL_RELEASE_FOR_DOWNLOAD llinfos << "callback fired [ name:" << item_name << " UUID:" << inv_item << " count:" << mFireCount << " ] " << llendl; +#endif mFireCount++; } -- cgit v1.2.3 From bc91053543278b56d7009ab6bbcdee88a0ee1418 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Wed, 16 Jun 2010 15:26:53 -0400 Subject: EXT-6571 FIX - avoid removing links to missing wearables, which fixes a problem with ordering in multi-wearables --- indra/newview/llappearancemgr.cpp | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) (limited to 'indra/newview/llappearancemgr.cpp') diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 3c267b3308..1ce5206e89 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -652,7 +652,15 @@ bool LLWearableHoldingPattern::pollMissingWearables() if (done) { gAgentAvatarp->debugWearablesLoaded(); - clearCOFLinksForMissingWearables(); + + // BAP - if we don't call clearCOFLinksForMissingWearables() + // here, we won't have to add the link back in later if the + // wearable arrives late. This is to avoid corruption of + // wearable ordering info. Also has the effect of making + // unworn item links visible in the COF under some + // circumstances. + + //clearCOFLinksForMissingWearables(); onAllComplete(); } return done; @@ -698,8 +706,13 @@ void LLWearableHoldingPattern::handleLateArrivals() data.mWearable = wearable; replaced_types.insert(data.mWearableType); - - LLAppearanceMgr::instance().addCOFItemLink(data.mItemID,false); + + // BAP - if we didn't call + // clearCOFLinksForMissingWearables() earlier, we + // don't need to restore the link here. Fixes + // wearable ordering problems. + + // LLAppearanceMgr::instance().addCOFItemLink(data.mItemID,false); // BAP failing this means inventory or asset server // are corrupted in a way we don't handle. -- cgit v1.2.3 From 9745a0a9e4fab00da010793994c6d50e42635ebe Mon Sep 17 00:00:00 2001 From: Mike Antipov Date: Thu, 17 Jun 2010 17:03:05 +0300 Subject: EXT-7777 WIP Added several cases to show Loading indicator in "My Outfits:" * Outfit is loading for the first time * After user clicks: ** Item Context menu > Add ** Item Context menu > Replace Known Issues: 1. For multi-wearable indicator will disappear after first item from the batch is worn. Did not fix this to not affect the stability before 2.1 release. 2. To show loading indicator first time we have to notify subscribers of LLAgentWearables. For now this is done from the deprecated LLAgentWearables::processAgentInitialWearablesUpdate Reviewed by Vadim Savchuk at https://codereview.productengine.com/secondlife/r/602/ --HG-- branch : product-engine --- indra/newview/llappearancemgr.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'indra/newview/llappearancemgr.cpp') diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 52a5587a16..be58a562c0 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -923,6 +923,14 @@ bool LLAppearanceMgr::wearItemOnAvatar(const LLUUID& item_id_to_wear, bool do_up { if (item_id_to_wear.isNull()) return false; + // *TODO: issue with multi-wearable should be fixed: + // in this case this method will be called N times - loading started for each item + // and than N times will be called - loading completed for each item. + // That means subscribers will be notified that loading is done after first item in a batch is worn. + // (loading indicator disappears for example before all selected items are worn) + // Have not fix this issue for 2.1 because of stability reason. EXT-7777. + gAgentWearables.notifyLoadingStarted(); + LLViewerInventoryItem* item_to_wear = gInventory.getItem(item_id_to_wear); if (!item_to_wear) return false; -- cgit v1.2.3 From 9f996443604a902e03de87d2d14545b4adffa69c Mon Sep 17 00:00:00 2001 From: Vadim Savchuk Date: Thu, 17 Jun 2010 19:03:57 +0300 Subject: EXT-7722 Fixed "Add to COF" and "Remove from COF" outfit context menu items to be enabled when appropriate and work properly. Work on "Take Off - Remove from Current Outfit" and "Wear - Add to Current Outfit" menu options: - The menu items of the outfit context menu and the My Outfits gear menu are now disabled when inappropriate instead of being hidden. - The menu items get enabled/disabled depending on whether you can wear (take off) anything from the selected outfit. (was: depending on whether you're wearing the outfit) - Changed the way the options work: they now only operate on clothes and attachments. "Add to COF" now only adds those body parts that are missing in COF; "Remove from COF" doesn't touch body parts at all. Without this change both "Add" and "Remove" options would be available simultaneously, because any valid outfit contains body parts. I think that would be confusing. And you don't expect you body parts to be replaced when doing "Add to COF'. (that's addition, not replacement) Reviewed by Mike Antipov at https://codereview.productengine.com/secondlife/r/585/ --HG-- branch : product-engine --- indra/newview/llappearancemgr.cpp | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) (limited to 'indra/newview/llappearancemgr.cpp') diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index be58a562c0..4e96372da9 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -1068,7 +1068,7 @@ void LLAppearanceMgr::takeOffOutfit(const LLUUID& cat_id) { LLInventoryModel::cat_array_t cats; LLInventoryModel::item_array_t items; - LLFindWorn collector; + LLFindWearablesEx collector(/*is_worn=*/ true, /*include_body_parts=*/ false); gInventory.collectDescendentsIf(cat_id, cats, items, FALSE, collector); @@ -1224,6 +1224,34 @@ bool LLAppearanceMgr::getCanRemoveOutfit(const LLUUID& outfit_cat_id) return true; } +// static +bool LLAppearanceMgr::getCanRemoveFromCOF(const LLUUID& outfit_cat_id) +{ + LLInventoryModel::cat_array_t cats; + LLInventoryModel::item_array_t items; + LLFindWearablesEx is_worn(/*is_worn=*/ true, /*include_body_parts=*/ false); + gInventory.collectDescendentsIf(outfit_cat_id, + cats, + items, + LLInventoryModel::EXCLUDE_TRASH, + is_worn); + return items.size() > 0; +} + +// static +bool LLAppearanceMgr::getCanAddToCOF(const LLUUID& outfit_cat_id) +{ + LLInventoryModel::cat_array_t cats; + LLInventoryModel::item_array_t items; + LLFindWearablesEx not_worn(/*is_worn=*/ false, /*include_body_parts=*/ false); + gInventory.collectDescendentsIf(outfit_cat_id, + cats, + items, + LLInventoryModel::EXCLUDE_TRASH, + not_worn); + return items.size() > 0; +} + void LLAppearanceMgr::purgeBaseOutfitLink(const LLUUID& category) { LLInventoryModel::cat_array_t cats; @@ -1338,9 +1366,12 @@ void LLAppearanceMgr::updateCOF(const LLUUID& category, bool append) // - Body parts: always include COF contents as a fallback in case any // required parts are missing. + // Preserve body parts from COF if appending. LLInventoryModel::item_array_t body_items; getDescendentsOfAssetType(cof, body_items, LLAssetType::AT_BODYPART, false); getDescendentsOfAssetType(category, body_items, LLAssetType::AT_BODYPART, false); + if (append) + reverse(body_items.begin(), body_items.end()); // Reduce body items to max of one per type. removeDuplicateItems(body_items); filterWearableItems(body_items, 1); -- cgit v1.2.3 From 89825da530f0f5bb4ed2f5260c213174a34f28d8 Mon Sep 17 00:00:00 2001 From: Mike Antipov Date: Fri, 18 Jun 2010 17:28:32 +0300 Subject: EXT-7777 WIP Implemented loading indicator for "Save" and "Save As" actions in "My Outfits" & "Edit Outfit" Panels. EXT-7929 FIXED Updated functionality of attaching object: loading indicator gets hidden when attaching is completed. - Fixed crash when accessing singleton on application exit. - Updated functionality of attaching object: loading indicator was not hidden. * Reason: link to attachment was created without next appearance updating. * Fix: passed "true" into LLAppearanceMgr::addCOFItemLink to call LLAppearanceMgr::updateAppearanceFromCOF when attachments is completed. (Like for clothing). Reviewed by Vadim Savchuk at https://codereview.productengine.com/secondlife/r/611/ --HG-- branch : product-engine --- indra/newview/llappearancemgr.cpp | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) (limited to 'indra/newview/llappearancemgr.cpp') diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 4e96372da9..405cc5b282 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -177,7 +177,13 @@ class LLUpdateDirtyState: public LLInventoryCallback { public: LLUpdateDirtyState() {} - virtual ~LLUpdateDirtyState(){ LLAppearanceMgr::getInstance()->updateIsDirty(); } + virtual ~LLUpdateDirtyState() + { + if (LLAppearanceMgr::instanceExists()) + { + LLAppearanceMgr::getInstance()->updateIsDirty(); + } + } virtual void fire(const LLUUID&) {} }; @@ -2150,6 +2156,8 @@ bool LLAppearanceMgr::updateBaseOutfit() } setOutfitLocked(true); + gAgentWearables.notifyLoadingStarted(); + const LLUUID base_outfit_id = getBaseOutfitUUID(); if (base_outfit_id.isNull()) return false; @@ -2309,6 +2317,7 @@ public: } LLAppearanceMgr::getInstance()->updateIsDirty(); + gAgentWearables.notifyLoadingFinished(); // New outfit is saved. LLAppearanceMgr::getInstance()->updatePanelOutfitName(""); } @@ -2324,6 +2333,8 @@ LLUUID LLAppearanceMgr::makeNewOutfitLinks(const std::string& new_folder_name, b { if (!isAgentAvatarValid()) return LLUUID::null; + gAgentWearables.notifyLoadingStarted(); + // First, make a folder in the My Outfits directory. const LLUUID parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS); LLUUID folder_id = gInventory.createNewCategory( @@ -2530,7 +2541,9 @@ void LLAppearanceMgr::registerAttachment(const LLUUID& item_id) if (mAttachmentInvLinkEnabled) { - LLAppearanceMgr::addCOFItemLink(item_id, false); // Add COF link for item. + // we have to pass do_update = true to call LLAppearanceMgr::updateAppearanceFromCOF. + // it will trigger gAgentWariables.notifyLoadingFinished() + LLAppearanceMgr::addCOFItemLink(item_id, true); // Add COF link for item. } else { @@ -2560,7 +2573,7 @@ void LLAppearanceMgr::linkRegisteredAttachments() ++it) { LLUUID item_id = *it; - addCOFItemLink(item_id, false); + addCOFItemLink(item_id, true); } mRegisteredAttachments.clear(); } -- cgit v1.2.3