summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/newview/llagentwearables.cpp4
-rw-r--r--indra/newview/llappearancemgr.cpp22
-rw-r--r--indra/newview/llappearancemgr.h6
-rw-r--r--indra/newview/llstartup.cpp159
-rw-r--r--indra/newview/llvoavatar.cpp3
5 files changed, 178 insertions, 16 deletions
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<LLInventoryCallback> 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,9 +519,31 @@ 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<LLInventoryCallback> 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<LLInventoryCallback> cb)
+{
LLInventoryModel::cat_array_t cats;
LLInventoryModel::item_array_t items;
gInventory.collectDescendents(src_id, cats, 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<LLInventoryCallback> cb);
+ // Copy all items in a category.
+ void shallowCopyCategoryContents(const LLUUID& src_id, const LLUUID& dst_id,
+ LLPointer<LLInventoryCallback> 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<LLInventoryCallback> 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;