From 1b745489820f1fd5b93f0394a95bca8f6ba0404a Mon Sep 17 00:00:00 2001 From: Kitty Barnett <develop@catznip.com> Date: Sat, 12 Oct 2013 22:57:07 +0200 Subject: [PATCH] - fixed : locked folder lookups don't properly refresh when an item is taken off (or worn) -> repro: * @attachthis:shirt=n with a shirt worn in a folder under #RLV * right-click the other items in the folder and note that Wear/Add is grayed out/blocked * right-click the worn shirt and "Take Off" * right-click the other items in the folder and note that Wear/Add is still grayed out/blocked when it shouldn't be * wear/take off anything else and note that the items in the #RLV folder are now enabled as they should have been -> RlvFolderLocks::m_fLookupDirty is flagged on any COF change, but RlvCommandOptionGetPath::getItemIDs() wasn't using COF data which caused the discrepency --HG-- branch : RLVa --- indra/newview/rlvhelper.cpp | 42 +++++++++++++++++++--------------- indra/newview/rlvhelper.h | 5 ++-- indra/newview/rlvinventory.cpp | 16 +++++++++++++ indra/newview/rlvinventory.h | 13 ++++++++++- 4 files changed, 55 insertions(+), 21 deletions(-) diff --git a/indra/newview/rlvhelper.cpp b/indra/newview/rlvhelper.cpp index 4c198d43987..6bfc6137c0e 100644 --- a/indra/newview/rlvhelper.cpp +++ b/indra/newview/rlvhelper.cpp @@ -263,11 +263,11 @@ RlvCommandOptionGetPath::RlvCommandOptionGetPath(const RlvCommand& rlvCmd, getpa RlvCommandOptionGeneric rlvCmdOption(rlvCmd.getOption()); if (rlvCmdOption.isWearableType()) // <option> can be a clothing layer { - getItemIDs(rlvCmdOption.getWearableType(), m_idItems, false); + getItemIDs(rlvCmdOption.getWearableType(), m_idItems); } else if (rlvCmdOption.isAttachmentPoint()) // ... or it can specify an attachment point { - getItemIDs(rlvCmdOption.getAttachmentPoint(), m_idItems, false); + getItemIDs(rlvCmdOption.getAttachmentPoint(), m_idItems); } else if (rlvCmdOption.isEmpty()) // ... or it can be empty (in which case we act on the object that issued the command) { @@ -296,33 +296,39 @@ RlvCommandOptionGetPath::RlvCommandOptionGetPath(const RlvCommand& rlvCmd, getpa } } -// Checked: 2010-11-30 (RLVa-1.3.0b) | Modified: RLVa-1.3.0b -bool RlvCommandOptionGetPath::getItemIDs(const LLViewerJointAttachment* pAttachPt, uuid_vec_t& idItems, bool fClear) +// Checked: 2013-10-12 (RLVa-1.4.9) +bool RlvCommandOptionGetPath::getItemIDs(const LLViewerJointAttachment* pAttachPt, uuid_vec_t& idItems) { - if (fClear) - idItems.clear(); uuid_vec_t::size_type cntItemsPrev = idItems.size(); - if (pAttachPt) + + LLInventoryModel::cat_array_t folders; LLInventoryModel::item_array_t items; + RlvFindAttachmentsOnPoint f(pAttachPt); + gInventory.collectDescendentsIf(LLAppearanceMgr::instance().getCOF(), folders, items, false, f); + for (LLInventoryModel::item_array_t::const_iterator itItem = items.begin(); itItem != items.end(); ++itItem) { - for (LLViewerJointAttachment::attachedobjs_vec_t::const_iterator itAttachObj = pAttachPt->mAttachedObjects.begin(); - itAttachObj != pAttachPt->mAttachedObjects.end(); ++itAttachObj) - { - idItems.push_back((*itAttachObj)->getAttachmentItemID()); - } + const LLViewerInventoryItem* pItem = *itItem; + if (pItem) + idItems.push_back(pItem->getLinkedUUID()); } + return (cntItemsPrev != idItems.size()); } -// Checked: 2010-11-30 (RLVa-1.3.0b) | Modified: RLVa-1.3.0b -bool RlvCommandOptionGetPath::getItemIDs(LLWearableType::EType wtType, uuid_vec_t& idItems, bool fClear) +// Checked: 2013-10-12 (RLVa-1.4.9) +bool RlvCommandOptionGetPath::getItemIDs(LLWearableType::EType wtType, uuid_vec_t& idItems) { - if (fClear) - idItems.clear(); uuid_vec_t::size_type cntItemsPrev = idItems.size(); - for (S32 idxWearable = 0, cntWearable = gAgentWearables.getWearableCount(wtType); idxWearable < cntWearable; idxWearable++) + + LLInventoryModel::cat_array_t folders; LLInventoryModel::item_array_t items; + LLFindWearablesOfType f(wtType); + gInventory.collectDescendentsIf(LLAppearanceMgr::instance().getCOF(), folders, items, false, f); + for (LLInventoryModel::item_array_t::const_iterator itItem = items.begin(); itItem != items.end(); ++itItem) { - idItems.push_back(gAgentWearables.getWearableItemID(wtType, idxWearable)); + const LLViewerInventoryItem* pItem = *itItem; + if (pItem) + idItems.push_back(pItem->getLinkedUUID()); } + return (cntItemsPrev != idItems.size()); } diff --git a/indra/newview/rlvhelper.h b/indra/newview/rlvhelper.h index b5bdc824f8f..d49ad1cf43d 100644 --- a/indra/newview/rlvhelper.h +++ b/indra/newview/rlvhelper.h @@ -144,8 +144,9 @@ struct RlvCommandOptionGetPath : public RlvCommandOption /*virtual*/ bool isEmpty() const { return m_idItems.empty(); } const uuid_vec_t& getItemIDs() const { return m_idItems; } - static bool getItemIDs(const LLViewerJointAttachment* pAttachPt, uuid_vec_t& idItems, bool fClear = true); - static bool getItemIDs(LLWearableType::EType wtType, uuid_vec_t& idItems, bool fClear = true); + // NOTE: Both functions are COF-based rather than items gathered from mAttachedObjects or gAgentWearables + static bool getItemIDs(const LLViewerJointAttachment* pAttachPt, uuid_vec_t& idItems); + static bool getItemIDs(LLWearableType::EType wtType, uuid_vec_t& idItems); protected: bool m_fCallback; // TRUE if a callback is schedueled diff --git a/indra/newview/rlvinventory.cpp b/indra/newview/rlvinventory.cpp index 4de32a363cd..48ef6000279 100644 --- a/indra/newview/rlvinventory.cpp +++ b/indra/newview/rlvinventory.cpp @@ -787,3 +787,19 @@ bool RlvWearableItemCollector::operator()(LLInventoryCategory* pFolder, LLInvent } // ============================================================================ +// General purpose inventory helper classes +// + +// Checked: 2013-10-12 (RLVa-1.4.9) +bool RlvFindAttachmentsOnPoint::operator()(LLInventoryCategory* pFolder, LLInventoryItem* pItem) +{ +#ifndef RLV_DEPRECATE_ATTACHPTNAMING + // First check if the item is attached to the attachment point; fall back to the item name otherwise + return (pItem) && (LLAssetType::AT_OBJECT == pItem->getType()) && + ( ((m_pAttachPt) && (m_pAttachPt->getAttachedObject(pItem->getLinkedUUID()))) || (RlvAttachPtLookup::getAttachPoint(pItem) == m_pAttachPt) ); +#else + return (pItem) && (LLAssetType::AT_OBJECT == pItem->getType()) && (m_pAttachPt) && (m_pAttachPt->getAttachedObject(pItem->getLinkedUUID())); +#endif // RLV_DEPRECATE_LEGACY_ATTACHPT +} + +// ============================================================================ diff --git a/indra/newview/rlvinventory.h b/indra/newview/rlvinventory.h index b35fbe4e07c..1899ece4e05 100644 --- a/indra/newview/rlvinventory.h +++ b/indra/newview/rlvinventory.h @@ -234,10 +234,21 @@ class RlvIsLinkType : public LLInventoryCollectFunctor { public: RlvIsLinkType() {} - virtual ~RlvIsLinkType() {} + /*virtual*/ ~RlvIsLinkType() {} virtual bool operator()(LLInventoryCategory* pFolder, LLInventoryItem* pItem) { return (pItem) && (pItem->getIsLinkType()); } }; +// If the attachment item is linked in COF but isn't worn (or just detached) the function will return inconsistent information +class RlvFindAttachmentsOnPoint : public LLInventoryCollectFunctor +{ +public: + RlvFindAttachmentsOnPoint(const LLViewerJointAttachment* pAttachPt) : m_pAttachPt(pAttachPt) {} + /*virtual*/ ~RlvFindAttachmentsOnPoint() {} + virtual bool operator()(LLInventoryCategory* pFolder, LLInventoryItem* pItem); +protected: + const LLViewerJointAttachment* m_pAttachPt; +}; + // ============================================================================ // RlvInventory inlined member functions // -- GitLab