From 5dea0791f7087f2ce2bbe2bdce49d62f1a6f1f92 Mon Sep 17 00:00:00 2001 From: Loren Shih <seraph@lindenlab.com> Date: Wed, 18 Nov 2009 14:51:14 -0500 Subject: [PATCH] EXT-2581 : Old items still display as "(worn)" even after I change outfits Added gInventory.notifyObservers to idle callbacks so it gets triggered without explicit notifyObservers synchronization. Added more state tracking for attachments, wearables, and links of those types, so that they're marked as changed properly. --- indra/newview/llagentwearables.cpp | 23 +++++-------- indra/newview/llappearancemgr.cpp | 51 ++++++++++++++--------------- indra/newview/llappearancemgr.h | 19 ++++++----- indra/newview/llappviewer.cpp | 1 + indra/newview/llinventorybridge.cpp | 35 ++------------------ indra/newview/llinventorybridge.h | 2 -- indra/newview/llinventorymodel.cpp | 17 +++++++--- indra/newview/llinventorymodel.h | 5 +-- indra/newview/llwearable.cpp | 7 ++++ indra/newview/llwearable.h | 2 ++ 10 files changed, 70 insertions(+), 92 deletions(-) diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index 6b2033fc6f9..538dcb6f3df 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; diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 60c6061e966..d6265a85f63 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -579,7 +579,6 @@ void LLAppearanceManager::updateAgentWearables(LLWearableHoldingPattern* holder, if(wearables.count() > 0) { gAgentWearables.setWearableOutfit(items, wearables, !append); - gInventory.notifyObservers(); } delete holder; @@ -819,15 +818,23 @@ bool areMatchingWearables(const LLViewerInventoryItem *a, const LLViewerInventor (a->getWearableType() == b->getWearableType())); } -void LLAppearanceManager::addItemLink( LLInventoryItem* item, bool do_update ) +void LLAppearanceManager::addCOFItemLink(const LLUUID &item_id, bool do_update ) { - LLViewerInventoryItem *vitem = dynamic_cast<LLViewerInventoryItem*>(item); + const LLInventoryItem *item = gInventory.getItem(item_id); + addCOFItemLink(item); +} + +void LLAppearanceManager::addCOFItemLink(const LLInventoryItem *item, bool do_update ) +{ + const LLViewerInventoryItem *vitem = dynamic_cast<const LLViewerInventoryItem*>(item); if (!vitem) { llwarns << "not an llviewerinventoryitem, failed" << llendl; return; } - + + gInventory.addChangedMask(LLInventoryObserver::LABEL, vitem->getLinkedUUID()); + LLInventoryModel::cat_array_t cat_array; LLInventoryModel::item_array_t item_array; gInventory.collectDescendents(LLAppearanceManager::getCOF(), @@ -839,7 +846,7 @@ void LLAppearanceManager::addItemLink( LLInventoryItem* item, bool do_update ) { // Are these links to the same object? const LLViewerInventoryItem* inv_item = item_array.get(i).get(); - if (inv_item->getLinkedUUID() == item->getLinkedUUID()) + if (inv_item->getLinkedUUID() == vitem->getLinkedUUID()) { linked_already = true; } @@ -850,7 +857,6 @@ void LLAppearanceManager::addItemLink( LLInventoryItem* item, bool do_update ) { gAgentWearables.removeWearable(inv_item->getWearableType(),true,0); gInventory.purgeObject(inv_item->getUUID()); - gInventory.notifyObservers(); } } if (linked_already) @@ -886,8 +892,10 @@ void LLAppearanceManager::addEnsembleLink( LLInventoryCategory* cat, bool do_upd #endif } -void LLAppearanceManager::removeItemLinks(const LLUUID& item_id, bool do_update) +void LLAppearanceManager::removeCOFItemLinks(const LLUUID& item_id, bool do_update) { + gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id); + LLInventoryModel::cat_array_t cat_array; LLInventoryModel::item_array_t item_array; gInventory.collectDescendents(LLAppearanceManager::getCOF(), @@ -899,7 +907,8 @@ void LLAppearanceManager::removeItemLinks(const LLUUID& item_id, bool do_update) const LLInventoryItem* item = item_array.get(i).get(); if (item->getLinkedUUID() == item_id) { - gInventory.purgeObject(item_array.get(i)->getUUID()); + const LLUUID& item_id = item_array.get(i)->getUUID(); + gInventory.purgeObject(item_id); } } if (do_update) @@ -978,18 +987,13 @@ void dumpAttachmentSet(const std::set<LLUUID>& atts, const std::string& msg) void LLAppearanceManager::registerAttachment(const LLUUID& item_id) { mRegisteredAttachments.insert(item_id); + gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id); //dumpAttachmentSet(mRegisteredAttachments,"after register:"); if (mAttachmentInvLinkEnabled) { - LLViewerInventoryItem *item = gInventory.getItem(item_id); - if (item) - { - //LLAppearanceManager::dumpCat(LLAppearanceManager::getCOF(),"Adding attachment link:"); - LLAppearanceManager::addItemLink(item,false); // Add COF link for item. - gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id); - gInventory.notifyObservers(); - } + //LLAppearanceManager::dumpCat(LLAppearanceManager::getCOF(),"Adding attachment link:"); + LLAppearanceManager::addCOFItemLink(item_id, false); // Add COF link for item. } else { @@ -1000,15 +1004,14 @@ void LLAppearanceManager::registerAttachment(const LLUUID& item_id) void LLAppearanceManager::unregisterAttachment(const LLUUID& item_id) { mRegisteredAttachments.erase(item_id); + gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id); + //dumpAttachmentSet(mRegisteredAttachments,"after unregister:"); if (mAttachmentInvLinkEnabled) { //LLAppearanceManager::dumpCat(LLAppearanceManager::getCOF(),"Removing attachment link:"); - LLAppearanceManager::removeItemLinks(item_id, false); - // BAP - needs to change for label to track link. - gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id); - gInventory.notifyObservers(); + LLAppearanceManager::removeCOFItemLinks(item_id, false); } else { @@ -1023,13 +1026,7 @@ void LLAppearanceManager::linkRegisteredAttachments() ++it) { LLUUID item_id = *it; - LLViewerInventoryItem *item = gInventory.getItem(item_id); - if (item) - { - addItemLink(item, false); - gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id); - gInventory.notifyObservers(); - } + addCOFItemLink(item_id, false); } mRegisteredAttachments.clear(); } diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h index 12ffa336b45..5daa6d067b6 100644 --- a/indra/newview/llappearancemgr.h +++ b/indra/newview/llappearancemgr.h @@ -54,12 +54,6 @@ class LLAppearanceManager: public LLSingleton<LLAppearanceManager> void wearOutfitByName(const std::string& name); void changeOutfit(bool proceed, const LLUUID& category, bool append); - // Add COF link to individual item. - void addItemLink(LLInventoryItem* item, bool do_update = true); - - // Add COF link to ensemble folder. - void addEnsembleLink(LLInventoryCategory* item, bool do_update = true); - // Copy all items in a category. void shallowCopyCategory(const LLUUID& src_id, const LLUUID& dst_id, LLPointer<LLInventoryCallback> cb); @@ -67,9 +61,6 @@ class LLAppearanceManager: public LLSingleton<LLAppearanceManager> // Find the Current Outfit folder. LLUUID getCOF(); - // Remove COF entries - void removeItemLinks(const LLUUID& item_id, bool do_update = true); - void updateAgentWearables(LLWearableHoldingPattern* holder, bool append); // For debugging - could be moved elsewhere. @@ -87,6 +78,16 @@ class LLAppearanceManager: public LLSingleton<LLAppearanceManager> LLInventoryModel::item_array_t& items, LLPointer<LLInventoryCallback> cb); + // Add COF link to individual item. + void addCOFItemLink(const LLUUID& item_id, bool do_update = true); + void addCOFItemLink(const LLInventoryItem *item, bool do_update = true); + + // Remove COF entries + void removeCOFItemLinks(const LLUUID& item_id, bool do_update = true); + + // Add COF link to ensemble folder. + void addEnsembleLink(LLInventoryCategory* item, bool do_update = true); + protected: LLAppearanceManager(); ~LLAppearanceManager(); diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index f82d1780895..3d7b3244585 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -3534,6 +3534,7 @@ void LLAppViewer::idle() gEventNotifier.update(); gIdleCallbacks.callFunctions(); + gInventory.notifyObservers(); } if (gDisconnected) diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index fbef237779c..384d2ae671a 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -183,37 +183,6 @@ BOOL LLInvFVBridge::isItemRemovable() return FALSE; } -// Sends an update to all link items that point to the base item. -void LLInvFVBridge::renameLinkedItems(const LLUUID &item_id, const std::string& new_name) -{ - LLInventoryModel* model = getInventoryModel(); - if(!model) return; - - LLInventoryItem* itemp = model->getItem(mUUID); - if (!itemp) return; - - if (itemp->getIsLinkType()) - { - return; - } - - LLInventoryModel::item_array_t item_array = model->collectLinkedItems(item_id); - for (LLInventoryModel::item_array_t::iterator iter = item_array.begin(); - iter != item_array.end(); - iter++) - { - LLViewerInventoryItem *linked_item = (*iter); - if (linked_item->getUUID() == item_id) continue; - - LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(linked_item); - new_item->rename(new_name); - new_item->updateServer(FALSE); - model->updateItem(new_item); - // model->addChangedMask(LLInventoryObserver::LABEL, linked_item->getUUID()); - } - model->notifyObservers(); -} - // Can be moved to another folder BOOL LLInvFVBridge::isItemMovable() const { @@ -2924,7 +2893,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, // BAP - should skip if dup. if (move_is_into_current_outfit) { - LLAppearanceManager::instance().addItemLink(inv_item); + LLAppearanceManager::instance().addCOFItemLink(inv_item); } else { @@ -4171,7 +4140,7 @@ void wear_inventory_item_on_avatar( LLInventoryItem* item ) lldebugs << "wear_inventory_item_on_avatar( " << item->getName() << " )" << llendl; - LLAppearanceManager::instance().addItemLink(item); + LLAppearanceManager::instance().addCOFItemLink(item); } } diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h index 56cb0f93ed9..49e64ebdded 100644 --- a/indra/newview/llinventorybridge.h +++ b/indra/newview/llinventorybridge.h @@ -204,8 +204,6 @@ class LLInvFVBridge : public LLFolderViewEventListener const LLUUID& new_parent, BOOL restamp); void removeBatchNoCheck(LLDynamicArray<LLFolderViewEventListener*>& batch); - void renameLinkedItems(const LLUUID &item_id, const std::string& new_name); - protected: LLHandle<LLPanel> mInventoryPanel; const LLUUID mUUID; // item id diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index 84588fbe8ca..fbaab385fed 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -509,7 +509,7 @@ void LLInventoryModel::collectDescendentsIf(const LLUUID& id, } } -void LLInventoryModel::updateLinkedItems(const LLUUID& object_id) +void LLInventoryModel::addChangedMaskForLinks(const LLUUID& object_id, U32 mask) { const LLInventoryObject *obj = getObject(object_id); if (!obj || obj->getIsLinkType()) @@ -532,7 +532,7 @@ void LLInventoryModel::updateLinkedItems(const LLUUID& object_id) cat_iter++) { LLViewerInventoryCategory *linked_cat = (*cat_iter); - addChangedMask(LLInventoryObserver::LABEL, linked_cat->getUUID()); + addChangedMask(mask, linked_cat->getUUID()); }; for (LLInventoryModel::item_array_t::iterator iter = item_array.begin(); @@ -540,9 +540,8 @@ void LLInventoryModel::updateLinkedItems(const LLUUID& object_id) iter++) { LLViewerInventoryItem *linked_item = (*iter); - addChangedMask(LLInventoryObserver::LABEL, linked_item->getUUID()); + addChangedMask(mask, linked_item->getUUID()); }; - notifyObservers(); } const LLUUID& LLInventoryModel::getLinkedItemID(const LLUUID& object_id) const @@ -1133,6 +1132,14 @@ void LLInventoryModel::notifyObservers(const std::string service_name) llwarns << "Call was made to notifyObservers within notifyObservers!" << llendl; return; } + + if ((mModifyMask == LLInventoryObserver::NONE) && (service_name == "")) + { + mModifyMask = LLInventoryObserver::NONE; + mChangedItemIDs.clear(); + return; + } + mIsNotifyObservers = TRUE; for (observer_list_t::iterator iter = mObservers.begin(); iter != mObservers.end(); ) @@ -1180,7 +1187,7 @@ void LLInventoryModel::addChangedMask(U32 mask, const LLUUID& referent) // not sure what else might need to be accounted for this. if (mModifyMask & LLInventoryObserver::LABEL) { - updateLinkedItems(referent); + addChangedMaskForLinks(referent, LLInventoryObserver::LABEL); } } diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h index aa4ffb392fd..da12dbdf7fd 100644 --- a/indra/newview/llinventorymodel.h +++ b/indra/newview/llinventorymodel.h @@ -167,8 +167,6 @@ class LLInventoryModel // Assumes item_id is itself not a linked item. item_array_t collectLinkedItems(const LLUUID& item_id, const LLUUID& start_folder_id = LLUUID::null); - // Updates all linked items pointing to this id. - void updateLinkedItems(const LLUUID& object_id); // Get the inventoryID that this item points to, else just return item_id const LLUUID& getLinkedItemID(const LLUUID& object_id) const; @@ -440,6 +438,9 @@ class LLInventoryModel bool messageUpdateCore(LLMessageSystem* msg, bool do_accounting); + // Updates all linked items pointing to this id. + void addChangedMaskForLinks(const LLUUID& object_id, U32 mask); + protected: cat_array_t* getUnlockedCatArray(const LLUUID& id); item_array_t* getUnlockedItemArray(const LLUUID& id); diff --git a/indra/newview/llwearable.cpp b/indra/newview/llwearable.cpp index 2849cfa20ed..ced0b648966 100644 --- a/indra/newview/llwearable.cpp +++ b/indra/newview/llwearable.cpp @@ -38,6 +38,7 @@ #include "lllocaltextureobject.h" #include "llviewertexturelist.h" #include "llinventorymodel.h" +#include "llinventoryobserver.h" #include "llviewerregion.h" #include "llvoavatar.h" #include "llvoavatarself.h" @@ -1098,6 +1099,12 @@ void LLWearable::destroyTextures() mSavedTEMap.clear(); } + +void LLWearable::setLabelUpdated() const +{ + gInventory.addChangedMask(LLInventoryObserver::LABEL, getItemID()); +} + struct LLWearableSaveData { EWearableType mType; diff --git a/indra/newview/llwearable.h b/indra/newview/llwearable.h index fd19a864062..0863adb7f56 100644 --- a/indra/newview/llwearable.h +++ b/indra/newview/llwearable.h @@ -128,6 +128,8 @@ class LLWearable BOOL isOnTop() const; + // Something happened that requires the wearable's label to be updated (e.g. worn/unworn). + void setLabelUpdated() const; private: typedef std::map<S32, LLLocalTextureObject*> te_map_t; -- GitLab