Commits

Anonymous committed 4156e46

EXP-1844 FIX Selecting a large number of inventory items can block the viewer for a long time.
only show hourglass and fetching text when downloading folders, not item metadata

  • Participants
  • Parent commits 21e539d

Comments (0)

Files changed (9)

File indra/newview/llfolderview.cpp

 	}
 	else if (mShowEmptyMessage)
 	{
-		if (LLInventoryModelBackgroundFetch::instance().backgroundFetchActive() || mCompletedFilterGeneration < mFilter->getMinRequiredGeneration())
+		if (LLInventoryModelBackgroundFetch::instance().folderFetchActive() || mCompletedFilterGeneration < mFilter->getMinRequiredGeneration())
 		{
 			mStatusText = LLTrans::getString("Searching");
 		}
 	// However we allow scrolling for folder views with mAutoSelectOverride
 	// (used in Places SP) as an exception because the selection in them
 	// is not reset during items filtering. See STORM-133.
-	if ( (!LLInventoryModelBackgroundFetch::instance().backgroundFetchActive() || mAutoSelectOverride)
+	if ( (!LLInventoryModelBackgroundFetch::instance().folderFetchActive() || mAutoSelectOverride)
 			&& mSelectedItems.size() )
 	{
 		mNeedsScroll = TRUE;

File indra/newview/llfolderviewitem.cpp

 	}
 	if ((mIsLoading
 		&&	mTimeSinceRequestStart.getElapsedTimeF32() >= gSavedSettings.getF32("FolderLoadingMessageWaitTime"))
-			||	(LLInventoryModelBackgroundFetch::instance().backgroundFetchActive()
+			||	(LLInventoryModelBackgroundFetch::instance().folderFetchActive()
 				&&	root_is_loading
 				&&	mShowLoadStatus))
 	{

File indra/newview/llinventorybridge.cpp

 	LLViewerInventoryItem* item = static_cast<LLViewerInventoryItem*>(getItem());
 	if(item && !item->isFinished())
 	{
+		//item->fetchFromServer();
 		LLInventoryModelBackgroundFetch::instance().start(item->getUUID(), false);
 	}
 }

File indra/newview/llinventoryfilter.cpp

 		filtered_by_all_types = FALSE;
 	}
 
-	if (!LLInventoryModelBackgroundFetch::instance().backgroundFetchActive()
+	if (!LLInventoryModelBackgroundFetch::instance().folderFetchActive()
 		&& filtered_by_type
 		&& !filtered_by_all_types)
 	{

File indra/newview/llinventorymodelbackgroundfetch.cpp

 
 LLInventoryModelBackgroundFetch::LLInventoryModelBackgroundFetch() :
 	mBackgroundFetchActive(FALSE),
+	mFolderFetchActive(false),
 	mAllFoldersFetched(FALSE),
 	mRecursiveInventoryFetchStarted(FALSE),
 	mRecursiveLibraryFetchStarted(FALSE),
 	return mAllFoldersFetched;
 }
 
-BOOL LLInventoryModelBackgroundFetch::backgroundFetchActive() const
+BOOL LLInventoryModelBackgroundFetch::folderFetchActive() const
 {
-	return mBackgroundFetchActive;
+	return mFolderFetchActive;
 }
 
 void LLInventoryModelBackgroundFetch::start(const LLUUID& id, BOOL recursive)
 {
 	LLViewerInventoryCategory* cat = gInventory.getCategory(id);
-	if (cat || (id.isNull() && !mAllFoldersFetched))
+	if (cat || (id.isNull() && !isEverythingFetched()))
 	{	// it's a folder, do a bulk fetch
 		LL_DEBUGS("InventoryFetch") << "Start fetching category: " << id << ", recursive: " << recursive << LL_ENDL;
 
 		mBackgroundFetchActive = TRUE;
+		mFolderFetchActive = true;
 		if (id.isNull())
 		{
 			if (!mRecursiveInventoryFetchStarted)
 void LLInventoryModelBackgroundFetch::findLostItems()
 {
 	mBackgroundFetchActive = TRUE;
+	mFolderFetchActive = true;
     mFetchQueue.push_back(FetchQueueInfo(LLUUID::null, TRUE));
     gIdleCallbacks.addFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, NULL);
 }
 
-void LLInventoryModelBackgroundFetch::stopBackgroundFetch()
-{
-	if (mBackgroundFetchActive)
-	{
-		mBackgroundFetchActive = FALSE;
-		gIdleCallbacks.deleteFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, NULL);
-		mFetchCount=0;
-		mMinTimeBetweenFetches=0.0f;
-	}
-}
-
 void LLInventoryModelBackgroundFetch::setAllFoldersFetched()
 {
 	if (mRecursiveInventoryFetchStarted &&
 	{
 		mAllFoldersFetched = TRUE;
 	}
-	stopBackgroundFetch();
+	mFolderFetchActive = false;
 }
 
 void LLInventoryModelBackgroundFetch::backgroundFetchCB(void *)
 			llinfos << "Inventory fetch completed" << llendl;
 
 			setAllFoldersFetched();
+			mBackgroundFetchActive = false;
+			mFolderFetchActive = false;
+
 			return;
 		}
 
 			}
 
 			const FetchQueueInfo info = mFetchQueue.front();
-			LLViewerInventoryCategory* cat = gInventory.getCategory(info.mUUID);
 
-			// Category has been deleted, remove from queue.
-			if (!cat)
+			if (info.mIsCategory)
 			{
+
+				LLViewerInventoryCategory* cat = gInventory.getCategory(info.mUUID);
+
+				// 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.mUUID))
+				{
+					// 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);
+						lldebugs << "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;
+			}
+			else
+			{
+				LLViewerInventoryItem* itemp = gInventory.getItem(info.mUUID);
+
 				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())
+				if (!itemp) 
 				{
+					continue;
+				}
+
+				if (mFetchTimer.getElapsedTimeF32() > mMinTimeBetweenFetches)
+				{
+					itemp->fetchFromServer();
 					mFetchTimer.reset();
 					mTimelyFetchPending = TRUE;
 				}
-				else
+				else if (itemp->mIsComplete)
 				{
-					//  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;
+					mTimelyFetchPending = FALSE;
 				}
-			}
-			// Do I have all my children?
-			else if (gInventory.isCategoryComplete(info.mUUID))
-			{
-				// 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)
+				else if (mFetchTimer.getElapsedTimeF32() > mMaxTimeBetweenFetches)
 				{
-					mFetchQueue.push_back(FetchQueueInfo((*it)->getUUID(),info.mRecursive));
+					mFetchQueue.push_back(info);
+					mFetchTimer.reset();
+					mTimelyFetchPending = FALSE;
 				}
-
-				// 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);
-					lldebugs << "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();
+				// Not enough time has elapsed to do a new fetch
 				break;
 			}
-
-			// Not enough time has elapsed to do a new fetch
-			break;
 		}
 
 		//
 	//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.  
 	LLViewerRegion* region = gAgent.getRegion();
 	if (!region) return;
 
 	LLSD item_request_body;
 	LLSD item_request_body_lib;
 
-	while (!(mFetchQueue.empty()) && ((item_count + folder_count) < max_batch_size))
+	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
 			{

File indra/newview/llinventorymodelbackgroundfetch.h

 	// This gets triggered when performing a filter-search.
 	void start(const LLUUID& cat_id = LLUUID::null, BOOL recursive = TRUE);
 
-	BOOL backgroundFetchActive() const;
+	BOOL folderFetchActive() const;
 	bool isEverythingFetched() const; // completing the fetch once per session should be sufficient
 
 	bool libraryFetchStarted() const;
 
 	void backgroundFetch();
 	static void backgroundFetchCB(void*); // background fetch idle function
-	void stopBackgroundFetch(); // stop fetch process
 
 	void setAllFoldersFetched();
 	bool fetchQueueContainsNoDescendentsOf(const LLUUID& cat_id) const;
 	BOOL mAllFoldersFetched;
 
 	BOOL mBackgroundFetchActive;
+	bool mFolderFetchActive;
 	S16 mFetchCount;
 	BOOL mTimelyFetchPending;
 	S32 mNumFetchRetries;

File indra/newview/llinventorypanel.cpp

 	if(handled)
 	{
 		ECursorType cursor = getWindow()->getCursor();
-		if (LLInventoryModelBackgroundFetch::instance().backgroundFetchActive() && cursor == UI_CURSOR_ARROW)
+		if (LLInventoryModelBackgroundFetch::instance().folderFetchActive() && cursor == UI_CURSOR_ARROW)
 		{
 			// replace arrow cursor with arrow and hourglass cursor
 			getWindow()->setCursor(UI_CURSOR_WORKING);

File indra/newview/llpanelmaininventory.cpp

 
 	std::string text = "";
 
-	if (LLInventoryModelBackgroundFetch::instance().backgroundFetchActive())
+	if (LLInventoryModelBackgroundFetch::instance().folderFetchActive())
 	{
 		text = getString("ItemcountFetching", string_args);
 	}

File indra/newview/llviewerinventory.cpp

 			gAgent.sendReliableMessage();
 		}
 	}
-	else
-	{
-		// *FIX: this can be removed after a bit.
-		llwarns << "request to fetch complete item" << llendl;
-	}
 }
 
 // virtual