SL-20015 wait for the outfit items to load before wearing it

meow-7.2.2
Maxim Nikolenko 2023-07-19 21:15:52 +03:00 committed by GitHub
parent acf82867b6
commit 3058e6e6fd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 108 additions and 2 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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