SL-18629 Load cof only once links are ready

meow-7.2.2
Andrey Kleshchev 2023-03-20 22:06:20 +02:00 committed by akleshchev
parent 72131418aa
commit b68a674910
7 changed files with 121 additions and 40 deletions

View File

@ -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)
{

View File

@ -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)

View File

@ -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

View File

@ -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)
{

View File

@ -360,6 +360,20 @@ public:
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class LLFindBrokenLinks
//
// Collects broken links
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class LLFindBrokenLinks : public LLInventoryCollectFunctor
{
public:
LLFindBrokenLinks() {}
virtual ~LLFindBrokenLinks() {}
virtual bool operator()(LLInventoryCategory* cat,
LLInventoryItem* item);
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class LLFindByMask
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -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()

View File

@ -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;
//--------------------------------------------------------------------