summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorMaxim Nikolenko <maximnproductengine@lindenlab.com>2023-07-19 21:15:52 +0300
committerGitHub <noreply@github.com>2023-07-19 21:15:52 +0300
commit3058e6e6fd66ad4abb91fa5354ee11f6b7843a02 (patch)
treeb18fa67f59c74d9dde9008b8d42105de38509ae7 /indra
parentacf82867b61535b7b39b89f71a282e3ce3d0673e (diff)
SL-20015 wait for the outfit items to load before wearing it
Diffstat (limited to 'indra')
-rw-r--r--indra/newview/llaisapi.cpp36
-rw-r--r--indra/newview/llaisapi.h2
-rw-r--r--indra/newview/llappearancemgr.cpp29
-rw-r--r--indra/newview/llappearancemgr.h1
-rw-r--r--indra/newview/llinventorymodel.cpp12
-rw-r--r--indra/newview/llinventorymodel.h4
-rw-r--r--indra/newview/llstartup.cpp25
-rw-r--r--indra/newview/llstartup.h1
8 files changed, 108 insertions, 2 deletions
diff --git a/indra/newview/llaisapi.cpp b/indra/newview/llaisapi.cpp
index 4ac2acf1d1..f3799361db 100644
--- a/indra/newview/llaisapi.cpp
+++ b/indra/newview/llaisapi.cpp
@@ -709,6 +709,40 @@ void AISAPI::FetchCOF(completion_t callback)
EnqueueAISCommand("FetchCOF", proc);
}
+void AISAPI::FetchCategoryLinks(const LLUUID &catId, completion_t callback)
+{
+ std::string cap = getInvCap();
+ if (cap.empty())
+ {
+ LL_WARNS("Inventory") << "Inventory cap not found!" << LL_ENDL;
+ if (callback)
+ {
+ callback(LLUUID::null);
+ }
+ return;
+ }
+ std::string url = cap + std::string("/category/") + catId.asString() + "/links";
+
+ invokationFn_t getFn = boost::bind(
+ // Humans ignore next line. It is just a cast to specify which LLCoreHttpUtil::HttpCoroutineAdapter routine overload.
+ static_cast<LLSD (LLCoreHttpUtil::HttpCoroutineAdapter::*)(LLCore::HttpRequest::ptr_t, const std::string &,
+ LLCore::HttpOptions::ptr_t, LLCore::HttpHeaders::ptr_t)>
+ //----
+ // _1 -> httpAdapter
+ // _2 -> httpRequest
+ // _3 -> url
+ // _4 -> body
+ // _5 -> httpOptions
+ // _6 -> httpHeaders
+ (&LLCoreHttpUtil::HttpCoroutineAdapter::getAndSuspend),
+ _1, _2, _3, _5, _6);
+
+ LLCoprocedureManager::CoProcedure_t proc(
+ boost::bind(&AISAPI::InvokeAISCommandCoro, _1, getFn, url, LLUUID::null, LLSD(), callback, FETCHCATEGORYLINKS));
+
+ EnqueueAISCommand("FetchCategoryLinks", proc);
+}
+
/*static*/
void AISAPI::FetchOrphans(completion_t callback)
{
@@ -938,6 +972,7 @@ void AISAPI::InvokeAISCommandCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t ht
case FETCHCATEGORYCATEGORIES:
case FETCHCATEGORYCHILDREN:
case FETCHCATEGORYSUBSET:
+ case FETCHCATEGORYLINKS:
case FETCHCOF:
if (result.has("category_id"))
{
@@ -1002,6 +1037,7 @@ AISUpdate::AISUpdate(const LLSD& update, AISAPI::COMMAND_TYPE type, const LLSD&
|| (type == AISAPI::FETCHCATEGORYCATEGORIES)
|| (type == AISAPI::FETCHCATEGORYSUBSET)
|| (type == AISAPI::FETCHCOF)
+ || (type == AISAPI::FETCHCATEGORYLINKS)
|| (type == AISAPI::FETCHORPHANS);
// parse update llsd into stuff to do or parse received items.
mFetchDepth = MAX_FOLDER_DEPTH_REQUEST;
diff --git a/indra/newview/llaisapi.h b/indra/newview/llaisapi.h
index 973c82a847..53c74ae078 100644
--- a/indra/newview/llaisapi.h
+++ b/indra/newview/llaisapi.h
@@ -62,6 +62,7 @@ public:
static void FetchCategoryCategories(const LLUUID &catId, ITEM_TYPE type = AISAPI::ITEM_TYPE::INVENTORY, bool recursive = false, completion_t callback = completion_t(), S32 depth = 0);
static void FetchCategorySubset(const LLUUID& catId, const uuid_vec_t specificChildren, ITEM_TYPE type = AISAPI::ITEM_TYPE::INVENTORY, bool recursive = false, completion_t callback = completion_t(), S32 depth = 0);
static void FetchCOF(completion_t callback = completion_t());
+ static void FetchCategoryLinks(const LLUUID &catId, completion_t callback = completion_t());
static void FetchOrphans(completion_t callback = completion_t() );
static void CopyLibraryCategory(const LLUUID& sourceId, const LLUUID& destId, bool copySubfolders, completion_t callback = completion_t());
@@ -81,6 +82,7 @@ public:
FETCHCATEGORYSUBSET,
FETCHCOF,
FETCHORPHANS,
+ FETCHCATEGORYLINKS
} COMMAND_TYPE;
private:
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index 454ac5d88c..d4fc6a9f9d 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -4612,6 +4612,35 @@ void callAfterCategoryFetch(const LLUUID& cat_id, nullary_func_t cb)
}
}
+void callAfterCategoryLinksFetch(const LLUUID &cat_id, nullary_func_t cb)
+{
+ LLViewerInventoryCategory *cat = gInventory.getCategory(cat_id);
+ if (AISAPI::isAvailable())
+ {
+ // Mark folder (update timer) so that background fetch won't request it
+ cat->setFetching(LLViewerInventoryCategory::FETCH_RECURSIVE);
+ // Assume that we have no relevant cache. Fetch folder, and items folder's links point to.
+ AISAPI::FetchCategoryLinks(cat_id,
+ [cb, cat_id](const LLUUID &id)
+ {
+ cb();
+ LLViewerInventoryCategory *cat = gInventory.getCategory(cat_id);
+ if (cat)
+ {
+ cat->setFetching(LLViewerInventoryCategory::FETCH_NONE);
+ }
+ });
+ }
+ else
+ {
+ LL_WARNS() << "AIS API v3 not available, can't use AISAPI::FetchCOF" << LL_ENDL;
+ // startup should have marked folder as fetching, remove that
+ cat->setFetching(LLViewerInventoryCategory::FETCH_NONE);
+ callAfterCategoryFetch(cat_id, cb);
+ }
+
+}
+
void add_wearable_type_counts(const uuid_vec_t& ids,
S32& clothing_count,
S32& bodypart_count,
diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h
index f6aa30d865..43839e47a6 100644
--- a/indra/newview/llappearancemgr.h
+++ b/indra/newview/llappearancemgr.h
@@ -340,6 +340,7 @@ LLUUID findDescendentCategoryIDByName(const LLUUID& parent_id,const std::string&
// Invoke a given callable after category contents are fully fetched.
void callAfterCOFFetch(nullary_func_t cb);
void callAfterCategoryFetch(const LLUUID& cat_id, nullary_func_t cb);
+void callAfterCategoryLinksFetch(const LLUUID &cat_id, nullary_func_t cb);
// Wear all items in a uuid vector.
void wear_multiple(const uuid_vec_t& ids, bool replace);
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index ed375661b8..586f1388ff 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -79,6 +79,8 @@
const S32 LLInventoryModel::sCurrentInvCacheVersion = 3;
BOOL LLInventoryModel::sFirstTimeInViewer2 = TRUE;
+S32 LLInventoryModel::sPendingSystemFolders = 0;
+
///----------------------------------------------------------------------------
/// Local function declarations, constants, enums, and typedefs
///----------------------------------------------------------------------------
@@ -861,8 +863,9 @@ void LLInventoryModel::ensureCategoryForTypeExists(LLFolderType::EType preferred
}
else
{
- LL_DEBUGS("Inventory") << "Created category: " << new_cat_id
+ LL_WARNS("Inventory") << "Created category: " << new_cat_id
<< " for type: " << preferred_type << LL_ENDL;
+ sPendingSystemFolders--;
}
}
);
@@ -873,6 +876,10 @@ void LLInventoryModel::ensureCategoryForTypeExists(LLFolderType::EType preferred
<< " because inventory is not usable" << LL_ENDL;
}
}
+ else
+ {
+ sPendingSystemFolders--;
+ }
}
const LLUUID LLInventoryModel::findCategoryUUIDForTypeInRoot(
@@ -3253,6 +3260,9 @@ LLCore::HttpHandle LLInventoryModel::requestPost(bool foreground,
void LLInventoryModel::createCommonSystemCategories()
{
+ //amount of System Folder we should wait for
+ sPendingSystemFolders = 8;
+
gInventory.ensureCategoryForTypeExists(LLFolderType::FT_TRASH);
gInventory.ensureCategoryForTypeExists(LLFolderType::FT_FAVORITE);
gInventory.ensureCategoryForTypeExists(LLFolderType::FT_CALLINGCARD);
diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h
index db159d480a..a90ed2bf42 100644
--- a/indra/newview/llinventorymodel.h
+++ b/indra/newview/llinventorymodel.h
@@ -227,10 +227,14 @@ private:
//--------------------------------------------------------------------
public:
static BOOL getIsFirstTimeInViewer2();
+ static bool isSysFoldersReady() { return (sPendingSystemFolders == 0); }
+
private:
static BOOL sFirstTimeInViewer2;
const static S32 sCurrentInvCacheVersion; // expected inventory cache version
+ static S32 sPendingSystemFolders;
+
/** Initialization/Setup
** **
*******************************************************************************/
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 9f9e117760..c925563919 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -1912,7 +1912,22 @@ bool idle_startup()
LLInventoryModelBackgroundFetch::instance().start();
gInventory.createCommonSystemCategories();
+ LLStartUp::setStartupState(STATE_INVENTORY_CALLBACKS );
+ display_startup();
+
+ return FALSE;
+ }
+ //---------------------------------------------------------------------
+ // STATE_INVENTORY_CALLBACKS
+ //---------------------------------------------------------------------
+ if (STATE_INVENTORY_CALLBACKS == LLStartUp::getStartupState())
+ {
+ if (!LLInventoryModel::isSysFoldersReady())
+ {
+ display_startup();
+ return FALSE;
+ }
LLInventoryModelBackgroundFetch::instance().start();
LLUUID cof_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT);
LLViewerInventoryCategory* cof = gInventory.getCategory(cof_id);
@@ -2850,8 +2865,15 @@ void LLStartUp::loadInitialOutfit( const std::string& outfit_folder_name,
bool do_append = false;
LLViewerInventoryCategory *cat = gInventory.getCategory(cat_id);
// Need to fetch cof contents before we can wear.
- callAfterCategoryFetch(LLAppearanceMgr::instance().getCOF(),
+ if (do_copy)
+ {
+ callAfterCategoryFetch(LLAppearanceMgr::instance().getCOF(),
boost::bind(&LLAppearanceMgr::wearInventoryCategory, LLAppearanceMgr::getInstance(), cat, do_copy, do_append));
+ }
+ else
+ {
+ callAfterCategoryLinksFetch(cat_id, boost::bind(&LLAppearanceMgr::wearInventoryCategory, LLAppearanceMgr::getInstance(), cat, do_copy, do_append));
+ }
LL_DEBUGS() << "initial outfit category id: " << cat_id << LL_ENDL;
}
@@ -2904,6 +2926,7 @@ std::string LLStartUp::startupStateToString(EStartupState state)
RTNENUM( STATE_AGENT_SEND );
RTNENUM( STATE_AGENT_WAIT );
RTNENUM( STATE_INVENTORY_SEND );
+ RTNENUM(STATE_INVENTORY_CALLBACKS );
RTNENUM( STATE_MISC );
RTNENUM( STATE_PRECACHE );
RTNENUM( STATE_WEARABLES_WAIT );
diff --git a/indra/newview/llstartup.h b/indra/newview/llstartup.h
index fe8e215f76..921f088423 100644
--- a/indra/newview/llstartup.h
+++ b/indra/newview/llstartup.h
@@ -71,6 +71,7 @@ typedef enum {
STATE_AGENT_SEND, // Connect to a region
STATE_AGENT_WAIT, // Wait for region
STATE_INVENTORY_SEND, // Do inventory transfer
+ STATE_INVENTORY_CALLBACKS, // Wait for missing system folders and register callbacks
STATE_MISC, // Do more things (set bandwidth, start audio, save location, etc)
STATE_PRECACHE, // Wait a bit for textures to download
STATE_WEARABLES_WAIT, // Wait for clothing to download