summaryrefslogtreecommitdiff
path: root/indra/newview/llinventoryobserver.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llinventoryobserver.cpp')
-rw-r--r--indra/newview/llinventoryobserver.cpp164
1 files changed, 130 insertions, 34 deletions
diff --git a/indra/newview/llinventoryobserver.cpp b/indra/newview/llinventoryobserver.cpp
index db0751cb89..281a8bc789 100644
--- a/indra/newview/llinventoryobserver.cpp
+++ b/indra/newview/llinventoryobserver.cpp
@@ -37,8 +37,10 @@
#include "llagent.h"
#include "llagentwearables.h"
+#include "llaisapi.h"
#include "llfloater.h"
#include "llfocusmgr.h"
+#include "llinventorymodelbackgroundfetch.h"
#include "llinventorybridge.h"
#include "llinventoryfunctions.h"
#include "llinventorymodel.h"
@@ -56,6 +58,7 @@
#include "llsdutil.h"
#include <deque>
+const S32 LLInventoryFetchItemsObserver::MAX_INDIVIDUAL_ITEM_REQUESTS = 7;
const F32 LLInventoryFetchItemsObserver::FETCH_TIMER_EXPIRY = 60.0f;
@@ -149,7 +152,7 @@ LLInventoryFetchItemsObserver::LLInventoryFetchItemsObserver(const uuid_vec_t& i
void LLInventoryFetchItemsObserver::changed(U32 mask)
{
- LL_DEBUGS() << this << " remaining incomplete " << mIncomplete.size()
+ LL_DEBUGS("InventoryFetch") << this << " remaining incomplete " << mIncomplete.size()
<< " complete " << mComplete.size()
<< " wait period " << mFetchingPeriod.getRemainingTimeF32()
<< LL_ENDL;
@@ -158,6 +161,15 @@ void LLInventoryFetchItemsObserver::changed(U32 mask)
// appropriate.
if (!mIncomplete.empty())
{
+ if (!LLInventoryModelBackgroundFetch::getInstance()->isEverythingFetched())
+ {
+ // Folders have a priority over items and they download items as well
+ // Wait untill initial folder fetch is done
+ LL_DEBUGS("InventoryFetch") << "Folder fetch in progress, resetting fetch timer" << LL_ENDL;
+
+ mFetchingPeriod.reset();
+ mFetchingPeriod.setTimerExpirySec(FETCH_TIMER_EXPIRY);
+ }
// Have we exceeded max wait time?
bool timeout_expired = mFetchingPeriod.hasExpired();
@@ -176,7 +188,7 @@ void LLInventoryFetchItemsObserver::changed(U32 mask)
if (timeout_expired)
{
// Just concede that this item hasn't arrived in reasonable time and continue on.
- LL_WARNS() << "Fetcher timed out when fetching inventory item UUID: " << item_id << LL_ENDL;
+ LL_WARNS("InventoryFetch") << "Fetcher timed out when fetching inventory item UUID: " << item_id << LL_ENDL;
it = mIncomplete.erase(it);
}
else
@@ -191,7 +203,7 @@ void LLInventoryFetchItemsObserver::changed(U32 mask)
if (mIncomplete.empty())
{
- LL_DEBUGS() << this << " done at remaining incomplete "
+ LL_DEBUGS("InventoryFetch") << this << " done at remaining incomplete "
<< mIncomplete.size() << " complete " << mComplete.size() << LL_ENDL;
done();
}
@@ -251,29 +263,21 @@ void fetch_items_from_llsd(const LLSD& items_llsd)
void LLInventoryFetchItemsObserver::startFetch()
{
- LLUUID owner_id;
+ bool aisv3 = AISAPI::isAvailable();
+
LLSD items_llsd;
+
+ typedef std::map<LLUUID, uuid_vec_t> requests_by_folders_t;
+ requests_by_folders_t requests;
for (uuid_vec_t::const_iterator it = mIDs.begin(); it < mIDs.end(); ++it)
{
- LLViewerInventoryItem* item = gInventory.getItem(*it);
- if (item)
- {
- if (item->isFinished())
- {
- // It's complete, so put it on the complete container.
- mComplete.push_back(*it);
- continue;
- }
- else
- {
- owner_id = item->getPermissions().getOwner();
- }
- }
- else
- {
- // assume it's agent inventory.
- owner_id = gAgent.getID();
- }
+ LLViewerInventoryItem* item = gInventory.getItem(*it);
+ if (item && item->isFinished())
+ {
+ // It's complete, so put it on the complete container.
+ mComplete.push_back(*it);
+ continue;
+ }
// Ignore categories since they're not items. We
// could also just add this to mComplete but not sure what the
@@ -294,17 +298,98 @@ void LLInventoryFetchItemsObserver::startFetch()
// pack this on the message.
mIncomplete.push_back(*it);
- // Prepare the data to fetch
- LLSD item_entry;
- item_entry["owner_id"] = owner_id;
- item_entry["item_id"] = (*it);
- items_llsd.append(item_entry);
+ if (aisv3)
+ {
+ if (item)
+ {
+ LLUUID parent_id = item->getParentUUID();
+ requests[parent_id].push_back(*it);
+ }
+ else
+ {
+ // Can happen for gestures and calling cards if server notified us before they fetched
+ // Request by id without checking for an item.
+ LLInventoryModelBackgroundFetch::getInstance()->scheduleItemFetch(*it);
+ }
+ }
+ else
+ {
+ // Prepare the data to fetch
+ LLSD item_entry;
+ if (item)
+ {
+ item_entry["owner_id"] = item->getPermissions().getOwner();
+ }
+ else
+ {
+ // assume it's agent inventory.
+ item_entry["owner_id"] = gAgent.getID();
+ }
+ item_entry["item_id"] = (*it);
+ items_llsd.append(item_entry);
+ }
}
mFetchingPeriod.reset();
mFetchingPeriod.setTimerExpirySec(FETCH_TIMER_EXPIRY);
- fetch_items_from_llsd(items_llsd);
+ if (aisv3)
+ {
+ for (requests_by_folders_t::value_type &folder : requests)
+ {
+ if (folder.second.size() > MAX_INDIVIDUAL_ITEM_REQUESTS)
+ {
+ // requesting one by one will take a while
+ // do whole folder
+ LLInventoryModelBackgroundFetch::getInstance()->scheduleFolderFetch(folder.first, true);
+ }
+ else
+ {
+ LLViewerInventoryCategory* cat = gInventory.getCategory(folder.first);
+ if (cat)
+ {
+ if (cat->getVersion() == LLViewerInventoryCategory::VERSION_UNKNOWN)
+ {
+ // start fetching whole folder since it's not ready either way
+ cat->fetch();
+ }
+ else if (cat->getViewerDescendentCount() <= folder.second.size()
+ || cat->getDescendentCount() <= folder.second.size())
+ {
+ // Start fetching whole folder since we need all items
+ LLInventoryModelBackgroundFetch::getInstance()->scheduleFolderFetch(folder.first, true);
+
+ }
+ else
+ {
+ // get items one by one
+ for (LLUUID &item_id : folder.second)
+ {
+ LLInventoryModelBackgroundFetch::getInstance()->scheduleItemFetch(item_id);
+ }
+ }
+ }
+ else
+ {
+ // Isn't supposed to happen? We should have all folders
+ // and if item exists, folder is supposed to exist as well.
+ llassert(false);
+ LL_WARNS("Inventory") << "Missing folder: " << folder.first << " fetching items individually" << LL_ENDL;
+
+ // get items one by one
+ for (LLUUID &item_id : folder.second)
+ {
+ LLInventoryModelBackgroundFetch::getInstance()->scheduleItemFetch(item_id);
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ fetch_items_from_llsd(items_llsd);
+ }
+
}
LLInventoryFetchDescendentsObserver::LLInventoryFetchDescendentsObserver(const LLUUID& cat_id) :
@@ -649,6 +734,13 @@ void LLInventoryCategoriesObserver::changed(U32 mask)
}
}
+ const LLUUID thumbnail_id = category->getThumbnailUUID();
+ if (cat_data.mThumbnailId != thumbnail_id)
+ {
+ cat_data.mThumbnailId = thumbnail_id;
+ cat_changed = true;
+ }
+
// If anything has changed above, fire the callback.
if (cat_changed)
cat_data.mCallback();
@@ -666,6 +758,7 @@ bool LLInventoryCategoriesObserver::addCategory(const LLUUID& cat_id, callback_t
S32 version = LLViewerInventoryCategory::VERSION_UNKNOWN;
S32 current_num_known_descendents = LLViewerInventoryCategory::DESCENDENT_COUNT_UNKNOWN;
bool can_be_added = true;
+ LLUUID thumbnail_id;
LLViewerInventoryCategory* category = gInventory.getCategory(cat_id);
// If category could not be retrieved it might mean that
@@ -677,6 +770,7 @@ bool LLInventoryCategoriesObserver::addCategory(const LLUUID& cat_id, callback_t
// Inventory category version is used to find out if some changes
// to a category have been made.
version = category->getVersion();
+ thumbnail_id = category->getThumbnailUUID();
LLInventoryModel::cat_array_t* cats;
LLInventoryModel::item_array_t* items;
@@ -701,12 +795,12 @@ bool LLInventoryCategoriesObserver::addCategory(const LLUUID& cat_id, callback_t
{
if(init_name_hash)
{
- digest_t item_name_hash = gInventory.hashDirectDescendentNames(cat_id);
- mCategoryMap.insert(category_map_value_t(cat_id,LLCategoryData(cat_id, cb, version, current_num_known_descendents,item_name_hash)));
+ digest_t item_name_hash = gInventory.hashDirectDescendentNames(cat_id);
+ mCategoryMap.insert(category_map_value_t(cat_id,LLCategoryData(cat_id, thumbnail_id, cb, version, current_num_known_descendents,item_name_hash)));
}
else
{
- mCategoryMap.insert(category_map_value_t(cat_id,LLCategoryData(cat_id, cb, version, current_num_known_descendents)));
+ mCategoryMap.insert(category_map_value_t(cat_id,LLCategoryData(cat_id, thumbnail_id, cb, version, current_num_known_descendents)));
}
}
@@ -719,23 +813,25 @@ void LLInventoryCategoriesObserver::removeCategory(const LLUUID& cat_id)
}
LLInventoryCategoriesObserver::LLCategoryData::LLCategoryData(
- const LLUUID& cat_id, callback_t cb, S32 version, S32 num_descendents)
+ const LLUUID& cat_id, const LLUUID& thumbnail_id, callback_t cb, S32 version, S32 num_descendents)
: mCatID(cat_id)
, mCallback(cb)
, mVersion(version)
, mDescendentsCount(num_descendents)
+ , mThumbnailId(thumbnail_id)
, mIsNameHashInitialized(false)
{
}
LLInventoryCategoriesObserver::LLCategoryData::LLCategoryData(
- const LLUUID& cat_id, callback_t cb, S32 version, S32 num_descendents, const digest_t& name_hash)
+ const LLUUID& cat_id, const LLUUID& thumbnail_id, callback_t cb, S32 version, S32 num_descendents, const digest_t& name_hash)
: mCatID(cat_id)
, mCallback(cb)
, mVersion(version)
, mDescendentsCount(num_descendents)
+ , mThumbnailId(thumbnail_id)
, mIsNameHashInitialized(true)
, mItemNameHash(name_hash)
{