diff options
Diffstat (limited to 'indra/newview/llinventorymodel.cpp')
-rw-r--r-- | indra/newview/llinventorymodel.cpp | 1248 |
1 files changed, 130 insertions, 1118 deletions
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index 961f7adc0a..53835f0166 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -2,31 +2,25 @@ * @file llinventorymodel.cpp * @brief Implementation of the inventory model used to track agent inventory. * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -35,6 +29,7 @@ #include "llagent.h" #include "llagentwearables.h" +#include "llappearancemgr.h" #include "llinventorypanel.h" #include "llinventorybridge.h" #include "llinventoryfunctions.h" @@ -57,32 +52,16 @@ #include "process.h" #endif -BOOL LLInventoryModel::sBackgroundFetchActive = FALSE; -BOOL LLInventoryModel::sAllFoldersFetched = FALSE; -BOOL LLInventoryModel::sMyInventoryFetchStarted = FALSE; -BOOL LLInventoryModel::sLibraryFetchStarted = FALSE; -S32 LLInventoryModel::sNumFetchRetries = 0; -F32 LLInventoryModel::sMinTimeBetweenFetches = 0.3f; -F32 LLInventoryModel::sMaxTimeBetweenFetches = 10.f; -BOOL LLInventoryModel::sTimelyFetchPending = FALSE; -LLFrameTimer LLInventoryModel::sFetchTimer; -S16 LLInventoryModel::sBulkFetchCount = 0; -BOOL LLInventoryModel::sFirstTimeInViewer2 = TRUE; - // Increment this if the inventory contents change in a non-backwards-compatible way. // For viewer 2, the addition of link items makes a pre-viewer-2 cache incorrect. const S32 LLInventoryModel::sCurrentInvCacheVersion = 2; - -// RN: for some reason, using std::queue in the header file confuses the compiler which things it's an xmlrpc_queue -static std::deque<LLUUID> sFetchQueue; +BOOL LLInventoryModel::sFirstTimeInViewer2 = TRUE; ///---------------------------------------------------------------------------- /// Local function declarations, constants, enums, and typedefs ///---------------------------------------------------------------------------- //BOOL decompress_file(const char* src_filename, const char* dst_filename); -const F32 MAX_TIME_FOR_SINGLE_FETCH = 10.f; -const S32 MAX_FETCH_RETRIES = 10; const char CACHE_FORMAT_STRING[] = "%s.inv"; struct InventoryIDPtrLess @@ -218,7 +197,10 @@ BOOL LLInventoryModel::isObjectDescendentOf(const LLUUID& obj_id, const LLViewerInventoryCategory *LLInventoryModel::getFirstNondefaultParent(const LLUUID& obj_id) const { const LLInventoryObject* obj = getObject(obj_id); - const LLUUID& parent_id = obj->getParentUUID(); + + // Search up the parent chain until we get to root or an acceptable folder. + // This assumes there are no cycles in the tree else we'll get a hang. + LLUUID parent_id = obj->getParentUUID(); while (!parent_id.isNull()) { const LLViewerInventoryCategory *cat = getCategory(parent_id); @@ -230,6 +212,7 @@ const LLViewerInventoryCategory *LLInventoryModel::getFirstNondefaultParent(cons { return cat; } + parent_id = cat->getParentUUID(); } return NULL; } @@ -305,6 +288,30 @@ void LLInventoryModel::getDirectDescendentsOf(const LLUUID& cat_id, items = get_ptr_in_map(mParentChildItemTree, cat_id); } +LLMD5 LLInventoryModel::hashDirectDescendentNames(const LLUUID& cat_id) const +{ + LLInventoryModel::cat_array_t* cat_array; + LLInventoryModel::item_array_t* item_array; + getDirectDescendentsOf(cat_id,cat_array,item_array); + LLMD5 item_name_hash; + if (!item_array) + { + item_name_hash.finalize(); + return item_name_hash; + } + for (LLInventoryModel::item_array_t::const_iterator iter = item_array->begin(); + iter != item_array->end(); + iter++) + { + const LLViewerInventoryItem *item = (*iter); + if (!item) + continue; + item_name_hash.update(item->getName()); + } + item_name_hash.finalize(); + return item_name_hash; +} + // SJB: Added version to lock the arrays to catch potential logic bugs void LLInventoryModel::lockDirectDescendentArrays(const LLUUID& cat_id, cat_array_t*& categories, @@ -331,30 +338,18 @@ void LLInventoryModel::unlockDirectDescendentArrays(const LLUUID& cat_id) // specifies 'type' as what it defaults to containing. The category is // not necessarily only for that type. *NOTE: This will create a new // inventory category on the fly if one does not exist. -const LLUUID LLInventoryModel::findCategoryUUIDForType(LLFolderType::EType t, bool create_folder, bool find_in_library) -{ - const LLUUID &rv = findCatUUID(t, find_in_library); - if(rv.isNull() && isInventoryUsable() && (create_folder && !find_in_library)) - { - const LLUUID &root_id = gInventory.getRootFolderID(); - if(root_id.notNull()) - { - return createNewCategory(root_id, t, LLStringUtil::null); - } - } - return rv; -} - -// Internal method which looks for a category with the specified -// preferred type. Returns LLUUID::null if not found. -const LLUUID &LLInventoryModel::findCatUUID(LLFolderType::EType preferred_type, bool find_in_library) const +const LLUUID LLInventoryModel::findCategoryUUIDForType(LLFolderType::EType preferred_type, + bool create_folder, + bool find_in_library) { + LLUUID rv = LLUUID::null; + const LLUUID &root_id = (find_in_library) ? gInventory.getLibraryRootFolderID() : gInventory.getRootFolderID(); if(LLFolderType::FT_ROOT_INVENTORY == preferred_type) { - return root_id; + rv = root_id; } - if(root_id.notNull()) + else if (root_id.notNull()) { cat_array_t* cats = NULL; cats = get_ptr_in_map(mParentChildCategoryTree, root_id); @@ -365,12 +360,21 @@ const LLUUID &LLInventoryModel::findCatUUID(LLFolderType::EType preferred_type, { if(cats->get(i)->getPreferredType() == preferred_type) { - return cats->get(i)->getUUID(); + rv = cats->get(i)->getUUID(); + break; } } } } - return LLUUID::null; + + if(rv.isNull() && isInventoryUsable() && (create_folder && !find_in_library)) + { + if(root_id.notNull()) + { + return createNewCategory(root_id, preferred_type, LLStringUtil::null); + } + } + return rv; } // Convenience function to create a new category. You could call @@ -497,7 +501,7 @@ void LLInventoryModel::collectDescendentsIf(const LLUUID& id, for(S32 i = 0; i < count; ++i) { item = item_array->get(i); - if (item->getActualType() == LLAssetType::AT_LINK_FOLDER) + if (item && item->getActualType() == LLAssetType::AT_LINK_FOLDER) { LLViewerInventoryCategory *linked_cat = item->getLinkedCategory(); if (linked_cat && linked_cat->getPreferredType() != LLFolderType::FT_OUTFIT) @@ -581,6 +585,11 @@ const LLUUID& LLInventoryModel::getLinkedItemID(const LLUUID& object_id) const return item->getLinkedUUID(); } +LLViewerInventoryItem* LLInventoryModel::getLinkedItem(const LLUUID& object_id) const +{ + return object_id.notNull() ? getItem(getLinkedItemID(object_id)) : NULL; +} + LLInventoryModel::item_array_t LLInventoryModel::collectLinkedItems(const LLUUID& id, const LLUUID& start_folder_id) { @@ -595,27 +604,6 @@ LLInventoryModel::item_array_t LLInventoryModel::collectLinkedItems(const LLUUID return items; } -// Generates a string containing the path to the item specified by -// item_id. -void LLInventoryModel::appendPath(const LLUUID& id, std::string& path) const -{ - std::string temp; - const LLInventoryObject* obj = getObject(id); - LLUUID parent_id; - if(obj) parent_id = obj->getParentUUID(); - std::string forward_slash("/"); - while(obj) - { - obj = getCategory(parent_id); - if(obj) - { - temp.assign(forward_slash + obj->getName() + temp); - parent_id = obj->getParentUUID(); - } - } - path.append(temp); -} - bool LLInventoryModel::isInventoryUsable() const { bool result = false; @@ -751,8 +739,20 @@ U32 LLInventoryModel::updateItem(const LLViewerInventoryItem* item) // Valid UUID; set the item UUID and rename it new_item->setCreator(id); std::string avatar_name; - // Fetch the currect name - gCacheName->get(id, FALSE, boost::bind(&LLViewerInventoryItem::onCallingCardNameLookup, new_item.get(), _1, _2, _3)); + + if (gCacheName->getFullName(id, avatar_name)) + { + new_item->rename(avatar_name); + mask |= LLInventoryObserver::LABEL; + } + else + { + // Fetch the current name + gCacheName->get(id, FALSE, + boost::bind(&LLViewerInventoryItem::onCallingCardNameLookup, new_item.get(), + _1, _2, _3)); + } + } } else if (new_item->getType() == LLAssetType::AT_GESTURE) @@ -1036,98 +1036,6 @@ void LLInventoryModel::purgeDescendentsOf(const LLUUID& id) } } -void LLInventoryModel::deleteFromServer(LLDynamicArray<LLUUID>& category_ids, - LLDynamicArray<LLUUID>& item_ids) -{ - // Store off tre UUIDS of parents which are being deleted (thus no - // need to increment) and the parents which are being modified. We - // have to increment the version of the parent with each message - // sent upstream since the dataserver will increment each unique - // parent per update message. - std::set<LLUUID> ignore_parents; - update_map_t inc_parents; - - S32 i; - S32 count = category_ids.count(); - BOOL start_new_message = TRUE; - LLMessageSystem* msg = gMessageSystem; - LLPointer<LLViewerInventoryCategory> cat; - for(i = 0; i < count; i++) - { - if(start_new_message) - { - start_new_message = FALSE; - msg->newMessageFast(_PREHASH_RemoveInventoryObjects); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - } - LLUUID cat_id = category_ids.get(i); - - msg->nextBlockFast(_PREHASH_FolderData); - msg->addUUIDFast(_PREHASH_FolderID, cat_id); - cat = getCategory(cat_id); - ignore_parents.insert(cat_id); - addChangedMask(LLInventoryObserver::REMOVE | LLInventoryObserver::STRUCTURE, cat_id); - if(cat.notNull() && (ignore_parents.find(cat->getParentUUID())==ignore_parents.end())) - { - --inc_parents[cat->getParentUUID()]; - } - if(msg->isSendFullFast(_PREHASH_FolderData)) - { - start_new_message = TRUE; - msg->nextBlockFast(_PREHASH_ItemData); - msg->addUUIDFast(_PREHASH_ItemID, LLUUID::null); - gAgent.sendReliableMessage(); - accountForUpdate(inc_parents); - inc_parents.clear(); - } - } - - count = item_ids.count(); - std::set<LLUUID>::iterator not_ignored = ignore_parents.end(); - LLPointer<LLViewerInventoryItem> item; - if((0 == count) && (!start_new_message)) - { - msg->nextBlockFast(_PREHASH_ItemData); - msg->addUUIDFast(_PREHASH_ItemID, LLUUID::null); - } - for(i = 0; i < count; i++) - { - if(start_new_message) - { - start_new_message = FALSE; - msg->newMessageFast(_PREHASH_RemoveInventoryObjects); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->nextBlockFast(_PREHASH_FolderData); - msg->addUUIDFast(_PREHASH_FolderID, LLUUID::null); - } - LLUUID item_id = item_ids.get(i); - msg->nextBlockFast(_PREHASH_ItemData); - msg->addUUIDFast(_PREHASH_ItemID, item_id); - item = getItem(item_id); - addChangedMask(LLInventoryObserver::REMOVE | LLInventoryObserver::STRUCTURE, item_id); - if(item.notNull() && (ignore_parents.find(item->getParentUUID()) == not_ignored)) - { - --inc_parents[item->getParentUUID()]; - } - if(msg->isSendFullFast(_PREHASH_ItemData)) - { - start_new_message = TRUE; - gAgent.sendReliableMessage(); - accountForUpdate(inc_parents); - inc_parents.clear(); - } - } - if(!start_new_message) - { - gAgent.sendReliableMessage(); - accountForUpdate(inc_parents); - } -} - // Add/remove an observer. If the observer is destroyed, be sure to // remove it. void LLInventoryModel::addObserver(LLInventoryObserver* observer) @@ -1218,29 +1126,7 @@ void LLInventoryModel::addChangedMask(U32 mask, const LLUUID& referent) } } -// This method to prepares a set of mock inventory which provides -// minimal functionality before the actual arrival of inventory. -/* -void LLInventoryModel::mock(const LLUUID& root_id) -{ - llinfos << "LLInventoryModel::mock() " << root_id << llendl; - if(root_id.isNull()) - { - llwarns << "Not a valid root id" << llendl; - return; - } - LLPointer<LLViewerInventoryCategory> cat = new LLViewerInventoryCategory( - root_id, - LLUUID::null, - LLAssetType::AT_CATEGORY, - LLFolderType::lookupNewCategoryName(LLFolderType::FT_ROOT_INVENTORY), - gAgent.getID()); - addCategory(cat); - gInventory.buildParentChildMap(); -} -*/ - -//If we get back a normal response, handle it here +// If we get back a normal response, handle it here void LLInventoryModel::fetchInventoryResponder::result(const LLSD& content) { start_new_inventory_observer(); @@ -1313,7 +1199,7 @@ void LLInventoryModel::fetchInventoryResponder::error(U32 status, const std::str gInventory.notifyObservers("fetchinventory"); } -bool LLInventoryModel::fetchDescendentsOf(const LLUUID& folder_id) +bool LLInventoryModel::fetchDescendentsOf(const LLUUID& folder_id) const { if(folder_id.isNull()) { @@ -1338,544 +1224,7 @@ bool LLInventoryModel::fetchDescendentsOf(const LLUUID& folder_id) //{ // known_descendents += items->count(); //} - return cat->fetchDescendents(); -} - -//Initialize statics. -bool LLInventoryModel::isBulkFetchProcessingComplete() -{ - return sFetchQueue.empty() && sBulkFetchCount<=0; -} - -class LLInventoryModelFetchDescendentsResponder: public LLHTTPClient::Responder -{ - public: - LLInventoryModelFetchDescendentsResponder(const LLSD& request_sd) : mRequestSD(request_sd) {}; - //LLInventoryModelFetchDescendentsResponder() {}; - void result(const LLSD& content); - void error(U32 status, const std::string& reason); - public: - typedef std::vector<LLViewerInventoryCategory*> folder_ref_t; - protected: - LLSD mRequestSD; -}; - -//If we get back a normal response, handle it here -void LLInventoryModelFetchDescendentsResponder::result(const LLSD& content) -{ - if (content.has("folders")) - { - - for(LLSD::array_const_iterator folder_it = content["folders"].beginArray(); - folder_it != content["folders"].endArray(); - ++folder_it) - { - LLSD folder_sd = *folder_it; - - - //LLUUID agent_id = folder_sd["agent_id"]; - - //if(agent_id != gAgent.getID()) //This should never happen. - //{ - // llwarns << "Got a UpdateInventoryItem for the wrong agent." - // << llendl; - // break; - //} - - LLUUID parent_id = folder_sd["folder_id"]; - LLUUID owner_id = folder_sd["owner_id"]; - S32 version = (S32)folder_sd["version"].asInteger(); - S32 descendents = (S32)folder_sd["descendents"].asInteger(); - LLPointer<LLViewerInventoryCategory> tcategory = new LLViewerInventoryCategory(owner_id); - - if (parent_id.isNull()) - { - LLPointer<LLViewerInventoryItem> titem = new LLViewerInventoryItem; - for(LLSD::array_const_iterator item_it = folder_sd["items"].beginArray(); - item_it != folder_sd["items"].endArray(); - ++item_it) - { - const LLUUID lost_uuid = gInventory.findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND); - if (lost_uuid.notNull()) - { - LLSD item = *item_it; - titem->unpackMessage(item); - - LLInventoryModel::update_list_t update; - LLInventoryModel::LLCategoryUpdate new_folder(lost_uuid, 1); - update.push_back(new_folder); - gInventory.accountForUpdate(update); - - titem->setParent(lost_uuid); - titem->updateParentOnServer(FALSE); - gInventory.updateItem(titem); - gInventory.notifyObservers("fetchDescendents"); - - } - } - } - - LLViewerInventoryCategory* pcat = gInventory.getCategory(parent_id); - if (!pcat) - { - continue; - } - - for(LLSD::array_const_iterator category_it = folder_sd["categories"].beginArray(); - category_it != folder_sd["categories"].endArray(); - ++category_it) - { - LLSD category = *category_it; - tcategory->fromLLSD(category); - - if (LLInventoryModel::sMyInventoryFetchStarted || - LLInventoryModel::sLibraryFetchStarted) - { - sFetchQueue.push_back(tcategory->getUUID()); - } - else if ( !gInventory.isCategoryComplete(tcategory->getUUID()) ) - { - gInventory.updateCategory(tcategory); - } - - } - LLPointer<LLViewerInventoryItem> titem = new LLViewerInventoryItem; - for(LLSD::array_const_iterator item_it = folder_sd["items"].beginArray(); - item_it != folder_sd["items"].endArray(); - ++item_it) - { - LLSD item = *item_it; - titem->unpackMessage(item); - - gInventory.updateItem(titem); - } - - // set version and descendentcount according to message. - LLViewerInventoryCategory* cat = gInventory.getCategory(parent_id); - if(cat) - { - cat->setVersion(version); - cat->setDescendentCount(descendents); - cat->determineFolderType(); - } - - } - } - - if (content.has("bad_folders")) - { - for(LLSD::array_const_iterator folder_it = content["bad_folders"].beginArray(); - folder_it != content["bad_folders"].endArray(); - ++folder_it) - { - LLSD folder_sd = *folder_it; - - //These folders failed on the dataserver. We probably don't want to retry them. - llinfos << "Folder " << folder_sd["folder_id"].asString() - << "Error: " << folder_sd["error"].asString() << llendl; - } - } - - LLInventoryModel::incrBulkFetch(-1); - - if (LLInventoryModel::isBulkFetchProcessingComplete()) - { - llinfos << "Inventory fetch completed" << llendl; - LLInventoryModel::setAllFoldersFetched(); - } - - gInventory.notifyObservers("fetchDescendents"); -} - -//If we get back an error (not found, etc...), handle it here -void LLInventoryModelFetchDescendentsResponder::error(U32 status, const std::string& reason) -{ - llinfos << "LLInventoryModelFetchDescendentsResponder::error " - << status << ": " << reason << llendl; - - LLInventoryModel::incrBulkFetch(-1); - - if (status==499) //timed out. Let's be awesome! - { - for(LLSD::array_const_iterator folder_it = mRequestSD["folders"].beginArray(); - folder_it != mRequestSD["folders"].endArray(); - ++folder_it) - { - LLSD folder_sd = *folder_it; - LLUUID folder_id = folder_sd["folder_id"]; - sFetchQueue.push_front(folder_id); - } - } - else - { - if (LLInventoryModel::isBulkFetchProcessingComplete()) - { - LLInventoryModel::setAllFoldersFetched(); - } - } - gInventory.notifyObservers("fetchDescendents"); -} - -//static Bundle up a bunch of requests to send all at once. -void LLInventoryModel::bulkFetch(std::string url) -{ - //Background fetch is called from gIdleCallbacks in a loop until background fetch is stopped. - //If there are items in sFetchQueue, we want to check the time since the last bulkFetch was - //sent. If it exceeds our retry time, go ahead and fire off another batch. - //Stopbackgroundfetch will be run from the Responder instead of here. - - S16 max_concurrent_fetches=8; - F32 new_min_time = 0.5f; //HACK! Clean this up when old code goes away entirely. - if (sMinTimeBetweenFetches < new_min_time) sMinTimeBetweenFetches=new_min_time; //HACK! See above. - - if(gDisconnected - || sBulkFetchCount > max_concurrent_fetches - || sFetchTimer.getElapsedTimeF32() < sMinTimeBetweenFetches) - { - return; // just bail if we are disconnected. - } - - U32 folder_count=0; - U32 max_batch_size=5; - - U32 sort_order = gSavedSettings.getU32("InventorySortOrder") & 0x1; - - LLSD body; - LLSD body_lib; - while( !(sFetchQueue.empty() ) && (folder_count < max_batch_size) ) - { - if (sFetchQueue.front().isNull()) //DEV-17797 - { - LLSD folder_sd; - folder_sd["folder_id"] = LLUUID::null.asString(); - folder_sd["owner_id"] = gAgent.getID(); - folder_sd["sort_order"] = (LLSD::Integer)sort_order; - folder_sd["fetch_folders"] = (LLSD::Boolean)FALSE; - folder_sd["fetch_items"] = (LLSD::Boolean)TRUE; - body["folders"].append(folder_sd); - folder_count++; - } - else - { - - - LLViewerInventoryCategory* cat = gInventory.getCategory(sFetchQueue.front()); - - if (cat) - { - if ( LLViewerInventoryCategory::VERSION_UNKNOWN == cat->getVersion()) - { - LLSD folder_sd; - folder_sd["folder_id"] = cat->getUUID(); - folder_sd["owner_id"] = cat->getOwnerID(); - folder_sd["sort_order"] = (LLSD::Integer)sort_order; - folder_sd["fetch_folders"] = TRUE; //(LLSD::Boolean)sFullFetchStarted; - folder_sd["fetch_items"] = (LLSD::Boolean)TRUE; - - if (ALEXANDRIA_LINDEN_ID == cat->getOwnerID()) - body_lib["folders"].append(folder_sd); - else - body["folders"].append(folder_sd); - folder_count++; - } - if (sMyInventoryFetchStarted || - sLibraryFetchStarted) - { //Already have this folder but append child folders to list. - // add all children to queue - parent_cat_map_t::iterator cat_it = gInventory.mParentChildCategoryTree.find(cat->getUUID()); - if (cat_it != gInventory.mParentChildCategoryTree.end()) - { - cat_array_t* child_categories = cat_it->second; - - for (S32 child_num = 0; child_num < child_categories->count(); child_num++) - { - sFetchQueue.push_back(child_categories->get(child_num)->getUUID()); - } - } - - } - } - } - sFetchQueue.pop_front(); - } - - if (folder_count > 0) - { - sBulkFetchCount++; - if (body["folders"].size()) - { - LLHTTPClient::post(url, body, new LLInventoryModelFetchDescendentsResponder(body),300.0); - } - if (body_lib["folders"].size()) - { - std::string url_lib = gAgent.getRegion()->getCapability("FetchLibDescendents"); - LLHTTPClient::post(url_lib, body_lib, new LLInventoryModelFetchDescendentsResponder(body_lib),300.0); - } - sFetchTimer.reset(); - } - else if (isBulkFetchProcessingComplete()) - { - setAllFoldersFetched(); - } -} - -bool fetchQueueContainsNoDescendentsOf(const LLUUID& cat_id) -{ - for (std::deque<LLUUID>::iterator it = sFetchQueue.begin(); - it != sFetchQueue.end(); ++it) - { - const LLUUID& fetch_id = *it; - if (gInventory.isObjectDescendentOf(fetch_id, cat_id)) - return false; - } - return true; -} - -/* static */ -bool LLInventoryModel::libraryFetchStarted() -{ - return sLibraryFetchStarted; -} - -/* static */ -bool LLInventoryModel::libraryFetchCompleted() -{ - return libraryFetchStarted() && fetchQueueContainsNoDescendentsOf(gInventory.getLibraryRootFolderID()); -} - -/* static */ -bool LLInventoryModel::libraryFetchInProgress() -{ - return libraryFetchStarted() && !libraryFetchCompleted(); -} - -/* static */ -bool LLInventoryModel::myInventoryFetchStarted() -{ - return sMyInventoryFetchStarted; -} - -/* static */ -bool LLInventoryModel::myInventoryFetchCompleted() -{ - return myInventoryFetchStarted() && fetchQueueContainsNoDescendentsOf(gInventory.getRootFolderID()); -} - -/* static */ -bool LLInventoryModel::myInventoryFetchInProgress() -{ - return myInventoryFetchStarted() && !myInventoryFetchCompleted(); -} - -// static -bool LLInventoryModel::isEverythingFetched() -{ - return sAllFoldersFetched; -} - -//static -BOOL LLInventoryModel::backgroundFetchActive() -{ - return sBackgroundFetchActive; -} - -void LLInventoryModel::startBackgroundFetch(const LLUUID& cat_id) -{ - if (!sAllFoldersFetched) - { - sBackgroundFetchActive = TRUE; - if (cat_id.isNull()) - { - if (!sMyInventoryFetchStarted) - { - sMyInventoryFetchStarted = TRUE; - sFetchQueue.push_back(gInventory.getRootFolderID()); - gIdleCallbacks.addFunction(&LLInventoryModel::backgroundFetch, NULL); - } - if (!sLibraryFetchStarted) - { - sLibraryFetchStarted = TRUE; - sFetchQueue.push_back(gInventory.getLibraryRootFolderID()); - gIdleCallbacks.addFunction(&LLInventoryModel::backgroundFetch, NULL); - } - } - else - { - // specific folder requests go to front of queue - if (sFetchQueue.empty() || sFetchQueue.front() != cat_id) - { - sFetchQueue.push_front(cat_id); - gIdleCallbacks.addFunction(&LLInventoryModel::backgroundFetch, NULL); - } - if (cat_id == gInventory.getLibraryRootFolderID()) - { - sLibraryFetchStarted = TRUE; - } - if (cat_id == gInventory.getRootFolderID()) - { - sMyInventoryFetchStarted = TRUE; - } - } - } -} - -//static -void LLInventoryModel::findLostItems() -{ - sBackgroundFetchActive = TRUE; - sFetchQueue.push_back(LLUUID::null); - gIdleCallbacks.addFunction(&LLInventoryModel::backgroundFetch, NULL); -} - -//static -void LLInventoryModel::stopBackgroundFetch() -{ - if (sBackgroundFetchActive) - { - sBackgroundFetchActive = FALSE; - gIdleCallbacks.deleteFunction(&LLInventoryModel::backgroundFetch, NULL); - sBulkFetchCount=0; - sMinTimeBetweenFetches=0.0f; - } -} - -// static -void LLInventoryModel::setAllFoldersFetched() -{ - if (sMyInventoryFetchStarted && - sLibraryFetchStarted) - { - sAllFoldersFetched = TRUE; - } - stopBackgroundFetch(); -} - -//static -void LLInventoryModel::backgroundFetch(void*) -{ - if (sBackgroundFetchActive && gAgent.getRegion()) - { - //If we'll be using the capability, we'll be sending batches and the background thing isn't as important. - std::string url = gAgent.getRegion()->getCapability("WebFetchInventoryDescendents"); - if (!url.empty()) - { - bulkFetch(url); - return; - } - - //DEPRECATED OLD CODE FOLLOWS. - // no more categories to fetch, stop fetch process - if (sFetchQueue.empty()) - { - llinfos << "Inventory fetch completed" << llendl; - - setAllFoldersFetched(); - return; - } - - F32 fast_fetch_time = lerp(sMinTimeBetweenFetches, sMaxTimeBetweenFetches, 0.1f); - F32 slow_fetch_time = lerp(sMinTimeBetweenFetches, sMaxTimeBetweenFetches, 0.5f); - if (sTimelyFetchPending && sFetchTimer.getElapsedTimeF32() > slow_fetch_time) - { - // double timeouts on failure - sMinTimeBetweenFetches = llmin(sMinTimeBetweenFetches * 2.f, 10.f); - sMaxTimeBetweenFetches = llmin(sMaxTimeBetweenFetches * 2.f, 120.f); - llinfos << "Inventory fetch times grown to (" << sMinTimeBetweenFetches << ", " << sMaxTimeBetweenFetches << ")" << llendl; - // fetch is no longer considered "timely" although we will wait for full time-out - sTimelyFetchPending = FALSE; - } - - while(1) - { - if (sFetchQueue.empty()) - { - break; - } - - if(gDisconnected) - { - // just bail if we are disconnected. - break; - } - - LLViewerInventoryCategory* cat = gInventory.getCategory(sFetchQueue.front()); - - // category has been deleted, remove from queue. - if (!cat) - { - sFetchQueue.pop_front(); - continue; - } - - if (sFetchTimer.getElapsedTimeF32() > sMinTimeBetweenFetches && - LLViewerInventoryCategory::VERSION_UNKNOWN == cat->getVersion()) - { - // category exists but has no children yet, fetch the descendants - // for now, just request every time and rely on retry timer to throttle - if (cat->fetchDescendents()) - { - sFetchTimer.reset(); - sTimelyFetchPending = TRUE; - } - else - { - // The catagory also tracks if it has expired and here it says it hasn't - // yet. Get out of here because nothing is going to happen until we - // update the timers. - break; - } - } - // do I have all my children? - else if (gInventory.isCategoryComplete(sFetchQueue.front())) - { - // finished with this category, remove from queue - sFetchQueue.pop_front(); - - // add all children to queue - parent_cat_map_t::iterator cat_it = gInventory.mParentChildCategoryTree.find(cat->getUUID()); - if (cat_it != gInventory.mParentChildCategoryTree.end()) - { - cat_array_t* child_categories = cat_it->second; - - for (S32 child_num = 0; child_num < child_categories->count(); child_num++) - { - sFetchQueue.push_back(child_categories->get(child_num)->getUUID()); - } - } - - // we received a response in less than the fast time - if (sTimelyFetchPending && sFetchTimer.getElapsedTimeF32() < fast_fetch_time) - { - // shrink timeouts based on success - sMinTimeBetweenFetches = llmax(sMinTimeBetweenFetches * 0.8f, 0.3f); - sMaxTimeBetweenFetches = llmax(sMaxTimeBetweenFetches * 0.8f, 10.f); - //llinfos << "Inventory fetch times shrunk to (" << sMinTimeBetweenFetches << ", " << sMaxTimeBetweenFetches << ")" << llendl; - } - - sTimelyFetchPending = FALSE; - continue; - } - else if (sFetchTimer.getElapsedTimeF32() > sMaxTimeBetweenFetches) - { - // received first packet, but our num descendants does not match db's num descendants - // so try again later - LLUUID fetch_id = sFetchQueue.front(); - sFetchQueue.pop_front(); - - if (sNumFetchRetries++ < MAX_FETCH_RETRIES) - { - // push on back of queue - sFetchQueue.push_back(fetch_id); - } - sTimelyFetchPending = FALSE; - sFetchTimer.reset(); - break; - } - - // not enough time has elapsed to do a new fetch - break; - } - } + return cat->fetch(); } void LLInventoryModel::cache( @@ -1923,6 +1272,9 @@ void LLInventoryModel::addCategory(LLViewerInventoryCategory* category) //llinfos << "LLInventoryModel::addCategory()" << llendl; if(category) { + // try to localize default names first. See EXT-8319, EXT-7051. + category->localizeName(); + // Insert category uniquely into the map mCategoryMap[category->getUUID()] = category; // LLPointer will deref and delete the old one //mInventory[category->getUUID()] = category; @@ -1931,25 +1283,26 @@ void LLInventoryModel::addCategory(LLViewerInventoryCategory* category) void LLInventoryModel::addItem(LLViewerInventoryItem* item) { - //llinfos << "LLInventoryModel::addItem()" << llendl; - - // This can happen if assettype enums from llassettype.h ever change. - // For example, there is a known backwards compatibility issue in some viewer prototypes prior to when - // the AT_LINK enum changed from 23 to 24. - if ((item->getType() == LLAssetType::AT_NONE) - || LLAssetType::lookup(item->getType()) == LLAssetType::badLookup()) - { - llwarns << "Got bad asset type for item [ name: " << item->getName() << " type: " << item->getType() << " inv-type: " << item->getInventoryType() << " ], ignoring." << llendl; - return; - } + llassert(item); if(item) { + // This can happen if assettype enums from llassettype.h ever change. + // For example, there is a known backwards compatibility issue in some viewer prototypes prior to when + // the AT_LINK enum changed from 23 to 24. + if ((item->getType() == LLAssetType::AT_NONE) + || LLAssetType::lookup(item->getType()) == LLAssetType::badLookup()) + { + llwarns << "Got bad asset type for item [ name: " << item->getName() << " type: " << item->getType() << " inv-type: " << item->getInventoryType() << " ], ignoring." << llendl; + return; + } + // This condition means that we tried to add a link without the baseobj being in memory. // The item will show up as a broken link. if (item->getIsBrokenLink()) { llinfos << "Adding broken link [ name: " << item->getName() << " itemID: " << item->getUUID() << " assetID: " << item->getAssetUUID() << " ) parent: " << item->getParentUUID() << llendl; } + mItemMap[item->getUUID()] = item; } } @@ -2328,6 +1681,17 @@ bool LLInventoryModel::loadSkeleton( } } + // Invalidate all categories that failed fetching descendents for whatever + // reason (e.g. one of the descendents was a broken link). + for (cat_set_t::iterator invalid_cat_it = invalid_categories.begin(); + invalid_cat_it != invalid_categories.end(); + invalid_cat_it++) + { + LLViewerInventoryCategory* cat = (*invalid_cat_it).get(); + cat->setVersion(NO_VERSION); + llinfos << "Invalidating category name: " << cat->getName() << " UUID: " << cat->getUUID() << " due to invalid descendents cache" << llendl; + } + // At this point, we need to set the known descendents for each // category which successfully cached so that we do not // needlessly fetch descendents for categories which we have. @@ -2350,17 +1714,6 @@ bool LLInventoryModel::loadSkeleton( } } - // Invalidate all categories that failed fetching descendents for whatever - // reason (e.g. one of the descendents was a broken link). - for (cat_set_t::iterator invalid_cat_it = invalid_categories.begin(); - invalid_cat_it != invalid_categories.end(); - invalid_cat_it++) - { - LLViewerInventoryCategory* cat = (*invalid_cat_it).get(); - cat->setVersion(NO_VERSION); - llinfos << "Invalidating category name: " << cat->getName() << " UUID: " << cat->getUUID() << " due to invalid descendents cache" << llendl; - } - if(remove_inventory_file) { // clean up the gunzipped file. @@ -2382,88 +1735,6 @@ bool LLInventoryModel::loadSkeleton( return rv; } -bool LLInventoryModel::loadMeat(const LLSD& options, const LLUUID& owner_id) -{ - llinfos << "importing inventory for " << owner_id << llendl; - bool rv = true; - for(LLSD::array_const_iterator it = options.beginArray(), - end = options.endArray(); it != end; ++it) - { - LLSD name = (*it)["name"]; - LLSD item_id = (*it)["item_id"]; - LLSD parent_id = (*it)["parent_id"]; - LLSD asset_type = (*it)["type"]; - LLSD data_id = (*it)["data_id"]; - if(name.isDefined() - && item_id.isDefined() - && parent_id.isDefined() - && asset_type.isDefined() - && data_id.isDefined()) - { - LLPointer<LLViewerInventoryItem> item = new LLViewerInventoryItem; - item->rename(name.asString()); - item->setUUID(item_id.asUUID()); - item->setParent(parent_id.asUUID()); - LLAssetType::EType type = (LLAssetType::EType)asset_type.asInteger(); - item->setType(type); - - LLSD llsd_inv_type = (*it)["inv_type"]; - if(llsd_inv_type.isDefined()) - { - LLInventoryType::EType inv_type = (LLInventoryType::EType)llsd_inv_type.asInteger(); - item->setInventoryType(inv_type); - } - - if(LLAssetType::AT_CALLINGCARD == type) - { - LLPermissions perm; - perm.init(data_id.asUUID(), owner_id, LLUUID::null, LLUUID::null); - item->setPermissions(perm); - } - else - { - LLPermissions default_perm; - default_perm.init(LLUUID::null, owner_id, LLUUID::null, LLUUID::null); - LLSD llsd_perm_mask = (*it)["perm_mask"]; - if(llsd_perm_mask.isDefined()) - { - PermissionMask perm_mask = llsd_perm_mask.asInteger(); - default_perm.initMasks( - perm_mask, perm_mask, perm_mask, perm_mask, perm_mask); - } - else - { - default_perm.initMasks( - PERM_NONE, PERM_NONE, PERM_NONE, PERM_NONE, PERM_NONE); - } - item->setPermissions(default_perm); - item->setAssetUUID(data_id.asUUID()); - } - - LLSD flags = (*it)["flags"]; - if(flags.isDefined()) - { - // Not sure how well LLSD.asInteger() maps to - // unsigned long - using strtoul() - item->setFlags(strtoul(flags.asString().c_str(), NULL, 0)); - } - - LLSD time = (*it)["time"]; - if(time.isDefined()) - { - item->setCreationDate(time.asInteger()); - } - addItem(item); - } - else - { - llwarns << "Unable to import near " << name.asString() << llendl; - rv = false; - } - } - return rv; -} - // This is a brute force method to rebuild the entire parent-child // relations. The overall operation has O(NlogN) performance, which // should be sufficient for our needs. @@ -2588,7 +1859,7 @@ void LLInventoryModel::buildParentChildMap() } count = items.count(); lost = 0; - std::vector<LLUUID> lost_item_ids; + uuid_vec_t lost_item_ids; for(i = 0; i < count; ++i) { LLPointer<LLViewerInventoryItem> item; @@ -2627,7 +1898,7 @@ void LLInventoryModel::buildParentChildMap() LLMessageSystem* msg = gMessageSystem; BOOL start_new_message = TRUE; const LLUUID lnf = findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND); - for(std::vector<LLUUID>::iterator it = lost_item_ids.begin() ; it < lost_item_ids.end(); ++it) + for(uuid_vec_t::iterator it = lost_item_ids.begin() ; it < lost_item_ids.end(); ++it) { if(start_new_message) { @@ -2731,73 +2002,6 @@ bool LLUUIDAndName::operator>(const LLUUIDAndName& rhs) const return (mID > rhs.mID); } -// Given the current state of the inventory items, figure out the -// clone information. *FIX: This is sub-optimal, since we can insert -// this information snurgically, but this makes sure the implementation -// works before we worry about optimization. -//void LLInventoryModel::recalculateCloneInformation() -//{ -// //dumpInventory(); -// -// // This implements a 'multi-map' like structure to keep track of -// // how many clones we find. -// typedef LLDynamicArray<LLViewerInventoryItem*> viewer_item_array_t; -// typedef std::map<LLUUIDAndName, viewer_item_array_t*> clone_map_t; -// clone_map_t clone_map; -// LLUUIDAndName id_and_name; -// viewer_item_array_t* clones = NULL; -// LLViewerInventoryItem* item = NULL; -// for(item = (LLViewerInventoryItem*)mItemMap.getFirstData(); -// item != NULL; -// item = (LLViewerInventoryItem*)mItemMap.getNextData()) -// { -// if(item->getType() == LLAssetType::AT_CALLINGCARD) -// { -// // if it's a calling card, we key off of the creator id, not -// // the asset id. -// id_and_name.mID = item->getCreatorUUID(); -// } -// else -// { -// // if it's not a calling card, we key clones from the -// // asset id. -// id_and_name.mID = item->getAssetUUID(); -// } -// if(id_and_name.mID == LLUUID::null) -// { -// continue; -// } -// id_and_name.mName = item->getName(); -// if(clone_map.checkData(id_and_name)) -// { -// clones = clone_map.getData(id_and_name); -// } -// else -// { -// clones = new viewer_item_array_t; -// clone_map.addData(id_and_name, clones); -// } -// clones->put(item); -// } -// -// S32 count = 0; -// for(clones = clone_map.getFirstData(); -// clones != NULL; -// clones = clone_map.getNextData()) -// { -// count = clones->count(); -// for(S32 i = 0; i < count; i++) -// { -// item = clones->get(i); -// item->setCloneCount(count - 1); -// //clones[i] = NULL; -// } -// delete clones; -// } -// clone_map.removeAllData(); -// //dumpInventory(); -//} - // static bool LLInventoryModel::loadFromFile(const std::string& filename, LLInventoryModel::cat_array_t& categories, @@ -3087,7 +2291,7 @@ void LLInventoryModel::processRemoveInventoryItem(LLMessageSystem* msg, void**) return; } S32 count = msg->getNumberOfBlocksFast(_PREHASH_InventoryData); - std::vector<LLUUID> item_ids; + uuid_vec_t item_ids; update_map_t update; for(S32 i = 0; i < count; ++i) { @@ -3103,7 +2307,7 @@ void LLInventoryModel::processRemoveInventoryItem(LLMessageSystem* msg, void**) } } gInventory.accountForUpdate(update); - for(std::vector<LLUUID>::iterator it = item_ids.begin(); it != item_ids.end(); ++it) + for(uuid_vec_t::iterator it = item_ids.begin(); it != item_ids.end(); ++it) { gInventory.deleteObject(*it); } @@ -3183,7 +2387,7 @@ void LLInventoryModel::processRemoveInventoryFolder(LLMessageSystem* msg, << llendl; return; } - std::vector<LLUUID> folder_ids; + uuid_vec_t folder_ids; update_map_t update; S32 count = msg->getNumberOfBlocksFast(_PREHASH_FolderData); for(S32 i = 0; i < count; ++i) @@ -3197,7 +2401,7 @@ void LLInventoryModel::processRemoveInventoryFolder(LLMessageSystem* msg, } } gInventory.accountForUpdate(update); - for(std::vector<LLUUID>::iterator it = folder_ids.begin(); it != folder_ids.end(); ++it) + for(uuid_vec_t::iterator it = folder_ids.begin(); it != folder_ids.end(); ++it) { gInventory.deleteObject(*it); } @@ -3264,7 +2468,9 @@ void LLInventoryModel::processBulkUpdateInventory(LLMessageSystem* msg, void**) } LLUUID tid; msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_TransactionID, tid); +#ifndef LL_RELEASE_FOR_DOWNLOAD llinfos << "Bulk inventory: " << tid << llendl; +#endif update_map_t update; cat_array_t folders; @@ -3310,7 +2516,7 @@ void LLInventoryModel::processBulkUpdateInventory(LLMessageSystem* msg, void**) count = msg->getNumberOfBlocksFast(_PREHASH_ItemData); - std::vector<LLUUID> wearable_ids; + uuid_vec_t wearable_ids; item_array_t items; std::list<InventoryCallbackInfo> cblist; for(i = 0; i < count; ++i) @@ -3385,7 +2591,7 @@ void LLInventoryModel::processBulkUpdateInventory(LLMessageSystem* msg, void**) { LLViewerInventoryItem* wearable_item; wearable_item = gInventory.getItem(wearable_ids[i]); - wear_inventory_item_on_avatar(wearable_item); + LLAppearanceMgr::instance().wearItemOnAvatar(wearable_item->getUUID(), true, true); } } @@ -3643,6 +2849,10 @@ static LLInventoryModel::item_array_t::iterator find_item_iter_by_uuid(LLInvento } // static +// * @param[in, out] items - vector with items to be updated. It should be sorted in a right way +// * before calling this method. +// * @param src_item_id - LLUUID of inventory item to be moved in new position +// * @param dest_item_id - LLUUID of inventory item before which source item should be placed. void LLInventoryModel::updateItemsOrder(LLInventoryModel::item_array_t& items, const LLUUID& src_item_id, const LLUUID& dest_item_id) { LLInventoryModel::item_array_t::iterator it_src = find_item_iter_by_uuid(items, src_item_id); @@ -3658,6 +2868,7 @@ void LLInventoryModel::updateItemsOrder(LLInventoryModel::item_array_t& items, c items.insert(it_dest, src_item); } +//* @param[in] items vector of items in order to be saved. void LLInventoryModel::saveItemsOrder(const LLInventoryModel::item_array_t& items) { int sortField = 0; @@ -3701,6 +2912,8 @@ static void rearrange_item_order_by_sort_field(LLInventoryModel::item_array_t& i std::sort(items.begin(), items.end(), sort_functor); } +// * @param source_item_id - LLUUID of the source item to be moved into new position +// * @param target_item_id - LLUUID of the target item before which source item should be placed. void LLInventoryModel::rearrangeFavoriteLandmarks(const LLUUID& source_item_id, const LLUUID& target_item_id) { LLInventoryModel::cat_array_t cats; @@ -3757,207 +2970,6 @@ void LLInventoryModel::dumpInventory() const } ///---------------------------------------------------------------------------- -/// LLInventoryCollectFunctor implementations -///---------------------------------------------------------------------------- - -// static -bool LLInventoryCollectFunctor::itemTransferCommonlyAllowed(LLInventoryItem* item) -{ - if (!item) - return false; - - bool allowed = false; - LLVOAvatarSelf* my_avatar = NULL; - - switch(item->getType()) - { - case LLAssetType::AT_CALLINGCARD: - // not allowed - break; - - case LLAssetType::AT_OBJECT: - my_avatar = gAgent.getAvatarObject(); - if(my_avatar && !my_avatar->isWearingAttachment(item->getUUID())) - { - allowed = true; - } - break; - - case LLAssetType::AT_BODYPART: - case LLAssetType::AT_CLOTHING: - if(!gAgentWearables.isWearingItem(item->getUUID())) - { - allowed = true; - } - break; - - default: - allowed = true; - break; - } - - return allowed; -} - -bool LLIsType::operator()(LLInventoryCategory* cat, LLInventoryItem* item) -{ - if(mType == LLAssetType::AT_CATEGORY) - { - if(cat) return TRUE; - } - if(item) - { - if(item->getType() == mType) return TRUE; - } - return FALSE; -} - -bool LLIsNotType::operator()(LLInventoryCategory* cat, LLInventoryItem* item) -{ - if(mType == LLAssetType::AT_CATEGORY) - { - if(cat) return FALSE; - } - if(item) - { - if(item->getType() == mType) return FALSE; - else return TRUE; - } - return TRUE; -} - -bool LLIsTypeWithPermissions::operator()(LLInventoryCategory* cat, LLInventoryItem* item) -{ - if(mType == LLAssetType::AT_CATEGORY) - { - if(cat) - { - return TRUE; - } - } - if(item) - { - if(item->getType() == mType) - { - LLPermissions perm = item->getPermissions(); - if ((perm.getMaskBase() & mPerm) == mPerm) - { - return TRUE; - } - } - } - return FALSE; -} - - -//bool LLIsClone::operator()(LLInventoryCategory* cat, LLInventoryItem* item) -//{ -// if(cat) return FALSE; -// if(item) -// { -// if(mItemMap->getType() == LLAssetType::AT_CALLINGCARD) -// { -// if((item->getType() == LLAssetType::AT_CALLINGCARD) -// && !(item->getCreatorUUID().isNull()) -// && (item->getCreatorUUID() == mItemMap->getCreatorUUID())) -// { -// return TRUE; -// } -// } -// else -// { -// if((item->getType() == mItemMap->getType()) -// && !(item->getAssetUUID().isNull()) -// && (item->getAssetUUID() == mItemMap->getAssetUUID()) -// && (item->getName() == mItemMap->getName())) -// { -// return TRUE; -// } -// } -// } -// return FALSE; -//} - -bool LLBuddyCollector::operator()(LLInventoryCategory* cat, - LLInventoryItem* item) -{ - if(item) - { - if((LLAssetType::AT_CALLINGCARD == item->getType()) - && (!item->getCreatorUUID().isNull()) - && (item->getCreatorUUID() != gAgent.getID())) - { - return true; - } - } - return false; -} - - -bool LLUniqueBuddyCollector::operator()(LLInventoryCategory* cat, - LLInventoryItem* item) -{ - if(item) - { - if((LLAssetType::AT_CALLINGCARD == item->getType()) - && (item->getCreatorUUID().notNull()) - && (item->getCreatorUUID() != gAgent.getID())) - { - mSeen.insert(item->getCreatorUUID()); - return true; - } - } - return false; -} - - -bool LLParticularBuddyCollector::operator()(LLInventoryCategory* cat, - LLInventoryItem* item) -{ - if(item) - { - if((LLAssetType::AT_CALLINGCARD == item->getType()) - && (item->getCreatorUUID() == mBuddyID)) - { - return TRUE; - } - } - return FALSE; -} - - -bool LLNameCategoryCollector::operator()( - LLInventoryCategory* cat, LLInventoryItem* item) -{ - if(cat) - { - if (!LLStringUtil::compareInsensitive(mName, cat->getName())) - { - return true; - } - } - return false; -} - -///---------------------------------------------------------------------------- -/// LLAssetIDMatches -///---------------------------------------------------------------------------- -bool LLAssetIDMatches::operator()(LLInventoryCategory* cat, LLInventoryItem* item) -{ - return (item && item->getAssetUUID() == mAssetID); -} - -///---------------------------------------------------------------------------- -/// LLLinkedItemIDMatches -///---------------------------------------------------------------------------- -bool LLLinkedItemIDMatches::operator()(LLInventoryCategory* cat, LLInventoryItem* item) -{ - return (item && - (item->getIsLinkType()) && - (item->getLinkedUUID() == mBaseItemID)); // A linked item's assetID will be the compared-to item's itemID. -} - -///---------------------------------------------------------------------------- /// Local function definitions ///---------------------------------------------------------------------------- |