From d8f0bc021f3e7e18e3918178f3c81cdf444fb0d3 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Fri, 5 Feb 2010 16:37:23 -0500 Subject: For EXT-4919: Initial gesture setup is wrong for new users. Checkpointing work in progress. --- indra/newview/llagentwearables.cpp | 4 +- indra/newview/llappearancemgr.cpp | 22 +++++ indra/newview/llappearancemgr.h | 6 +- indra/newview/llstartup.cpp | 159 ++++++++++++++++++++++++++++++++++--- indra/newview/llvoavatar.cpp | 3 +- 5 files changed, 178 insertions(+), 16 deletions(-) (limited to 'indra') diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index acbf02678c..f2e6a3a5fb 100644 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -1410,7 +1410,7 @@ LLUUID LLAgentWearables::makeNewOutfitLinks(const std::string& new_folder_name) new_folder_name); LLPointer cb = new LLShowCreatedOutfit(folder_id); - LLAppearanceManager::instance().shallowCopyCategory(LLAppearanceManager::instance().getCOF(),folder_id, cb); + LLAppearanceManager::instance().shallowCopyCategoryContents(LLAppearanceManager::instance().getCOF(),folder_id, cb); LLAppearanceManager::instance().createBaseOutfitLink(folder_id, cb); return folder_id; @@ -2327,7 +2327,7 @@ void LLLibraryOutfitsFetch::libraryDone(void) LLUUID folder_id = gInventory.createNewCategory(mImportedClothingID, LLFolderType::FT_NONE, iter->second); - LLAppearanceManager::getInstance()->shallowCopyCategory(iter->first, folder_id, copy_waiter); + LLAppearanceManager::getInstance()->shallowCopyCategoryContents(iter->first, folder_id, copy_waiter); } } else diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 0fe236c056..6c4c59c4e7 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -519,8 +519,30 @@ void LLAppearanceManager::changeOutfit(bool proceed, const LLUUID& category, boo LLAppearanceManager::instance().updateCOF(category,append); } +// Create a copy of src_id + contents as a subfolder of dst_id. void LLAppearanceManager::shallowCopyCategory(const LLUUID& src_id, const LLUUID& dst_id, LLPointer cb) +{ + LLInventoryCategory *src_cat = gInventory.getCategory(src_id); + if (!src_cat) + { + llwarns << "folder not found for src " << src_id.asString() << llendl; + return; + } + LLUUID parent_id = dst_id; + if(parent_id.isNull()) + { + parent_id = gInventory.getRootFolderID(); + } + LLUUID subfolder_id = gInventory.createNewCategory( parent_id, + LLFolderType::FT_NONE, + src_cat->getName()); + shallowCopyCategoryContents(src_id, subfolder_id, cb); +} + +// Copy contents of src_id to dst_id. +void LLAppearanceManager::shallowCopyCategoryContents(const LLUUID& src_id, const LLUUID& dst_id, + LLPointer cb) { LLInventoryModel::cat_array_t cats; LLInventoryModel::item_array_t items; diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h index 38d1e01d08..63ac4d5402 100644 --- a/indra/newview/llappearancemgr.h +++ b/indra/newview/llappearancemgr.h @@ -54,10 +54,14 @@ public: void wearOutfitByName(const std::string& name); void changeOutfit(bool proceed, const LLUUID& category, bool append); - // Copy all items in a category. + // Copy all items and the src category itself. void shallowCopyCategory(const LLUUID& src_id, const LLUUID& dst_id, LLPointer cb); + // Copy all items in a category. + void shallowCopyCategoryContents(const LLUUID& src_id, const LLUUID& dst_id, + LLPointer cb); + // Find the Current Outfit folder. const LLUUID getCOF() const; diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index a402dfc3d1..7dd597a0df 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -2530,6 +2530,109 @@ bool callback_choose_gender(const LLSD& notification, const LLSD& response) return false; } +LLViewerInventoryCategory* findDescendentCategoryByName(const LLUUID& parent_id,const std::string& name) +{ + LLInventoryModel::cat_array_t cat_array; + LLInventoryModel::item_array_t item_array; + LLNameCategoryCollector has_name(name); + gInventory.collectDescendentsIf(parent_id, + cat_array, + item_array, + LLInventoryModel::EXCLUDE_TRASH, + has_name); + if (0 == cat_array.count()) + return NULL; + else + return cat_array.get(0); +} + +class CopyAfterFetchStage2: public LLInventoryFetchObserver +{ +public: + CopyAfterFetchStage2(LLViewerInventoryCategory *cat, const LLUUID& dst_id): + mCat(cat), + mDstID(dst_id) + { + } + ~CopyAfterFetchStage2() + { + } + virtual void done() + { +// LLAppearanceManager::instance().shallowCopyCategory(cat,dst_id,NULL); + gInventory.removeObserver(this); + LLPointer cb(NULL); + LLAppearanceManager *app_mgr = &(LLAppearanceManager::instance()); + doOnIdle(boost::bind(&LLAppearanceManager::shallowCopyCategory,app_mgr,mCat->getUUID(),mDstID,cb)); + delete this; + } +protected: + LLViewerInventoryCategory *mCat; + LLUUID mDstID; +}; + +class CopyAfterFetchStage1: public LLInventoryFetchDescendentsObserver +{ +public: + CopyAfterFetchStage1(LLViewerInventoryCategory *cat, const LLUUID& dst_id): + mCat(cat), + mDstID(dst_id) + { + } + ~CopyAfterFetchStage1() + { + } + virtual void done() + { + // What we do here is get the complete information on the items in + // the library, and set up an observer that will wait for that to + // happen. + LLInventoryModel::cat_array_t cat_array; + LLInventoryModel::item_array_t item_array; + gInventory.collectDescendents(mCompleteFolders.front(), + cat_array, + item_array, + LLInventoryModel::EXCLUDE_TRASH); + S32 count = item_array.count(); + if(!count) + { + llwarns << "Nothing fetched in category " << mCompleteFolders.front() + << llendl; + //dec_busy_count(); + gInventory.removeObserver(this); + delete this; + return; + } + + CopyAfterFetchStage2 *stage2 = new CopyAfterFetchStage2(mCat,mDstID); + LLInventoryFetchObserver::item_ref_t ids; + for(S32 i = 0; i < count; ++i) + { + ids.push_back(item_array.get(i)->getUUID()); + } + + gInventory.removeObserver(this); + + // do the fetch + stage2->fetchItems(ids); + if(stage2->isEverythingComplete()) + { + // everything is already here - call done. + stage2->done(); + } + else + { + // it's all on it's way - add an observer, and the inventory + // will call done for us when everything is here. + gInventory.addObserver(stage2); + } + delete this; + } +protected: + LLViewerInventoryCategory *mCat; + LLUUID mDstID; +}; + void LLStartUp::loadInitialOutfit( const std::string& outfit_folder_name, const std::string& gender_name ) { @@ -2553,27 +2656,59 @@ void LLStartUp::loadInitialOutfit( const std::string& outfit_folder_name, // try to find the outfit - if not there, create some default // wearables. - LLInventoryModel::cat_array_t cat_array; - LLInventoryModel::item_array_t item_array; - LLNameCategoryCollector has_name(outfit_folder_name); - gInventory.collectDescendentsIf(gInventory.getLibraryRootFolderID(), - cat_array, - item_array, - LLInventoryModel::EXCLUDE_TRASH, - has_name); - if (0 == cat_array.count()) + LLViewerInventoryCategory *cat = findDescendentCategoryByName( + gInventory.getLibraryRootFolderID(), + outfit_folder_name); + if (!cat) { gAgentWearables.createStandardWearables(gender); } else { - LLInventoryCategory* cat = cat_array.get(0); bool do_copy = true; bool do_append = false; LLAppearanceManager::instance().wearInventoryCategory(cat, do_copy, do_append); } - LLAppearanceManager::instance().wearOutfitByName(gestures); - LLAppearanceManager::instance().wearOutfitByName(COMMON_GESTURES_FOLDER); + + // Copy gender-specific gestures. + LLViewerInventoryCategory *gestures_cat = findDescendentCategoryByName( + gInventory.getLibraryRootFolderID(), + gestures); + if (gestures_cat) + { + CopyAfterFetchStage1 *stage1 = new CopyAfterFetchStage1( + gestures_cat, gInventory.findCategoryUUIDForType(LLFolderType::FT_GESTURE)); + LLInventoryFetchDescendentsObserver::folder_ref_t folders; + folders.push_back(gestures_cat->getUUID()); + stage1->fetchDescendents(folders); + if (stage1->isEverythingComplete()) + { + stage1->done(); + } + else + { + gInventory.addObserver(stage1); + } + +// LLAppearanceManager::instance().shallowCopyCategory( +// gestures_cat->getUUID(), +// gInventory.findCategoryUUIDForType(LLFolderType::FT_GESTURE), +// NULL); + } + + // Copy common gestures. +#if 0 + LLViewerInventoryCategory *common_gestures_cat = findDescendentCategoryByName( + gInventory.getLibraryRootFolderID(), + COMMON_GESTURES_FOLDER); + if (common_gestures_cat) + { + LLAppearanceManager::instance().shallowCopyCategory( + common_gestures_cat->getUUID(), + gInventory.findCategoryUUIDForType(LLFolderType::FT_GESTURE), + NULL); + } +#endif // This is really misnamed -- it means we have started loading // an outfit/shape that will give the avatar a gender eventually. JC diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 4235f97eab..bafdd9474e 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -1869,7 +1869,8 @@ void LLVOAvatar::releaseMeshData() // virtual void LLVOAvatar::restoreMeshData() { - llassert(!isSelf()); + // BAP restore + //llassert(!isSelf()); LLMemType mt(LLMemType::MTYPE_AVATAR); //llinfos << "Restoring" << llendl; -- cgit v1.2.3 From f5b82a377256d5806ec101e8a9d90533ea1a3bf9 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Fri, 5 Feb 2010 18:44:35 -0500 Subject: For EXT-4919: Initial gesture setup is wrong for new users. Added a template-y mechanism for roundtripping an inventory fetch - hopefully could replace some gratuitous classes elsewhere as well. --- indra/newview/llappearancemgr.cpp | 27 +++++++ indra/newview/llappearancemgr.h | 102 ++++++++++++++++++++++++ indra/newview/llstartup.cpp | 161 ++++++-------------------------------- indra/newview/llvoavatar.cpp | 3 +- 4 files changed, 156 insertions(+), 137 deletions(-) (limited to 'indra') diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 6c4c59c4e7..6a0d5312ee 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -48,6 +48,31 @@ #include "llviewerregion.h" #include "llwearablelist.h" +LLUUID findDescendentCategoryIDByName(const LLUUID& parent_id,const std::string& name) +{ + LLInventoryModel::cat_array_t cat_array; + LLInventoryModel::item_array_t item_array; + LLNameCategoryCollector has_name(name); + gInventory.collectDescendentsIf(parent_id, + cat_array, + item_array, + LLInventoryModel::EXCLUDE_TRASH, + has_name); + if (0 == cat_array.count()) + return LLUUID(); + else + { + LLViewerInventoryCategory *cat = cat_array.get(0); + if (cat) + return cat->getUUID(); + else + { + llwarns << "null cat" << llendl; + return LLUUID(); + } + } +} + // support for secondlife:///app/appearance SLapps class LLAppearanceHandler : public LLCommandHandler { @@ -538,6 +563,8 @@ void LLAppearanceManager::shallowCopyCategory(const LLUUID& src_id, const LLUUID LLFolderType::FT_NONE, src_cat->getName()); shallowCopyCategoryContents(src_id, subfolder_id, cb); + + gInventory.notifyObservers(); } // Copy contents of src_id to dst_id. diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h index 63ac4d5402..8ea52fb4af 100644 --- a/indra/newview/llappearancemgr.h +++ b/indra/newview/llappearancemgr.h @@ -35,6 +35,7 @@ #include "llsingleton.h" #include "llinventorymodel.h" +#include "llinventoryobserver.h" #include "llcallbacklist.h" class LLWearable; @@ -148,6 +149,8 @@ public: #define SUPPORT_ENSEMBLES 0 +LLUUID findDescendentCategoryIDByName(const LLUUID& parent_id,const std::string& name); + // Shim class and template function to allow arbitrary boost::bind // expressions to be run as one-time idle callbacks. template @@ -216,4 +219,103 @@ void doOnIdleRepeating(T callable) gIdleCallbacks.addFunction(&OnIdleCallbackRepeating::onIdle,cb_functor); } +template +class CallAfterCategoryFetchStage2: public LLInventoryFetchObserver +{ +public: + CallAfterCategoryFetchStage2(T callable): + mCallable(callable) + { + } + ~CallAfterCategoryFetchStage2() + { + } + virtual void done() + { + gInventory.removeObserver(this); + doOnIdle(mCallable); + delete this; + } +protected: + T mCallable; +}; + +template +class CallAfterCategoryFetchStage1: public LLInventoryFetchDescendentsObserver +{ +public: + CallAfterCategoryFetchStage1(T callable): + mCallable(callable) + { + } + ~CallAfterCategoryFetchStage1() + { + } + virtual void done() + { + // What we do here is get the complete information on the items in + // the library, and set up an observer that will wait for that to + // happen. + LLInventoryModel::cat_array_t cat_array; + LLInventoryModel::item_array_t item_array; + gInventory.collectDescendents(mCompleteFolders.front(), + cat_array, + item_array, + LLInventoryModel::EXCLUDE_TRASH); + S32 count = item_array.count(); + if(!count) + { + llwarns << "Nothing fetched in category " << mCompleteFolders.front() + << llendl; + //dec_busy_count(); + gInventory.removeObserver(this); + delete this; + return; + } + + CallAfterCategoryFetchStage2 *stage2 = new CallAfterCategoryFetchStage2(mCallable); + LLInventoryFetchObserver::item_ref_t ids; + for(S32 i = 0; i < count; ++i) + { + ids.push_back(item_array.get(i)->getUUID()); + } + + gInventory.removeObserver(this); + + // do the fetch + stage2->fetchItems(ids); + if(stage2->isEverythingComplete()) + { + // everything is already here - call done. + stage2->done(); + } + else + { + // it's all on it's way - add an observer, and the inventory + // will call done for us when everything is here. + gInventory.addObserver(stage2); + } + delete this; + } +protected: + T mCallable; +}; + +template +void callAfterCategoryFetch(const LLUUID& cat_id, T callable) +{ + CallAfterCategoryFetchStage1 *stage1 = new CallAfterCategoryFetchStage1(callable); + LLInventoryFetchDescendentsObserver::folder_ref_t folders; + folders.push_back(cat_id); + stage1->fetchDescendents(folders); + if (stage1->isEverythingComplete()) + { + stage1->done(); + } + else + { + gInventory.addObserver(stage1); + } +} + #endif diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 7dd597a0df..6baaba907c 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -2530,109 +2530,6 @@ bool callback_choose_gender(const LLSD& notification, const LLSD& response) return false; } -LLViewerInventoryCategory* findDescendentCategoryByName(const LLUUID& parent_id,const std::string& name) -{ - LLInventoryModel::cat_array_t cat_array; - LLInventoryModel::item_array_t item_array; - LLNameCategoryCollector has_name(name); - gInventory.collectDescendentsIf(parent_id, - cat_array, - item_array, - LLInventoryModel::EXCLUDE_TRASH, - has_name); - if (0 == cat_array.count()) - return NULL; - else - return cat_array.get(0); -} - -class CopyAfterFetchStage2: public LLInventoryFetchObserver -{ -public: - CopyAfterFetchStage2(LLViewerInventoryCategory *cat, const LLUUID& dst_id): - mCat(cat), - mDstID(dst_id) - { - } - ~CopyAfterFetchStage2() - { - } - virtual void done() - { -// LLAppearanceManager::instance().shallowCopyCategory(cat,dst_id,NULL); - gInventory.removeObserver(this); - LLPointer cb(NULL); - LLAppearanceManager *app_mgr = &(LLAppearanceManager::instance()); - doOnIdle(boost::bind(&LLAppearanceManager::shallowCopyCategory,app_mgr,mCat->getUUID(),mDstID,cb)); - delete this; - } -protected: - LLViewerInventoryCategory *mCat; - LLUUID mDstID; -}; - -class CopyAfterFetchStage1: public LLInventoryFetchDescendentsObserver -{ -public: - CopyAfterFetchStage1(LLViewerInventoryCategory *cat, const LLUUID& dst_id): - mCat(cat), - mDstID(dst_id) - { - } - ~CopyAfterFetchStage1() - { - } - virtual void done() - { - // What we do here is get the complete information on the items in - // the library, and set up an observer that will wait for that to - // happen. - LLInventoryModel::cat_array_t cat_array; - LLInventoryModel::item_array_t item_array; - gInventory.collectDescendents(mCompleteFolders.front(), - cat_array, - item_array, - LLInventoryModel::EXCLUDE_TRASH); - S32 count = item_array.count(); - if(!count) - { - llwarns << "Nothing fetched in category " << mCompleteFolders.front() - << llendl; - //dec_busy_count(); - gInventory.removeObserver(this); - delete this; - return; - } - - CopyAfterFetchStage2 *stage2 = new CopyAfterFetchStage2(mCat,mDstID); - LLInventoryFetchObserver::item_ref_t ids; - for(S32 i = 0; i < count; ++i) - { - ids.push_back(item_array.get(i)->getUUID()); - } - - gInventory.removeObserver(this); - - // do the fetch - stage2->fetchItems(ids); - if(stage2->isEverythingComplete()) - { - // everything is already here - call done. - stage2->done(); - } - else - { - // it's all on it's way - add an observer, and the inventory - // will call done for us when everything is here. - gInventory.addObserver(stage2); - } - delete this; - } -protected: - LLViewerInventoryCategory *mCat; - LLUUID mDstID; -}; - void LLStartUp::loadInitialOutfit( const std::string& outfit_folder_name, const std::string& gender_name ) { @@ -2656,10 +2553,10 @@ void LLStartUp::loadInitialOutfit( const std::string& outfit_folder_name, // try to find the outfit - if not there, create some default // wearables. - LLViewerInventoryCategory *cat = findDescendentCategoryByName( + LLUUID cat_id = findDescendentCategoryIDByName( gInventory.getLibraryRootFolderID(), outfit_folder_name); - if (!cat) + if (cat_id.isNull()) { gAgentWearables.createStandardWearables(gender); } @@ -2667,48 +2564,42 @@ void LLStartUp::loadInitialOutfit( const std::string& outfit_folder_name, { bool do_copy = true; bool do_append = false; + LLViewerInventoryCategory *cat = gInventory.getCategory(cat_id); LLAppearanceManager::instance().wearInventoryCategory(cat, do_copy, do_append); } - // Copy gender-specific gestures. - LLViewerInventoryCategory *gestures_cat = findDescendentCategoryByName( + // Copy gestures + LLUUID dst_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_GESTURE); + LLPointer cb(NULL); + LLAppearanceManager *app_mgr = &(LLAppearanceManager::instance()); + + // - Copy gender-specific gestures. + LLUUID gestures_cat_id = findDescendentCategoryIDByName( gInventory.getLibraryRootFolderID(), gestures); - if (gestures_cat) + if (gestures_cat_id.notNull()) { - CopyAfterFetchStage1 *stage1 = new CopyAfterFetchStage1( - gestures_cat, gInventory.findCategoryUUIDForType(LLFolderType::FT_GESTURE)); - LLInventoryFetchDescendentsObserver::folder_ref_t folders; - folders.push_back(gestures_cat->getUUID()); - stage1->fetchDescendents(folders); - if (stage1->isEverythingComplete()) - { - stage1->done(); - } - else - { - gInventory.addObserver(stage1); - } - -// LLAppearanceManager::instance().shallowCopyCategory( -// gestures_cat->getUUID(), -// gInventory.findCategoryUUIDForType(LLFolderType::FT_GESTURE), -// NULL); + callAfterCategoryFetch(gestures_cat_id, + boost::bind(&LLAppearanceManager::shallowCopyCategory, + app_mgr, + gestures_cat_id, + dst_id, + cb)); } - // Copy common gestures. -#if 0 - LLViewerInventoryCategory *common_gestures_cat = findDescendentCategoryByName( + // - Copy common gestures. + LLUUID common_gestures_cat_id = findDescendentCategoryIDByName( gInventory.getLibraryRootFolderID(), COMMON_GESTURES_FOLDER); - if (common_gestures_cat) + if (common_gestures_cat_id.notNull()) { - LLAppearanceManager::instance().shallowCopyCategory( - common_gestures_cat->getUUID(), - gInventory.findCategoryUUIDForType(LLFolderType::FT_GESTURE), - NULL); + callAfterCategoryFetch(common_gestures_cat_id, + boost::bind(&LLAppearanceManager::shallowCopyCategory, + app_mgr, + common_gestures_cat_id, + dst_id, + cb)); } -#endif // This is really misnamed -- it means we have started loading // an outfit/shape that will give the avatar a gender eventually. JC diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index bafdd9474e..4235f97eab 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -1869,8 +1869,7 @@ void LLVOAvatar::releaseMeshData() // virtual void LLVOAvatar::restoreMeshData() { - // BAP restore - //llassert(!isSelf()); + llassert(!isSelf()); LLMemType mt(LLMemType::MTYPE_AVATAR); //llinfos << "Restoring" << llendl; -- cgit v1.2.3