summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrey Kleshchev <andreykproductengine@lindenlab.com>2023-03-20 22:06:20 +0200
committerakleshchev <117672381+akleshchev@users.noreply.github.com>2023-03-20 23:39:30 +0200
commitb68a67491026a055f0de9df349508b9e60a200ed (patch)
tree546a35d7a8c8be76150be477b128acae6107811f
parent72131418aa943b93f61508993d7006b02ebd9c35 (diff)
SL-18629 Load cof only once links are ready
-rw-r--r--indra/newview/llaisapi.cpp68
-rw-r--r--indra/newview/llappearancemgr.cpp46
-rw-r--r--indra/newview/llappearancemgr.h1
-rw-r--r--indra/newview/llinventoryfunctions.cpp13
-rw-r--r--indra/newview/llinventoryfunctions.h14
-rw-r--r--indra/newview/llinventorymodel.cpp16
-rw-r--r--indra/newview/llinventorymodel.h3
7 files changed, 121 insertions, 40 deletions
diff --git a/indra/newview/llaisapi.cpp b/indra/newview/llaisapi.cpp
index ece03d6988..d2bf7a0e9a 100644
--- a/indra/newview/llaisapi.cpp
+++ b/indra/newview/llaisapi.cpp
@@ -637,15 +637,17 @@ void AISAPI::InvokeAISCommandCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t ht
bool needs_callback = true;
LLUUID id(LLUUID::null);
- if ( ( (type == COPYLIBRARYCATEGORY)
- || (type == FETCHCATEGORYCATEGORIES)
- || (type == FETCHCATEGORYCHILDREN))
- && result.has("category_id"))
- {
- id = result["category_id"];
- }
- if (type == FETCHITEM)
+ switch (type)
{
+ case COPYLIBRARYCATEGORY:
+ case FETCHCATEGORYCATEGORIES:
+ case FETCHCATEGORYCHILDREN:
+ if (result.has("category_id"))
+ {
+ id = result["category_id"];
+ }
+ break;
+ case FETCHITEM:
if (result.has("item_id"))
{
id = result["item_id"];
@@ -654,33 +656,35 @@ void AISAPI::InvokeAISCommandCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t ht
{
id = result["linked_id"];
}
- }
- if (type == CREATEINVENTORY)
- {
+ break;
+ case CREATEINVENTORY:
// CREATEINVENTORY can have multiple callbacks
- if (result.has("_created_categories"))
- {
- LLSD& cats = result["_created_categories"];
- LLSD::array_const_iterator cat_iter;
- for (cat_iter = cats.beginArray(); cat_iter != cats.endArray(); ++cat_iter)
- {
- LLUUID cat_id = *cat_iter;
- callback(cat_id);
+ if (result.has("_created_categories"))
+ {
+ LLSD& cats = result["_created_categories"];
+ LLSD::array_const_iterator cat_iter;
+ for (cat_iter = cats.beginArray(); cat_iter != cats.endArray(); ++cat_iter)
+ {
+ LLUUID cat_id = *cat_iter;
+ callback(cat_id);
needs_callback = false;
- }
- }
- if (result.has("_created_items"))
- {
- LLSD& items = result["_created_items"];
- LLSD::array_const_iterator item_iter;
- for (item_iter = items.beginArray(); item_iter != items.endArray(); ++item_iter)
- {
- LLUUID item_id = *item_iter;
- callback(item_id);
+ }
+ }
+ if (result.has("_created_items"))
+ {
+ LLSD& items = result["_created_items"];
+ LLSD::array_const_iterator item_iter;
+ for (item_iter = items.beginArray(); item_iter != items.endArray(); ++item_iter)
+ {
+ LLUUID item_id = *item_iter;
+ callback(item_id);
needs_callback = false;
- }
- }
- }
+ }
+ }
+ break;
+ default:
+ break;
+ }
if (needs_callback)
{
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index 4e36a4c351..1de3cef3ba 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -40,6 +40,7 @@
#include "llgesturemgr.h"
#include "llinventorybridge.h"
#include "llinventoryfunctions.h"
+#include "llinventorymodelbackgroundfetch.h"
#include "llinventoryobserver.h"
#include "llnotificationsutil.h"
#include "lloutfitobserver.h"
@@ -2416,6 +2417,46 @@ void LLAppearanceMgr::updateAppearanceFromCOF(bool enforce_item_restrictions,
LL_DEBUGS("Avatar") << self_av_string() << "starting" << LL_ENDL;
+ if (gInventory.hasPosiblyBrockenLinks())
+ {
+ // Inventory has either broken links or links that
+ // haven't loaded yet and fetch is still in progress.
+ // Check if LLAppearanceMgr needs to wait.
+ LLUUID current_outfit_id = getCOF();
+ LLInventoryModel::item_array_t cof_items;
+ LLInventoryModel::cat_array_t cof_cats;
+ LLFindBrokenLinks is_brocken_link;
+ gInventory.collectDescendentsIf(current_outfit_id,
+ cof_cats,
+ cof_items,
+ LLInventoryModel::EXCLUDE_TRASH,
+ is_brocken_link);
+
+ if (cof_items.size() > 0)
+ {
+ // 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)
+ if (!mBulkFecthCallbackSlot.connected())
+ {
+ nullary_func_t cb = post_update_func;
+ mBulkFecthCallbackSlot =
+ LLInventoryModelBackgroundFetch::getInstance()->setAllFoldersFetchedCallback(
+ [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;
+ }
+ }
+
if (enforce_item_restrictions)
{
// The point here is just to call
@@ -4213,6 +4254,11 @@ 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 8a55a848db..53b8098a44 100644
--- a/indra/newview/llappearancemgr.h
+++ b/indra/newview/llappearancemgr.h
@@ -263,6 +263,7 @@ 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/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp
index c2e9137910..dd116ce2d2 100644
--- a/indra/newview/llinventoryfunctions.cpp
+++ b/indra/newview/llinventoryfunctions.cpp
@@ -2274,6 +2274,19 @@ bool LLFindCOFValidItems::operator()(LLInventoryCategory* cat,
}
}
+bool LLFindBrokenLinks::operator()(LLInventoryCategory* cat,
+ LLInventoryItem* item)
+{
+ // only for broken links getType will be a link
+ // otherwise it's supposed to have the type of an item
+ // it is linked too
+ if (item && LLAssetType::lookupIsLinkType(item->getType()))
+ {
+ return TRUE;
+ }
+ return FALSE;
+}
+
bool LLFindWearables::operator()(LLInventoryCategory* cat,
LLInventoryItem* item)
{
diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h
index ec5e53f9a6..1cc778f8a5 100644
--- a/indra/newview/llinventoryfunctions.h
+++ b/indra/newview/llinventoryfunctions.h
@@ -361,6 +361,20 @@ public:
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Class LLFindBrokenLinks
+//
+// Collects broken links
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+class LLFindBrokenLinks : public LLInventoryCollectFunctor
+{
+public:
+ LLFindBrokenLinks() {}
+ virtual ~LLFindBrokenLinks() {}
+ virtual bool operator()(LLInventoryCategory* cat,
+ LLInventoryItem* item);
+};
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class LLFindByMask
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class LLFindByMask : public LLInventoryCollectFunctor
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index b82f0c3ede..b833571ee9 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -440,7 +440,7 @@ LLInventoryModel::LLInventoryModel()
mIsNotifyObservers(FALSE),
mModifyMask(LLInventoryObserver::ALL),
mChangedItemIDs(),
- mBulckFecthCallbackSlot(),
+ mBulkFecthCallbackSlot(),
mObservers(),
mHttpRequestFG(NULL),
mHttpRequestBG(NULL),
@@ -473,9 +473,9 @@ void LLInventoryModel::cleanupInventory()
delete observer;
}
- if (mBulckFecthCallbackSlot.connected())
+ if (mBulkFecthCallbackSlot.connected())
{
- mBulckFecthCallbackSlot.disconnect();
+ mBulkFecthCallbackSlot.disconnect();
}
mObservers.clear();
@@ -1764,6 +1764,7 @@ void LLInventoryModel::rebuildBrockenLinks()
addChangedMask(LLInventoryObserver::REBUILD, link_id);
}
mPossiblyBrockenLinks.clear();
+ notifyObservers();
}
// Does not appear to be used currently.
@@ -2389,16 +2390,17 @@ void LLInventoryModel::addItem(LLViewerInventoryItem* item)
// isEverythingFetched is actually 'initial' fetch only.
// Schedule this link for a recheck once inventory gets loaded
mPossiblyBrockenLinks.insert(item->getUUID());
- if (!mBulckFecthCallbackSlot.connected())
+ if (!mBulkFecthCallbackSlot.connected())
{
// Links might take a while to update this way, and there
// might be a lot of them. A better option might be to check
// links periodically with final check on fetch completion.
- mBulckFecthCallbackSlot =
+ mBulkFecthCallbackSlot =
LLInventoryModelBackgroundFetch::getInstance()->setAllFoldersFetchedCallback(
- []()
+ [this]()
{
- gInventory.rebuildBrockenLinks();
+ rebuildBrockenLinks();
+ mBulkFecthCallbackSlot.disconnect();
});
}
LL_DEBUGS(LOG_INV) << "Scheduling a link to be rebuilt later [ name: " << item->getName()
diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h
index 02278ed957..ac6eda02d8 100644
--- a/indra/newview/llinventorymodel.h
+++ b/indra/newview/llinventorymodel.h
@@ -410,6 +410,7 @@ public:
// Marks links from a "possibly" broken list for a rebuild
// clears the list
void rebuildBrockenLinks();
+ bool hasPosiblyBrockenLinks() const { return mPossiblyBrockenLinks.size() > 0; }
//--------------------------------------------------------------------
// Delete
@@ -579,7 +580,7 @@ private:
changed_items_t mChangedItemIDsBacklog;
changed_items_t mAddedItemIDsBacklog;
changed_items_t mPossiblyBrockenLinks;
- boost::signals2::connection mBulckFecthCallbackSlot;
+ boost::signals2::connection mBulkFecthCallbackSlot;
//--------------------------------------------------------------------