summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/newview/llaisapi.cpp3
-rw-r--r--indra/newview/llappearancemgr.cpp98
-rw-r--r--indra/newview/llappearancemgr.h1
-rw-r--r--indra/newview/llinventorymodel.cpp50
-rw-r--r--indra/newview/llinventorymodel.h4
-rw-r--r--indra/newview/llinventorymodelbackgroundfetch.cpp20
-rw-r--r--indra/newview/llviewerinventory.cpp1
7 files changed, 126 insertions, 51 deletions
diff --git a/indra/newview/llaisapi.cpp b/indra/newview/llaisapi.cpp
index ef3305a69d..7a87fc6c3d 100644
--- a/indra/newview/llaisapi.cpp
+++ b/indra/newview/llaisapi.cpp
@@ -707,6 +707,8 @@ void AISAPI::InvokeAISCommandCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t ht
httpOptions->setTimeout(180);
+ LL_DEBUGS("Inventory") << "Request url: " << url << LL_ENDL;
+
LLSD result;
LLSD httpResults;
LLCore::HttpStatus status;
@@ -721,7 +723,6 @@ void AISAPI::InvokeAISCommandCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t ht
F32MillisecondsImplicit elapsed_time = ais_timer.getElapsedTimeF32();
LL_DEBUGS("Inventory") << "Request type: " << (S32)type
- << " \nRequest url: " << url
<< " \nRequest target: " << targetId
<< " \nElapsed time ince request: " << elapsed_time
<< " \nstatus: " << status.toULong() << LL_ENDL;
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index 59bf418a00..e160b5813f 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -586,6 +586,66 @@ LLUpdateAppearanceAndEditWearableOnDestroy::~LLUpdateAppearanceAndEditWearableOn
}
}
+class LLBrokenLinkObserver : public LLInventoryObserver
+{
+public:
+ LLUUID mUUID;
+ bool mEnforceItemRestrictions;
+ bool mEnforceOrdering;
+ nullary_func_t mPostUpdateFunc;
+
+ LLBrokenLinkObserver(const LLUUID& uuid,
+ bool enforce_item_restrictions ,
+ bool enforce_ordering ,
+ nullary_func_t post_update_func) :
+ mUUID(uuid),
+ mEnforceItemRestrictions(enforce_item_restrictions),
+ mEnforceOrdering(enforce_ordering),
+ mPostUpdateFunc(post_update_func)
+ {
+ }
+ /* virtual */ void changed(U32 mask);
+ void postProcess();
+};
+
+void LLBrokenLinkObserver::changed(U32 mask)
+{
+ if (mask & LLInventoryObserver::REBUILD)
+ {
+ // This observer should be executed after LLInventoryPanel::itemChanged(),
+ // but if it isn't, consider calling updateAppearanceFromCOF with a delay
+ const uuid_set_t& changed_item_ids = gInventory.getChangedIDs();
+ for (uuid_set_t::const_iterator it = changed_item_ids.begin(); it != changed_item_ids.end(); ++it)
+ {
+ const LLUUID& id = *it;
+ if (id == mUUID)
+ {
+ // Might not be processed yet and it is not a
+ // good idea to update appearane here, postpone.
+ doOnIdleOneTime([this]()
+ {
+ postProcess();
+ });
+
+ gInventory.removeObserver(this);
+ return;
+ }
+ }
+ }
+}
+
+void LLBrokenLinkObserver::postProcess()
+{
+ LLViewerInventoryItem* item = gInventory.getItem(mUUID);
+ llassert(item && !item->getIsBrokenLink()); // the whole point was to get a correct link
+
+ LLAppearanceMgr::instance().updateAppearanceFromCOF(
+ mEnforceItemRestrictions ,
+ mEnforceOrdering ,
+ mPostUpdateFunc);
+ delete this;
+}
+
struct LLFoundData
{
@@ -2435,35 +2495,16 @@ void LLAppearanceMgr::updateAppearanceFromCOF(bool enforce_item_restrictions,
{
// Some links haven't loaded yet, but fetch isn't complete so
// links are likely fine and we will have to wait for them to
- // load (if inventory takes too long to load, might be a good
- // idea to make this check periodical)
+ // load
if (LLInventoryModelBackgroundFetch::getInstance()->folderFetchActive())
{
- if (!mBulkFecthCallbackSlot.connected())
- {
- nullary_func_t cb = post_update_func;
- mBulkFecthCallbackSlot =
- LLInventoryModelBackgroundFetch::getInstance()->setFetchCompletionCallback(
- [this, enforce_ordering, post_update_func, cb]()
- {
- // inventory model should be already tracking this
- // callback, but make sure rebuildBrockenLinks gets
- // called before a cof update
- gInventory.rebuildBrockenLinks();
- updateAppearanceFromCOF(enforce_ordering, post_update_func, post_update_func);
- mBulkFecthCallbackSlot.disconnect();
- });
- }
- return;
- }
- else
- {
- // this should have happened on completion callback,
- // check why it didn't then fix it
- llassert(false);
- // try to recover now
- gInventory.rebuildBrockenLinks();
+ LLBrokenLinkObserver* observer = new LLBrokenLinkObserver(cof_items.front()->getUUID(),
+ enforce_item_restrictions,
+ enforce_ordering,
+ post_update_func);
+ gInventory.addObserver(observer);
+ return;
}
}
}
@@ -4262,11 +4303,6 @@ LLAppearanceMgr::LLAppearanceMgr():
LLAppearanceMgr::~LLAppearanceMgr()
{
mActive = false;
-
- if (!mBulkFecthCallbackSlot.connected())
- {
- mBulkFecthCallbackSlot.disconnect();
- }
}
void LLAppearanceMgr::setAttachmentInvLinkEnable(bool val)
diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h
index edb4be83bb..cf953d21ac 100644
--- a/indra/newview/llappearancemgr.h
+++ b/indra/newview/llappearancemgr.h
@@ -264,7 +264,6 @@ private:
bool mIsInUpdateAppearanceFromCOF; // to detect recursive calls.
bool mOutstandingAppearanceBakeRequest; // A bake request is outstanding. Do not overlap.
bool mRerequestAppearanceBake;
- boost::signals2::connection mBulkFecthCallbackSlot;
/**
* Lock for blocking operations on outfit until server reply or timeout exceed
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index 4bca2ce650..32acd0eb03 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -1764,11 +1764,19 @@ void LLInventoryModel::rebuildBrockenLinks()
// make sure we aren't adding expensive Rebuild to anything else.
notifyObservers();
- for (const LLUUID &link_id : mPossiblyBrockenLinks)
+ for (const broken_links_t::value_type &link_list : mPossiblyBrockenLinks)
{
- addChangedMask(LLInventoryObserver::REBUILD, link_id);
+ for (const LLUUID& link_id : link_list.second)
+ {
+ addChangedMask(LLInventoryObserver::REBUILD , link_id);
+ }
+ }
+ for (const LLUUID& link_id : mLinksRebuildList)
+ {
+ addChangedMask(LLInventoryObserver::REBUILD , link_id);
}
mPossiblyBrockenLinks.clear();
+ mLinksRebuildList.clear();
notifyObservers();
}
@@ -2075,6 +2083,20 @@ void LLInventoryModel::idleNotifyObservers()
{
// *FIX: Think I want this conditional or moved elsewhere...
handleResponses(true);
+
+ if (mLinksRebuildList.size() > 0)
+ {
+ if (mModifyMask != LLInventoryObserver::NONE || (mChangedItemIDs.size() != 0))
+ {
+ notifyObservers();
+ }
+ for (const LLUUID& link_id : mLinksRebuildList)
+ {
+ addChangedMask(LLInventoryObserver::REBUILD , link_id);
+ }
+ mLinksRebuildList.clear();
+ notifyObservers();
+ }
if (mModifyMask == LLInventoryObserver::NONE && (mChangedItemIDs.size() == 0))
{
@@ -2394,11 +2416,14 @@ void LLInventoryModel::addItem(LLViewerInventoryItem* item)
// The item will show up as a broken link.
if (item->getIsBrokenLink())
{
- if (LLInventoryModelBackgroundFetch::getInstance()->folderFetchActive())
+ if (item->getAssetUUID().notNull()
+ && LLInventoryModelBackgroundFetch::getInstance()->folderFetchActive())
{
- // isEverythingFetched is actually 'initial' fetch only.
- // Schedule this link for a recheck once inventory gets loaded
- mPossiblyBrockenLinks.insert(item->getUUID());
+ // Schedule this link for a recheck as inventory gets loaded
+ // Todo: expand to cover not just an initial fetch
+ mPossiblyBrockenLinks[item->getAssetUUID()].insert(item->getUUID());
+
+ // Do a blank rebuild of links once fetch is done
if (!mBulkFecthCallbackSlot.connected())
{
// Links might take a while to update this way, and there
@@ -2408,6 +2433,9 @@ void LLInventoryModel::addItem(LLViewerInventoryItem* item)
LLInventoryModelBackgroundFetch::getInstance()->setFetchCompletionCallback(
[this]()
{
+ // rebuild is just in case, primary purpose is to wipe
+ // the list since we won't be getting anything 'new'
+ // see mLinksRebuildList
rebuildBrockenLinks();
mBulkFecthCallbackSlot.disconnect();
});
@@ -2424,6 +2452,16 @@ void LLInventoryModel::addItem(LLViewerInventoryItem* item)
<< " assetID: " << item->getAssetUUID() << " ) parent: " << item->getParentUUID() << LL_ENDL;
}
}
+ if (!mPossiblyBrockenLinks.empty())
+ {
+ // check if we are waiting for this item
+ broken_links_t::iterator iter = mPossiblyBrockenLinks.find(item->getUUID());
+ if (iter != mPossiblyBrockenLinks.end())
+ {
+ mLinksRebuildList.insert(iter->second.begin() , iter->second.end());
+ mPossiblyBrockenLinks.erase(iter);
+ }
+ }
if (item->getIsLinkType())
{
// Add back-link from linked-to UUID.
diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h
index b506eaac62..db159d480a 100644
--- a/indra/newview/llinventorymodel.h
+++ b/indra/newview/llinventorymodel.h
@@ -580,7 +580,9 @@ private:
U32 mModifyMaskBacklog;
changed_items_t mChangedItemIDsBacklog;
changed_items_t mAddedItemIDsBacklog;
- changed_items_t mPossiblyBrockenLinks;
+ typedef std::map<LLUUID , changed_items_t> broken_links_t;
+ broken_links_t mPossiblyBrockenLinks; // there can be multiple links per item
+ changed_items_t mLinksRebuildList;
boost::signals2::connection mBulkFecthCallbackSlot;
diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp
index f650cc383f..56646830a2 100644
--- a/indra/newview/llinventorymodelbackgroundfetch.cpp
+++ b/indra/newview/llinventorymodelbackgroundfetch.cpp
@@ -586,17 +586,15 @@ void LLInventoryModelBackgroundFetch::bulkFetchViaAis()
curent_time = LLTimer::getTotalSeconds();
}
- if (mRecursiveInventoryFetchStarted && mAllRecursiveFoldersFetched)
+ // Ideally we shouldn't fetch items if recursive fetch isn't done,
+ // but there is a chance some request will start timeouting and recursive
+ // fetch will get stuck on a signle folder, don't block item fetch in such case
+ while (!mFetchItemQueue.empty() && mFetchCount < max_concurrent_fetches && curent_time < end_time)
{
- // Don't fetch items if recursive fetch isn't done,
- // it gets both items and folders and should get the items in question faster
- while (!mFetchItemQueue.empty() && mFetchCount < max_concurrent_fetches && curent_time < end_time)
- {
- const FetchQueueInfo& fetch_info(mFetchItemQueue.front());
- bulkFetchViaAis(fetch_info);
- mFetchItemQueue.pop_front();
- curent_time = LLTimer::getTotalSeconds();
- }
+ const FetchQueueInfo& fetch_info(mFetchItemQueue.front());
+ bulkFetchViaAis(fetch_info);
+ mFetchItemQueue.pop_front();
+ curent_time = LLTimer::getTotalSeconds();
}
if (last_fetch_count != mFetchCount // if anything was added
@@ -696,7 +694,7 @@ void LLInventoryModelBackgroundFetch::bulkFetchViaAis(const FetchQueueInfo& fetc
item_type = AISAPI::LIBRARY;
}
- AISAPI::FetchCategoryChildren(cat_id , item_type , type == FT_RECURSIVE , cb);
+ AISAPI::FetchCategoryChildren(cat_id , item_type , type == FT_RECURSIVE , cb, 0);
}
}
else
diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp
index cd51a00c52..01ad4f0f09 100644
--- a/indra/newview/llviewerinventory.cpp
+++ b/indra/newview/llviewerinventory.cpp
@@ -579,6 +579,7 @@ LLViewerInventoryCategory::LLViewerInventoryCategory(const LLUUID& owner_id) :
LLViewerInventoryCategory::LLViewerInventoryCategory(const LLViewerInventoryCategory* other)
{
copyViewerCategory(other);
+ mFetching = FETCH_NONE;
}
LLViewerInventoryCategory::~LLViewerInventoryCategory()