From c99aabf17c5c9ed3ec24b8a2e5ff9407a58ed980 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Sun, 9 Oct 2011 21:48:01 -0500 Subject: [PATCH] LLAgentWearable LLSingleton-ized. --- indra/newview/llagentwearables.cpp | 50 ++++++++++++++-------------- indra/newview/llfloatercustomize.cpp | 2 +- indra/newview/llinventorybridge.cpp | 20 +++++------ indra/newview/llviewerwindow.cpp | 3 ++ indra/newview/llwearablelist.cpp | 24 ++++++------- indra/newview/llwearablelist.h | 14 +++++--- indra/newview/rlvhelper.cpp | 4 +-- indra/newview/rlvinventory.cpp | 2 +- 8 files changed, 63 insertions(+), 56 deletions(-) diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index 632534417..6f5223417 100644 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -247,7 +247,7 @@ void LLAgentWearables::saveWearable( LLWearableType::EType type, BOOL send_updat LLWearable* old_wearable = mWearableEntry[(S32)type].mWearable; if( old_wearable && (old_wearable->isDirty() || old_wearable->isOldVersion()) ) { - LLWearable* new_wearable = gWearableList.createCopyFromAvatar( old_wearable ); + LLWearable* new_wearable = LLWearableList::instance().createCopyFromAvatar( old_wearable ); mWearableEntry[(S32)type].mWearable = new_wearable; LLInventoryItem* item = gInventory.getItem(mWearableEntry[(S32)type].mItemID); @@ -297,10 +297,9 @@ void LLAgentWearables::saveWearable( LLWearableType::EType type, BOOL send_updat } } -void LLAgentWearables::saveWearableAs( - LLWearableType::EType type, - const std::string& new_name, - BOOL save_in_lost_and_found) +void LLAgentWearables::saveWearableAs(const LLWearableType::EType type, + const std::string& new_name, + BOOL save_in_lost_and_found) { if(!isWearableCopyable(type)) { @@ -321,7 +320,7 @@ void LLAgentWearables::saveWearableAs( } std::string trunc_name(new_name); LLStringUtil::truncate(trunc_name, DB_INV_ITEM_NAME_STR_LEN); - LLWearable* new_wearable = gWearableList.createCopyFromAvatar( + LLWearable* new_wearable = LLWearableList::instance().createCopyFromAvatar( old_wearable, trunc_name); LLPointer cb = @@ -356,7 +355,7 @@ void LLAgentWearables::saveWearableAs( { std::string old_name = old_wearable->getName(); old_wearable->setName( new_name ); - LLWearable* new_wearable = gWearableList.createCopyFromAvatar( old_wearable ); + LLWearable* new_wearable = LLWearableList::instance().createCopyFromAvatar( old_wearable ); old_wearable->setName( old_name ); LLUUID category_id; @@ -435,7 +434,7 @@ void LLAgentWearables::setWearableName( const LLUUID& item_id, const std::string std::string old_name = old_wearable->getName(); old_wearable->setName( new_name ); - LLWearable* new_wearable = gWearableList.createCopy( old_wearable ); + LLWearable* new_wearable = LLWearableList::instance().createCopy(old_wearable); LLInventoryItem* item = gInventory.getItem(item_id); if(item) { @@ -589,8 +588,9 @@ void LLAgentWearables::processAgentInitialWearablesUpdate( LLMessageSystem* mesg { gMessageSystem->getU32Fast(_PREHASH_AgentData, _PREHASH_SerialNum, gAgentQueryManager.mUpdateSerialNum ); + const S32 NUM_BODY_PARTS = 4; S32 num_wearables = gMessageSystem->getNumberOfBlocksFast(_PREHASH_WearableData); - if( num_wearables < 4 ) + if (num_wearables < NUM_BODY_PARTS) { // Transitional state. Avatars should always have at least their body parts (hair, eyes, shape and skin). // The fact that they don't have any here (only a dummy is sent) implies that this account existed @@ -600,9 +600,8 @@ void LLAgentWearables::processAgentInitialWearablesUpdate( LLMessageSystem* mesg //lldebugs << "processAgentInitialWearablesUpdate()" << llendl; // Add wearables - LLUUID asset_id_array[ LLWearableType::WT_COUNT ]; - S32 i; - for( i=0; i < num_wearables; i++ ) + std::pair asset_id_array[ LLWearableType::WT_COUNT ]; + for (S32 i=0; i < num_wearables; i++) { U8 type_u8 = 0; gMessageSystem->getU8Fast(_PREHASH_WearableData, _PREHASH_WearableType, type_u8, i ); @@ -630,7 +629,7 @@ void LLAgentWearables::processAgentInitialWearablesUpdate( LLMessageSystem* mesg } gAgentWearables.mWearableEntry[type].mItemID = item_id; - asset_id_array[type] = asset_id; + asset_id_array[type] = std::pair(asset_id,item_id); } LL_DEBUGS("Wearables") << " " << LLWearableType::getTypeLabel(type) << " " << asset_id << " item id " << gAgentWearables.mWearableEntry[type].mItemID.asString() << LL_ENDL; @@ -639,13 +638,14 @@ void LLAgentWearables::processAgentInitialWearablesUpdate( LLMessageSystem* mesg LLCOFMgr::instance().fetchCOF(); // now that we have the asset ids...request the wearable assets - for( i = 0; i < LLWearableType::WT_COUNT; i++ ) + for(S32 i = 0; i < LLWearableType::WT_COUNT; i++ ) { - LL_DEBUGS("Wearables") << " fetching " << asset_id_array[i] << LL_ENDL; - if( !gAgentWearables.mWearableEntry[i].mItemID.isNull() ) + LL_DEBUGS("Wearables") << " fetching " << asset_id_array[i].first << LL_ENDL; + const LLUUID item_id = asset_id_array[i].second; + if( !item_id.isNull() ) { - gWearableList.getAsset( - asset_id_array[i], + LLWearableList::instance().getAsset( + asset_id_array[i].first, LLStringUtil::null, LLWearableType::getAssetType( (LLWearableType::EType) i ), LLAgentWearables::onInitialWearableAssetArrived, (void*)(intptr_t)i ); @@ -726,7 +726,7 @@ void LLAgentWearables::recoverMissingWearable( LLWearableType::EType type ) // Try to recover by replacing missing wearable with a new one. LLNotificationsUtil::add("ReplacedMissingWearable"); lldebugs << "Wearable " << LLWearableType::getTypeLabel( type ) << " could not be downloaded. Replaced inventory item with default wearable." << llendl; - LLWearable* new_wearable = gWearableList.createNewWearable(type); + LLWearable* new_wearable = LLWearableList::instance().createNewWearable(type); S32 type_s32 = (S32) type; mWearableEntry[type_s32].mWearable = new_wearable; @@ -735,8 +735,7 @@ void LLAgentWearables::recoverMissingWearable( LLWearableType::EType type ) // Add a new one in the lost and found folder. // (We used to overwrite the "not found" one, but that could potentially // destory content.) JC - LLUUID lost_and_found_id = - gInventory.findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND); + const LLUUID lost_and_found_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND); LLPointer cb = new addWearableToAgentInventoryCallback( LLPointer(NULL), @@ -812,7 +811,7 @@ void LLAgentWearables::createStandardWearables(BOOL female) donecb = new createStandardWearablesAllDoneCallback; } llassert( mWearableEntry[i].mWearable == NULL ); - LLWearable* wearable = gWearableList.createNewWearable((LLWearableType::EType)i); + LLWearable* wearable = LLWearableList::instance().createNewWearable((LLWearableType::EType)i); mWearableEntry[i].mWearable = wearable; // no need to update here... LLPointer cb = @@ -913,7 +912,7 @@ void LLAgentWearables::makeNewOutfit( if (fUseLinks || isWearableCopyable((LLWearableType::EType)index)) { - LLWearable* new_wearable = gWearableList.createCopy(old_wearable); + LLWearable* new_wearable = LLWearableList::instance().createCopy(old_wearable); if (rename_clothing) { new_wearable->setName(new_name); @@ -1171,8 +1170,9 @@ void LLAgentWearables::copyWearableToInventory( LLWearableType::EType type ) // Save the old wearable if it has changed. if( wearable->isDirty() ) { - wearable = gWearableList.createCopyFromAvatar( wearable ); - mWearableEntry[ type ].mWearable = wearable; + LLWearable * new_wearable = LLWearableList::instance().createCopyFromAvatar( wearable ); + mWearableEntry[ type ].mWearable = new_wearable; + wearable = new_wearable; } // Make a new entry in the inventory. (Put it in the same folder as the original item if possible.) diff --git a/indra/newview/llfloatercustomize.cpp b/indra/newview/llfloatercustomize.cpp index d64fcea84..a6b60a7cf 100644 --- a/indra/newview/llfloatercustomize.cpp +++ b/indra/newview/llfloatercustomize.cpp @@ -719,7 +719,7 @@ bool LLPanelEditWearable::onSelectAutoWearOption(const LLSD& notification, const if(avatar) { // Create a new wearable in the default folder for the wearable's asset type. - LLWearable* wearable = gWearableList.createNewWearable( (LLWearableType::EType)notification["payload"]["wearable_type"].asInteger() ); + LLWearable* wearable = LLWearableList::instance().createNewWearable( (LLWearableType::EType)notification["payload"]["wearable_type"].asInteger() ); LLAssetType::EType asset_type = wearable->getAssetType(); LLUUID folder_id; diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 6ee0d2be5..a1bc411f3 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -2909,7 +2909,7 @@ void LLFolderBridge::createWearable(LLFolderBridge* bridge, LLWearableType::ETyp // static void LLFolderBridge::createWearable(LLUUID parent_id, LLWearableType::EType type) { - LLWearable* wearable = gWearableList.createNewWearable(type); + LLWearable* wearable = LLWearableList::instance().createNewWearable(type); LLAssetType::EType asset_type = wearable->getAssetType(); LLInventoryType::EType inv_type = LLInventoryType::IT_WEARABLE; create_inventory_item(gAgent.getID(), gAgent.getSessionID(), @@ -4484,7 +4484,7 @@ void wear_inventory_item_on_avatar( LLInventoryItem* item ) lldebugs << "wear_inventory_item_on_avatar( " << item->getName() << " )" << llendl; - gWearableList.getAsset(item->getAssetUUID(), + LLWearableList::instance().getAsset(item->getAssetUUID(), item->getName(), item->getType(), LLWearableBridge::onWearOnAvatarArrived, @@ -4606,8 +4606,8 @@ void LLOutfitObserver::done() name = cat->getName(); } LLViewerInventoryItem* item = NULL; - item_ref_t::iterator it = mComplete.begin(); - item_ref_t::iterator end = mComplete.end(); + uuid_vec_t::iterator it = mComplete.begin(); + uuid_vec_t::iterator end = mComplete.end(); LLUUID pid; for(; it < end; ++it) { @@ -4924,7 +4924,7 @@ void wear_inventory_category_on_avatar_step2( BOOL proceed, void* userdata ) // [/RLVa:KB] found = found_container.get(i); - gWearableList.getAsset(found->mAssetID, + LLWearableList::instance().getAsset(found->mAssetID, found->mName, found->mAssetType, wear_inventory_category_on_avatar_loop, @@ -5046,7 +5046,7 @@ void wear_inventory_category_on_avatar_step3(LLWearableHoldingPattern* holder, B //And this code does not handle failed asset uploads properly // if(!wearable->isMatchedToInventoryItem(item )) // { -// wearable = gWearableList.createWearableMatchedToInventoryItem( wearable, item ); +// wearable = LLWearableList::instance().createWearableMatchedToInventoryItem( wearable, item ); // // Now that we have an asset that matches the // // item, update the item to point to the new // // asset. @@ -5162,7 +5162,7 @@ void remove_inventory_category_from_avatar_step2( BOOL proceed, void* userdata) if ( (pWearable) && ( (!rlv_handler_t::isEnabled()) || (gRlvWearableLocks.canRemove(pWearable->getType())) ) ) // [/RLVa:KB] { - gWearableList.getAsset( item->getAssetUUID(), + LLWearableList::instance().getAsset( item->getAssetUUID(), item->getName(), item->getType(), LLWearableBridge::onRemoveFromAvatarArrived, @@ -5269,7 +5269,7 @@ void LLWearableBridge::performAction(LLFolderView* folder, LLInventoryModel* mod LLViewerInventoryItem* item = getItem(); if (item) { - gWearableList.getAsset(item->getAssetUUID(), + LLWearableList::instance().getAsset(item->getAssetUUID(), item->getName(), item->getType(), LLWearableBridge::onRemoveFromAvatarArrived, @@ -5484,7 +5484,7 @@ void LLWearableBridge::onWearOnAvatarArrived( LLWearable* wearable, void* userda // if(!wearable->isMatchedToInventoryItem(item)) // { -// LLWearable* new_wearable = gWearableList.createWearableMatchedToInventoryItem( wearable, item ); +// LLWearable* new_wearable = LLWearableList::instance().createWearableMatchedToInventoryItem( wearable, item ); // // // Now that we have an asset that matches the // // item, update the item to point to the new @@ -5563,7 +5563,7 @@ void LLWearableBridge::onRemoveFromAvatar(void* user_data) LLViewerInventoryItem* item = self->getItem(); if (item) { - gWearableList.getAsset(item->getAssetUUID(), + LLWearableList::instance().getAsset(item->getAssetUUID(), item->getName(), item->getType(), onRemoveFromAvatarArrived, diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 5e97aa2ce..8217fe19e 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -190,6 +190,7 @@ #include "llviewerjoystick.h" #include "llviewernetwork.h" #include "llpostprocess.h" +#include "llwearablelist.h" #include "llnotifications.h" #include "llnotificationsutil.h" @@ -2184,6 +2185,8 @@ void LLViewerWindow::shutdownGL() gSky.cleanup(); stop_glerror(); + LLWearableList::instance().cleanup() ; + gTextureList.shutdown(); stop_glerror(); diff --git a/indra/newview/llwearablelist.cpp b/indra/newview/llwearablelist.cpp index 1e6f65136..535beb3ad 100644 --- a/indra/newview/llwearablelist.cpp +++ b/indra/newview/llwearablelist.cpp @@ -43,18 +43,13 @@ #include "llviewerstats.h" #include "llnotificationsutil.h" -// Globals -LLWearableList gWearableList; // Globally constructed; be careful that there's no dependency with gAgent. - - +// Callback struct struct LLWearableArrivedData { - LLWearableArrivedData( - LLAssetType::EType asset_type, + LLWearableArrivedData(LLAssetType::EType asset_type, const std::string& wearable_name, void(*asset_arrived_callback)(LLWearable*, void* userdata), - void* userdata ) - : + void* userdata) : mAssetType( asset_type ), mCallback( asset_arrived_callback ), mUserdata( userdata ), @@ -75,6 +70,11 @@ struct LLWearableArrivedData // LLWearableList LLWearableList::~LLWearableList() +{ + llassert_always(mList.empty()) ; +} + +void LLWearableList::cleanup() { for_each(mList.begin(), mList.end(), DeletePairedPointer()); mList.clear(); @@ -90,8 +90,7 @@ void LLWearableList::getAsset( const LLAssetID& assetID, const std::string& wear } else { - gAssetStorage->getAssetData( - assetID, + gAssetStorage->getAssetData(assetID, asset_type, LLWearableList::processGetAssetReply, (void*)new LLWearableArrivedData( asset_type, wearable_name, asset_arrived_callback, userdata ), @@ -110,8 +109,7 @@ void LLWearableList::processGetAssetReply( const char* filename, const LLAssetID { LL_WARNS("Wearable") << "Bad Wearable Asset: missing file." << LL_ENDL; } - else - if( status >= 0 ) + else if (status >= 0) { // read the file LLFILE* fp = LLFile::fopen(std::string(filename), "rb"); /*Flawfinder: ignore*/ @@ -180,7 +178,7 @@ void LLWearableList::processGetAssetReply( const char* filename, const LLAssetID if (wearable) // success { - gWearableList.mList[ uuid ] = wearable; + LLWearableList::instance().mList[ uuid ] = wearable; LL_DEBUGS("Wearable") << "processGetAssetReply()" << LL_ENDL; LL_DEBUGS("Wearable") << wearable << LL_ENDL; } diff --git a/indra/newview/llwearablelist.h b/indra/newview/llwearablelist.h index c2a13eb66..890bf18f5 100644 --- a/indra/newview/llwearablelist.h +++ b/indra/newview/llwearablelist.h @@ -37,11 +37,19 @@ #include "lluuid.h" #include "llassetstorage.h" -class LLWearableList +// Globally constructed; be careful that there's no dependency with gAgent. +/* + BUG: mList's system of mapping between assetIDs and wearables is flawed + since LLWearable* has an associated itemID, and you can have multiple + inventory items pointing to the same asset (i.e. more than one ItemID + per assetID). EXT-6252 +*/ +class LLWearableList : public LLSingleton { public: LLWearableList() {} ~LLWearableList(); + void cleanup() ; S32 getLength() { return mList.size(); } @@ -62,9 +70,7 @@ public: protected: LLWearable* generateNewWearable(); // used for the create... functions private: - std::map< LLUUID, LLWearable* > mList; + std::map mList; }; -extern LLWearableList gWearableList; - #endif // LL_LLWEARABLELIST_H diff --git a/indra/newview/rlvhelper.cpp b/indra/newview/rlvhelper.cpp index dba0db371..2d264b879 100644 --- a/indra/newview/rlvhelper.cpp +++ b/indra/newview/rlvhelper.cpp @@ -845,14 +845,14 @@ void RlvForceWear::done() return; } - // If all the assets are available locally then "pWearData" will be freed *before* the last "gWearableList.getAsset()" call returns + // If all the assets are available locally then "pWearData" will be freed *before* the last "LLWearableList::instance().getAsset()" call returns bool fContinue = true; LLWearableHoldingPattern::found_list_t::const_iterator itWearable = pWearData->mFoundList.begin(); while ( (fContinue) && (itWearable != pWearData->mFoundList.end()) ) { const LLFoundData* pFound = *itWearable; ++itWearable; fContinue = (itWearable != pWearData->mFoundList.end()); - gWearableList.getAsset(pFound->mAssetID, pFound->mName, pFound->mAssetType, wear_inventory_category_on_avatar_loop, (void*)pWearData); + LLWearableList::instance().getAsset(pFound->mAssetID, pFound->mName, pFound->mAssetType, wear_inventory_category_on_avatar_loop, (void*)pWearData); } m_addWearables.clear(); diff --git a/indra/newview/rlvinventory.cpp b/indra/newview/rlvinventory.cpp index 94327cbd9..fc7b503a1 100644 --- a/indra/newview/rlvinventory.cpp +++ b/indra/newview/rlvinventory.cpp @@ -142,7 +142,7 @@ void RlvInventory::fetchWornItems() // Fetch all currently worn clothing layers and body parts for (int type = 0; type < LLWearableType::WT_COUNT; type++) { - const LLUUID& idItem = gAgentWearables.getWearableItemID((LLWearableType::EType)type); + const LLUUID idItem = gAgentWearables.getWearableItemID((LLWearableType::EType)type); if (idItem.notNull()) idItems.push_back(idItem); }