////////////////////////////////////////////////////////////////////////// // Private methods ////////////////////////////////////////////////////////////////////////// void LLOutfitsList::computeDifference( const LLInventoryModel::cat_array_t& vcats, uuid_vec_t& vadded, uuid_vec_t& vremoved) { uuid_vec_t vnew; // Creating a vector of newly collected sub-categories UUIDs. for (LLInventoryModel::cat_array_t::const_iterator iter = vcats.begin(); iter != vcats.end(); iter++) { vnew.push_back((*iter)->getUUID()); } uuid_vec_t vcur; // Creating a vector of currently displayed sub-categories UUIDs. for (outfits_map_t::const_iterator iter = mOutfitsMap.begin(); iter != mOutfitsMap.end(); iter++) { vcur.push_back((*iter).first); } LLCommonUtils::computeDifference(vnew, vcur, vadded, vremoved); }
void LLFloaterGesture::done() { //this method can be called twice: for GestureFolder and once after loading all sudir of GestureFolder if (gInventory.isCategoryComplete(mGestureFolderID)) { LL_DEBUGS("Gesture")<< "mGestureFolderID loaded" << LL_ENDL; // we load only gesture folder without childred. LLInventoryModel::cat_array_t* categories; LLInventoryModel::item_array_t* items; uuid_vec_t unloaded_folders; LL_DEBUGS("Gesture")<< "Get subdirs of Gesture Folder...." << LL_ENDL; gInventory.getDirectDescendentsOf(mGestureFolderID, categories, items); if (categories->empty()) { gInventory.removeObserver(this); LL_INFOS("Gesture")<< "Gesture dos NOT contains sub-directories."<< LL_ENDL; return; } LL_DEBUGS("Gesture")<< "There are " << categories->size() << " Folders "<< LL_ENDL; for (LLInventoryModel::cat_array_t::iterator it = categories->begin(); it != categories->end(); it++) { if (!gInventory.isCategoryComplete(it->get()->getUUID())) { unloaded_folders.push_back(it->get()->getUUID()); LL_DEBUGS("Gesture")<< it->get()->getName()<< " Folder added to fetchlist"<< LL_ENDL; } } if (!unloaded_folders.empty()) { LL_DEBUGS("Gesture")<< "Fetching subdirectories....." << LL_ENDL; setFetchIDs(unloaded_folders); startFetch(); } else { LL_DEBUGS("Gesture")<< "All Gesture subdirectories have been loaded."<< LL_ENDL; gInventory.removeObserver(this); buildGestureList(); } } else { LL_WARNS("Gesture")<< "Gesture list was NOT loaded"<< LL_ENDL; } }
//static void LLLocalInventory::saveInvCache(std::string filename, LLFolderView* folder) { LLInventoryModel* model = &gInventory; std::set<LLUUID> selected_items; folder->getSelectionList(selected_items); if(selected_items.size() < 1) { // No items selected? Wtfboom return; } LLInventoryModel::cat_array_t cats; LLInventoryModel::item_array_t items; // Make complete lists of child categories and items std::set<LLUUID>::iterator sel_iter = selected_items.begin(); std::set<LLUUID>::iterator sel_end = selected_items.end(); for( ; sel_iter != sel_end; ++sel_iter) { LLInventoryCategory* cat = model->getCategory(*sel_iter); if(cat) { climb(cat, cats, items); } } // And what about items inside a folder that wasn't selected? // I guess I will just add selected items, so long as they aren't already added for(sel_iter = selected_items.begin(); sel_iter != sel_end; ++sel_iter) { LLInventoryItem* item = model->getItem(*sel_iter); if(item) { if(std::find(items.begin(), items.end(), item) == items.end()) { items.push_back(LLPointer<LLViewerInventoryItem>((LLViewerInventoryItem*)item)); LLInventoryCategory* parent = model->getCategory(item->getParentUUID()); if(std::find(cats.begin(), cats.end(), parent) == cats.end()) { cats.push_back(LLPointer<LLViewerInventoryCategory>((LLViewerInventoryCategory*)parent)); } } } } LLInventoryModel::saveToFile(filename, cats, items); }
void LLFriendCardsManager::collectFriendsLists(folderid_buddies_map_t& folderBuddiesMap) const { folderBuddiesMap.clear(); LLInventoryModel::cat_array_t* listFolders; LLInventoryModel::item_array_t* items; // get folders in the Friend folder. Items should be NULL due to Cards should be in lists. gInventory.getDirectDescendentsOf(findFriendFolderUUIDImpl(), listFolders, items); if (NULL == listFolders) return; LLInventoryModel::cat_array_t::const_iterator itCats; // to iterate Friend Lists (categories) LLInventoryModel::item_array_t::const_iterator itBuddy; // to iterate Buddies in each List LLInventoryModel::cat_array_t* fakeCatsArg; for (itCats = listFolders->begin(); itCats != listFolders->end(); ++itCats) { if (items) items->clear(); // *HACK: Only Friends/All content will be shown for now // *TODO: Remove this hack, implement sorting if it will be needded by spec. if ((*itCats)->getUUID() != findFriendAllSubfolderUUIDImpl()) continue; gInventory.getDirectDescendentsOf((*itCats)->getUUID(), fakeCatsArg, items); if (NULL == items) continue; uuid_vec_t buddyUUIDs; for (itBuddy = items->begin(); itBuddy != items->end(); ++itBuddy) { buddyUUIDs.push_back((*itBuddy)->getCreatorUUID()); } folderBuddiesMap.insert(make_pair((*itCats)->getUUID(), buddyUUIDs)); } }
virtual ~LLOrderMyOutfitsOnDestroy() { if (!LLApp::isRunning()) { llwarns << "called during shutdown, skipping" << llendl; return; } const LLUUID& my_outfits_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS); if (my_outfits_id.isNull()) return; LLInventoryModel::cat_array_t* cats; LLInventoryModel::item_array_t* items; gInventory.getDirectDescendentsOf(my_outfits_id, cats, items); if (!cats) return; //My Outfits should at least contain saved initial outfit and one another outfit if (cats->size() < 2) { llwarning("My Outfits category was not populated properly", 0); return; } llinfos << "Starting updating My Outfits with wearables ordering information" << llendl; for (LLInventoryModel::cat_array_t::iterator outfit_iter = cats->begin(); outfit_iter != cats->end(); ++outfit_iter) { const LLUUID& cat_id = (*outfit_iter)->getUUID(); if (cat_id.isNull()) continue; // saved initial outfit already contains wearables ordering information if (cat_id == LLAppearanceMgr::getInstance()->getBaseOutfitUUID()) continue; LLAppearanceMgr::getInstance()->updateClothingOrderingInfo(cat_id); } llinfos << "Finished updating My Outfits with wearables ordering information" << llendl; }
// LLUUID catID=TraverseCategories("/My Inventory/#Luna/Durp") LLUUID TraverseCategories(const std::string& target_cat, LLViewerInventoryCategory *ccat, int i) { // Split the path into an array. boost::char_separator<char> sep("/"); boost::tokenizer<boost::char_separator<char> > tok(target_cat,sep); std::vector<std::string> vec; vec.assign(tok.begin(),tok.end()); std::string cat = vec[i]; LLUUID id; if(i==0) { id=gAgent.getInventoryRootID(); } else { id = ccat->getUUID(); } LLInventoryModel::cat_array_t *cats; LLInventoryModel::item_array_t *items; gInventory.getDirectDescendentsOf(id,cats,items); LLInventoryModel::cat_array_t::iterator cat_iter = cats->begin(); LLInventoryModel::cat_array_t::iterator cat_end = cats->end(); for( ; cat_iter != cat_end; ++cat_iter) { LLViewerInventoryCategory *c_cat=(*cat_iter); if(c_cat->getName() == cat) { if(vec.size() == i+1) { return c_cat->getUUID(); } else { ++i; return TraverseCategories(target_cat,*cat_iter,i); } } } return LLUUID::null; }
//static void LLLocalInventory::loadInvCache(std::string filename) { std::string extension = gDirUtilp->getExtension(filename); std::string inv_filename = filename; if(extension == "gz") { LLUUID random; random.generate(); inv_filename = filename.substr(0, filename.length() - 3) + "." + random.asString(); if(!gunzip_file(filename, inv_filename)) { // failure... message? return; } } LLInventoryModel::cat_array_t cats; LLInventoryModel::item_array_t items; bool is_cache_obsolete = false; if(LLInventoryModel::loadFromFile(inv_filename, cats, items, is_cache_obsolete)) { // create a container category for everything LLViewerInventoryCategory* container = new LLViewerInventoryCategory(gAgent.getID()); container->rename(gDirUtilp->getBaseFileName(filename, false)); LLUUID container_id; container_id.generate(); container->setUUID(container_id); container->setParent(gSystemFolderRoot); container->setPreferredType(LLFolderType::FT_NONE); LLInventoryModel::update_map_t container_update; ++container_update[container->getParentUUID()]; gInventory.accountForUpdate(container_update); gInventory.updateCategory(container); gInventory.notifyObservers(); LLViewerInventoryCategory* orphaned_items = new LLViewerInventoryCategory(gAgent.getID()); orphaned_items->rename("Orphaned Items"); LLUUID orphaned_items_id; orphaned_items_id.generate(); orphaned_items->setUUID(orphaned_items_id); orphaned_items->setParent(container_id); orphaned_items->setPreferredType(LLFolderType::FT_NONE); LLInventoryModel::update_map_t orphaned_items_update; ++orphaned_items_update[orphaned_items->getParentUUID()]; gInventory.accountForUpdate(orphaned_items_update); gInventory.updateCategory(orphaned_items); gInventory.notifyObservers(); //conflict handling std::map<LLUUID,LLUUID> conflicting_cats; int dropped_cats = 0; int dropped_items = 0; // Add all categories LLInventoryModel::cat_array_t::iterator cat_iter = cats.begin(); LLInventoryModel::cat_array_t::iterator cat_end = cats.end(); for(; cat_iter != cat_end; ++cat_iter) { // Conditionally change its parent // Note: Should I search for missing parent id's? //if the parent is null, it goes in the very root of the tree! if((*cat_iter)->getParentUUID().isNull()) { (*cat_iter)->setParent(container_id); } // If the parent exists and outside of pretend inventory, generate a new uuid else if(gInventory.getCategory((*cat_iter)->getParentUUID())) { if(!gInventory.isObjectDescendentOf((*cat_iter)->getParentUUID(), gSystemFolderRoot, TRUE)) { std::map<LLUUID,LLUUID>::iterator itr = conflicting_cats.find((*cat_iter)->getParentUUID()); if(itr == conflicting_cats.end()) { dropped_cats++; continue; } (*cat_iter)->setParent(itr->second); } } else { //well balls, this is orphaned. (*cat_iter)->setParent(orphaned_items_id); } // If this category already exists, generate a new uuid if(gInventory.getCategory((*cat_iter)->getUUID())) { LLUUID cat_random; cat_random.generate(); conflicting_cats[(*cat_iter)->getUUID()] = cat_random; (*cat_iter)->setUUID(cat_random); } LLInventoryModel::update_map_t update; ++update[(*cat_iter)->getParentUUID()]; gInventory.accountForUpdate(update); gInventory.updateCategory(*cat_iter); gInventory.notifyObservers(); } // Add all items LLInventoryModel::item_array_t::iterator item_iter = items.begin(); LLInventoryModel::item_array_t::iterator item_end = items.end(); for(; item_iter != item_end; ++item_iter) { // Conditionally change its parent // Note: Should I search for missing parent id's? //if the parent is null, it goes in the very root of the tree! if((*item_iter)->getParentUUID().isNull()) { (*item_iter)->setParent(container_id); } // If the parent exists and outside of pretend inventory, generate a new uuid if(gInventory.getCategory((*item_iter)->getParentUUID())) { if(!gInventory.isObjectDescendentOf((*item_iter)->getParentUUID(), gSystemFolderRoot, TRUE)) { std::map<LLUUID,LLUUID>::iterator itr = conflicting_cats.find((*item_iter)->getParentUUID()); if(itr == conflicting_cats.end()) { dropped_items++; continue; } (*item_iter)->setParent(itr->second); } } else { //well balls, this is orphaned. (*item_iter)->setParent(orphaned_items_id); } // Avoid conflicts with real inventory... // If this item id already exists, generate a new uuid if(gInventory.getItem((*item_iter)->getUUID())) { LLUUID item_random; item_random.generate(); (*item_iter)->setUUID(item_random); } LLInventoryModel::update_map_t update; ++update[(*item_iter)->getParentUUID()]; gInventory.accountForUpdate(update); gInventory.updateItem(*item_iter); gInventory.notifyObservers(); } // Quality time if(dropped_items || dropped_cats) { std::ostringstream message; message << "Some items were ignored due to conflicts:\n\n"; if(dropped_cats) message << dropped_cats << " folders\n"; if(dropped_items) message << dropped_items << " items\n"; LLSD args; args["ERROR_MESSAGE"] = message.str(); LLNotificationsUtil::add("ErrorMessage", args); } conflicting_cats.clear();// srsly dont think this is need but w/e :D } // remove temporary unzipped file if(extension == "gz") { LLFile::remove(inv_filename); } }
// Bundle up a bunch of requests to send all at once. // static void LLInventoryModelBackgroundFetch::bulkFetch(std::string url) { //Background fetch is called from gIdleCallbacks in a loop until background fetch is stopped. //If there are items in mFetchQueue, 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 (mMinTimeBetweenFetches < new_min_time) { mMinTimeBetweenFetches=new_min_time; //HACK! See above. } if (gDisconnected || (mBulkFetchCount > max_concurrent_fetches) || (mFetchTimer.getElapsedTimeF32() < mMinTimeBetweenFetches)) { return; // just bail if we are disconnected } U32 folder_count=0; U32 max_batch_size=5; U32 sort_order = gSavedSettings.getU32(LLInventoryPanel::DEFAULT_SORT_ORDER) & 0x1; uuid_vec_t recursive_cats; LLSD body; LLSD body_lib; while (!(mFetchQueue.empty()) && (folder_count < max_batch_size)) { const FetchQueueInfo& fetch_info = mFetchQueue.front(); const LLUUID &cat_id = fetch_info.mCatUUID; if (cat_id.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 { const LLViewerInventoryCategory* cat = gInventory.getCategory(cat_id); 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++; } // May already have this folder, but append child folders to list. if (fetch_info.mRecursive) { LLInventoryModel::cat_array_t* categories; LLInventoryModel::item_array_t* items; gInventory.getDirectDescendentsOf(cat->getUUID(), categories, items); for (LLInventoryModel::cat_array_t::const_iterator it = categories->begin(); it != categories->end(); ++it) { mFetchQueue.push_back(FetchQueueInfo((*it)->getUUID(), fetch_info.mRecursive)); } } } } if (fetch_info.mRecursive) recursive_cats.push_back(cat_id); mFetchQueue.pop_front(); } if (folder_count > 0) { mBulkFetchCount++; if (body["folders"].size()) { LLInventoryModelFetchDescendentsResponder *fetcher = new LLInventoryModelFetchDescendentsResponder(body, recursive_cats); LLHTTPClient::post(url, body, fetcher, 300.0); } if (body_lib["folders"].size()) { std::string url_lib = gAgent.getRegion()->getCapability("FetchLibDescendents2"); LLInventoryModelFetchDescendentsResponder *fetcher = new LLInventoryModelFetchDescendentsResponder(body_lib, recursive_cats); LLHTTPClient::post(url_lib, body_lib, fetcher, 300.0); } mFetchTimer.reset(); } else if (isBulkFetchProcessingComplete()) { setAllFoldersFetched(); } }
void LLInventoryModelBackgroundFetch::backgroundFetch() { if (mBackgroundFetchActive && 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("FetchInventoryDescendents2"); if (gSavedSettings.getBOOL("UseHTTPInventory") && !url.empty()) { bulkFetch(url); return; } #if 1 //-------------------------------------------------------------------------------- // DEPRECATED OLD CODE // // No more categories to fetch, stop fetch process. if (mFetchQueue.empty()) { llinfos << "Inventory fetch completed" << llendl; setAllFoldersFetched(); return; } F32 fast_fetch_time = lerp(mMinTimeBetweenFetches, mMaxTimeBetweenFetches, 0.1f); F32 slow_fetch_time = lerp(mMinTimeBetweenFetches, mMaxTimeBetweenFetches, 0.5f); if (mTimelyFetchPending && mFetchTimer.getElapsedTimeF32() > slow_fetch_time) { // Double timeouts on failure. mMinTimeBetweenFetches = llmin(mMinTimeBetweenFetches * 2.f, 10.f); mMaxTimeBetweenFetches = llmin(mMaxTimeBetweenFetches * 2.f, 120.f); llinfos << "Inventory fetch times grown to (" << mMinTimeBetweenFetches << ", " << mMaxTimeBetweenFetches << ")" << llendl; // fetch is no longer considered "timely" although we will wait for full time-out. mTimelyFetchPending = FALSE; } while(1) { if (mFetchQueue.empty()) { break; } if(gDisconnected) { // Just bail if we are disconnected. break; } const FetchQueueInfo info = mFetchQueue.front(); LLViewerInventoryCategory* cat = gInventory.getCategory(info.mCatUUID); // Category has been deleted, remove from queue. if (!cat) { mFetchQueue.pop_front(); continue; } if (mFetchTimer.getElapsedTimeF32() > mMinTimeBetweenFetches && 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->fetch()) { mFetchTimer.reset(); mTimelyFetchPending = 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(info.mCatUUID)) { // Finished with this category, remove from queue. mFetchQueue.pop_front(); // Add all children to queue. LLInventoryModel::cat_array_t* categories; LLInventoryModel::item_array_t* items; gInventory.getDirectDescendentsOf(cat->getUUID(), categories, items); for (LLInventoryModel::cat_array_t::const_iterator it = categories->begin(); it != categories->end(); ++it) { mFetchQueue.push_back(FetchQueueInfo((*it)->getUUID(),info.mRecursive)); } // We received a response in less than the fast time. if (mTimelyFetchPending && mFetchTimer.getElapsedTimeF32() < fast_fetch_time) { // Shrink timeouts based on success. mMinTimeBetweenFetches = llmax(mMinTimeBetweenFetches * 0.8f, 0.3f); mMaxTimeBetweenFetches = llmax(mMaxTimeBetweenFetches * 0.8f, 10.f); //llinfos << "Inventory fetch times shrunk to (" << mMinTimeBetweenFetches << ", " << mMaxTimeBetweenFetches << ")" << llendl; } mTimelyFetchPending = FALSE; continue; } else if (mFetchTimer.getElapsedTimeF32() > mMaxTimeBetweenFetches) { // Received first packet, but our num descendants does not match db's num descendants // so try again later. mFetchQueue.pop_front(); if (mNumFetchRetries++ < MAX_FETCH_RETRIES) { // push on back of queue mFetchQueue.push_back(info); } mTimelyFetchPending = FALSE; mFetchTimer.reset(); break; } // Not enough time has elapsed to do a new fetch break; } // // DEPRECATED OLD CODE //-------------------------------------------------------------------------------- #endif } }
// Bundle up a bunch of requests to send all at once. // static void LLInventoryModelBackgroundFetch::bulkFetch() { //Background fetch is called from gIdleCallbacks in a loop until background fetch is stopped. //If there are items in mFetchQueue, 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. LLViewerRegion* region = gAgent.getRegion(); if (!region) return; S16 max_concurrent_fetches=8; F32 new_min_time = 0.5f; //HACK! Clean this up when old code goes away entirely. if (mMinTimeBetweenFetches < new_min_time) { mMinTimeBetweenFetches=new_min_time; //HACK! See above. } if (gDisconnected || (mFetchCount > max_concurrent_fetches) || (mFetchTimer.getElapsedTimeF32() < mMinTimeBetweenFetches)) { return; // just bail if we are disconnected } U32 item_count=0; U32 folder_count=0; U32 max_batch_size=5; U32 sort_order = gSavedSettings.getU32(LLInventoryPanel::DEFAULT_SORT_ORDER) & 0x1; uuid_vec_t recursive_cats; LLSD folder_request_body; LLSD folder_request_body_lib; LLSD item_request_body; LLSD item_request_body_lib; while (!mFetchQueue.empty() && (item_count + folder_count) < max_batch_size) { const FetchQueueInfo& fetch_info = mFetchQueue.front(); if (fetch_info.mIsCategory) { const LLUUID &cat_id = fetch_info.mUUID; if (cat_id.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; folder_request_body["folders"].append(folder_sd); folder_count++; } else { const LLViewerInventoryCategory* cat = gInventory.getCategory(cat_id); 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()) folder_request_body_lib["folders"].append(folder_sd); else folder_request_body["folders"].append(folder_sd); folder_count++; } // May already have this folder, but append child folders to list. if (fetch_info.mRecursive) { LLInventoryModel::cat_array_t* categories; LLInventoryModel::item_array_t* items; gInventory.getDirectDescendentsOf(cat->getUUID(), categories, items); for (LLInventoryModel::cat_array_t::const_iterator it = categories->begin(); it != categories->end(); ++it) { mFetchQueue.push_back(FetchQueueInfo((*it)->getUUID(), fetch_info.mRecursive)); } } } } if (fetch_info.mRecursive) recursive_cats.push_back(cat_id); } else { LLViewerInventoryItem* itemp = gInventory.getItem(fetch_info.mUUID); if (itemp) { LLSD item_sd; item_sd["owner_id"] = itemp->getPermissions().getOwner(); item_sd["item_id"] = itemp->getUUID(); if (itemp->getPermissions().getOwner() == gAgent.getID()) { item_request_body.append(item_sd); } else { item_request_body_lib.append(item_sd); } //itemp->fetchFromServer(); item_count++; } } mFetchQueue.pop_front(); } if (item_count + folder_count > 0) { if (folder_count) { std::string url = region->getCapability("FetchInventoryDescendents2"); mFetchCount++; if (folder_request_body["folders"].size()) { LLInventoryModelFetchDescendentsResponder *fetcher = new LLInventoryModelFetchDescendentsResponder(folder_request_body, recursive_cats); LLHTTPClient::post(url, folder_request_body, fetcher, 300.0); } if (folder_request_body_lib["folders"].size()) { std::string url_lib = gAgent.getRegion()->getCapability("FetchLibDescendents2"); LLInventoryModelFetchDescendentsResponder *fetcher = new LLInventoryModelFetchDescendentsResponder(folder_request_body_lib, recursive_cats); LLHTTPClient::post(url_lib, folder_request_body_lib, fetcher, 300.0); } } if (item_count) { std::string url; if (item_request_body.size()) { mFetchCount++; url = region->getCapability("FetchInventory2"); if (!url.empty()) { LLSD body; body["agent_id"] = gAgent.getID(); body["items"] = item_request_body; LLHTTPClient::post(url, body, new LLInventoryModelFetchItemResponder(body)); } //else //{ // LLMessageSystem* msg = gMessageSystem; // msg->newMessage("FetchInventory"); // msg->nextBlock("AgentData"); // msg->addUUID("AgentID", gAgent.getID()); // msg->addUUID("SessionID", gAgent.getSessionID()); // msg->nextBlock("InventoryData"); // msg->addUUID("OwnerID", mPermissions.getOwner()); // msg->addUUID("ItemID", mUUID); // gAgent.sendReliableMessage(); //} } if (item_request_body_lib.size()) { mFetchCount++; url = region->getCapability("FetchLib2"); if (!url.empty()) { LLSD body; body["agent_id"] = gAgent.getID(); body["items"] = item_request_body_lib; LLHTTPClient::post(url, body, new LLInventoryModelFetchItemResponder(body)); } } } mFetchTimer.reset(); } else if (isBulkFetchProcessingComplete()) { setAllFoldersFetched(); } }
// Bundle up a bunch of requests to send all at once. void LLInventoryModelBackgroundFetch::bulkFetch() { //Background fetch is called from gIdleCallbacks in a loop until background fetch is stopped. //If there are items in mFetchQueue, 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. LLViewerRegion* region = gAgent.getRegion(); if (gDisconnected || !region) return; U32 const max_batch_size = 5; U32 sort_order = gSavedSettings.getU32(LLInventoryPanel::DEFAULT_SORT_ORDER) & 0x1; uuid_vec_t recursive_cats; U32 folder_count=0; U32 folder_lib_count=0; U32 item_count=0; U32 item_lib_count=0; // This function can do up to four requests at once. LLPointer<AIPerService::Approvement> approved_folder; LLPointer<AIPerService::Approvement> approved_folder_lib; LLPointer<AIPerService::Approvement> approved_item; LLPointer<AIPerService::Approvement> approved_item_lib; LLSD folder_request_body; LLSD folder_request_body_lib; LLSD item_request_body; LLSD item_request_body_lib; while (!mFetchQueue.empty()) { const FetchQueueInfo& fetch_info = mFetchQueue.front(); if (fetch_info.mIsCategory) { const LLUUID &cat_id = fetch_info.mUUID; if (!cat_id.isNull()) { const LLViewerInventoryCategory* cat = gInventory.getCategory(cat_id); 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()) { if (folder_lib_count == max_batch_size || (folder_lib_count == 0 && !(approved_folder_lib = AIPerService::approveHTTPRequestFor(mPerServicePtr, cap_inventory)))) { break; } folder_request_body_lib["folders"].append(folder_sd); ++folder_lib_count; } else { if (folder_count == max_batch_size || (folder_count == 0 && !(approved_folder = AIPerService::approveHTTPRequestFor(mPerServicePtr, cap_inventory)))) { break; } folder_request_body["folders"].append(folder_sd); ++folder_count; } } // May already have this folder, but append child folders to list. if (fetch_info.mRecursive) { LLInventoryModel::cat_array_t* categories; LLInventoryModel::item_array_t* items; gInventory.getDirectDescendentsOf(cat->getUUID(), categories, items); for (LLInventoryModel::cat_array_t::const_iterator it = categories->begin(); it != categories->end(); ++it) { mFetchQueue.push_back(FetchQueueInfo((*it)->getUUID(), fetch_info.mRecursive)); } } } if (fetch_info.mRecursive) recursive_cats.push_back(cat_id); } } else { LLViewerInventoryItem* itemp = gInventory.getItem(fetch_info.mUUID); if (itemp) { LLSD item_sd; item_sd["owner_id"] = itemp->getPermissions().getOwner(); item_sd["item_id"] = itemp->getUUID(); if (itemp->getPermissions().getOwner() == gAgent.getID()) { if (item_count == max_batch_size || (item_count == 0 && !(approved_item = AIPerService::approveHTTPRequestFor(mPerServicePtr, cap_inventory)))) { break; } item_request_body.append(item_sd); ++item_count; } else { if (item_lib_count == max_batch_size || (item_lib_count == 0 && !(approved_item_lib = AIPerService::approveHTTPRequestFor(mPerServicePtr, cap_inventory)))) { break; } item_request_body_lib.append(item_sd); ++item_lib_count; } } } mFetchQueue.pop_front(); } if (item_count + folder_count + item_lib_count + folder_lib_count > 0) { if (folder_count) { std::string url = region->getCapability("FetchInventoryDescendents2"); llassert(!url.empty()); ++mFetchCount; LLInventoryModelFetchDescendentsResponder *fetcher = new LLInventoryModelFetchDescendentsResponder(folder_request_body, recursive_cats); LLHTTPClient::post_approved(url, folder_request_body, fetcher, approved_folder); } if (folder_lib_count) { std::string url = gAgent.getRegion()->getCapability("FetchLibDescendents2"); llassert(!url.empty()); ++mFetchCount; LLInventoryModelFetchDescendentsResponder *fetcher = new LLInventoryModelFetchDescendentsResponder(folder_request_body_lib, recursive_cats); LLHTTPClient::post_approved(url, folder_request_body_lib, fetcher, approved_folder_lib); } if (item_count) { std::string url = region->getCapability("FetchInventory2"); llassert(!url.empty()); ++mFetchCount; LLSD body; body["agent_id"] = gAgent.getID(); body["items"] = item_request_body; LLHTTPClient::post_approved(url, body, new LLInventoryModelFetchItemResponder(body), approved_item); } if (item_lib_count) { std::string url = region->getCapability("FetchLib2"); llassert(!url.empty()); ++mFetchCount; LLSD body; body["agent_id"] = gAgent.getID(); body["items"] = item_request_body_lib; LLHTTPClient::post_approved(url, body, new LLInventoryModelFetchItemResponder(body), approved_item_lib); } mFetchTimer.reset(); } else if (isBulkFetchProcessingComplete()) { llinfos << "Inventory fetch completed" << llendl; setAllFoldersFetched(); } }