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.
master
Loren Shih 2009-11-18 14:51:14 -05:00
parent 2d82332479
commit 5dea0791f7
10 changed files with 70 additions and 92 deletions

View File

@ -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;

View File

@ -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();
}

View File

@ -54,12 +54,6 @@ public:
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 @@ public:
// 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 @@ public:
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();

View File

@ -3534,6 +3534,7 @@ void LLAppViewer::idle()
gEventNotifier.update();
gIdleCallbacks.callFunctions();
gInventory.notifyObservers();
}
if (gDisconnected)

View File

@ -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);
}
}

View File

@ -204,8 +204,6 @@ protected:
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

View File

@ -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);
}
}

View File

@ -167,8 +167,6 @@ public:
// 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 @@ protected:
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);

View File

@ -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;

View File

@ -128,6 +128,8 @@ public:
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;