summaryrefslogtreecommitdiff
path: root/indra/newview/llagentwearables.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llagentwearables.cpp')
-rw-r--r--indra/newview/llagentwearables.cpp186
1 files changed, 179 insertions, 7 deletions
diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp
index 9b4986247f..6cb96d1336 100644
--- a/indra/newview/llagentwearables.cpp
+++ b/indra/newview/llagentwearables.cpp
@@ -35,10 +35,11 @@
#include "llagent.h"
#include "llagentwearables.h"
+#include "llcallbacklist.h"
#include "llfloatercustomize.h"
#include "llfloaterinventory.h"
#include "llinventorybridge.h"
-#include "llinventorymodel.h"
+#include "llinventoryobserver.h"
#include "llinventorypanel.h"
#include "llnotify.h"
#include "llviewerregion.h"
@@ -82,6 +83,28 @@ public:
protected:
void processWearablesMessage();
+ void processContents();
+ static void onIdle(void *userdata);
+};
+
+class LLLibraryOutfitsFetch : public LLInventoryFetchDescendentsObserver
+{
+public:
+ enum ELibraryOutfitFetchStep {
+ LOFS_FOLDER = 0,
+ LOFS_OUTFITS,
+ LOFS_CONTENTS
+ };
+ LLLibraryOutfitsFetch() : mCurrFetchStep(LOFS_FOLDER), mOutfitsPopulated(false) {}
+ ~LLLibraryOutfitsFetch() {}
+ virtual void done();
+protected:
+ void folderDone(void);
+ void outfitsDone(void);
+ void contentsDone(void);
+ enum ELibraryOutfitFetchStep mCurrFetchStep;
+ std::vector< std::pair< LLUUID, std::string > > mOutfits;
+ bool mOutfitsPopulated;
};
LLAgentWearables gAgentWearables;
@@ -903,6 +926,8 @@ void LLAgentWearables::processAgentInitialWearablesUpdate(LLMessageSystem* mesgs
// will call done for us when everything is here.
gInventory.addObserver(outfit);
}
+
+ gAgentWearables.populateMyOutfitsFolder();
}
}
@@ -1261,7 +1286,7 @@ LLUUID LLAgentWearables::makeNewOutfitLinks(const std::string& new_folder_name)
LLFolderType::FT_OUTFIT,
new_folder_name);
- LLAppearanceManager::shallowCopyCategory(LLAppearanceManager::getCOF(),folder_id, NULL);
+ LLAppearanceManager::instance().shallowCopyCategory(LLAppearanceManager::instance().getCOF(),folder_id, NULL);
#if 0 // BAP - fix to go into rename state automatically after outfit is created.
LLViewerInventoryCategory *parent_category = gInventory.getCategory(parent_id);
@@ -1391,7 +1416,7 @@ void LLAgentWearables::removeWearableFinal(const EWearableType type, bool do_rem
const LLUUID &item_id = getWearableItemID(type,i);
popWearable(type,i);
gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id);
- LLAppearanceManager::removeItemLinks(item_id,false);
+ LLAppearanceManager::instance().removeItemLinks(item_id,false);
//queryWearableCache(); // moved below
if (old_wearable)
@@ -1408,7 +1433,7 @@ void LLAgentWearables::removeWearableFinal(const EWearableType type, bool do_rem
const LLUUID &item_id = getWearableItemID(type,index);
popWearable(type, index);
gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id);
- LLAppearanceManager::removeItemLinks(item_id,false);
+ LLAppearanceManager::instance().removeItemLinks(item_id,false);
//queryWearableCache(); // moved below
@@ -2002,11 +2027,158 @@ void LLAgentWearables::updateServer()
gAgent.sendAgentSetAppearance();
}
+void LLAgentWearables::populateMyOutfitsFolder(void)
+{
+ LLLibraryOutfitsFetch* outfits = new LLLibraryOutfitsFetch();
+
+ // What we do here is get the complete information on the items in
+ // the inventory, and set up an observer that will wait for that to
+ // happen.
+ LLInventoryFetchDescendentsObserver::folder_ref_t folders;
+ const LLUUID my_outfits_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS);
+
+ folders.push_back(my_outfits_id);
+ outfits->fetchDescendents(folders);
+ if(outfits->isEverythingComplete())
+ {
+ // everything is already here - call done.
+ outfits->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(outfits);
+ }
+}
+
+void LLLibraryOutfitsFetch::done()
+{
+ switch (mCurrFetchStep){
+ case LOFS_FOLDER:
+ mCurrFetchStep = LOFS_OUTFITS;
+ folderDone();
+ break;
+ case LOFS_OUTFITS:
+ mCurrFetchStep = LOFS_CONTENTS;
+ outfitsDone();
+ break;
+ case LOFS_CONTENTS:
+ // No longer need this observer hanging around.
+ gInventory.removeObserver(this);
+ contentsDone();
+ break;
+ default:
+ gInventory.removeObserver(this);
+ delete this;
+ return;
+ }
+ if (mOutfitsPopulated)
+ {
+ delete this;
+ }
+}
+
+void LLLibraryOutfitsFetch::folderDone(void)
+{
+ // Early out if we already have items in My Outfits.
+ LLInventoryModel::cat_array_t cat_array;
+ LLInventoryModel::item_array_t wearable_array;
+ gInventory.collectDescendents(mCompleteFolders.front(), cat_array, wearable_array,
+ LLInventoryModel::EXCLUDE_TRASH);
+ if (cat_array.count() > 0 || wearable_array.count() > 0)
+ {
+ mOutfitsPopulated = true;
+ gInventory.removeObserver(this);
+ return;
+ }
+
+ // Get the UUID of the library's clothing folder
+ const LLUUID library_clothing_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_CLOTHING, false, true);
+
+ mCompleteFolders.clear();
+
+ // What we do here is get the complete information on the items in
+ // the inventory, and set up an observer that will wait for that to
+ // happen.
+ LLInventoryFetchDescendentsObserver::folder_ref_t folders;
+ folders.push_back(library_clothing_id);
+ fetchDescendents(folders);
+ if(isEverythingComplete())
+ {
+ // everything is already here - call done.
+ outfitsDone();
+ }
+}
+
+void LLLibraryOutfitsFetch::outfitsDone(void)
+{
+ LLInventoryModel::cat_array_t cat_array;
+ LLInventoryModel::item_array_t wearable_array;
+ gInventory.collectDescendents(mCompleteFolders.front(), cat_array, wearable_array,
+ LLInventoryModel::EXCLUDE_TRASH);
+
+ LLInventoryFetchDescendentsObserver::folder_ref_t folders;
+ for(S32 i = 0; i < cat_array.count(); ++i)
+ {
+ if (cat_array.get(i)->getName() != "More Outfits" && cat_array.get(i)->getName() != "Ruth"){
+ folders.push_back(cat_array.get(i)->getUUID());
+ mOutfits.push_back( std::make_pair(cat_array.get(i)->getUUID(), cat_array.get(i)->getName() ));
+ }
+ }
+ mCompleteFolders.clear();
+ fetchDescendents(folders);
+ if(isEverythingComplete())
+ {
+ // everything is already here - call done.
+ contentsDone();
+ }
+}
+
+void LLLibraryOutfitsFetch::contentsDone(void)
+{
+ for(S32 i = 0; i < (S32)mOutfits.size(); ++i)
+ {
+ // First, make a folder in the My Outfits directory.
+ const LLUUID parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS);
+ LLUUID folder_id = gInventory.createNewCategory(parent_id,
+ LLFolderType::FT_OUTFIT,
+ mOutfits[i].second);
+
+ LLAppearanceManager::getInstance()->shallowCopyCategory(mOutfits[i].first, folder_id, NULL);
+ gInventory.notifyObservers();
+ }
+ mOutfitsPopulated = true;
+}
+
+//--------------------------------------------------------------------
+// InitialWearablesFetch
+//
+// This grabs contents from the COF and processes them.
+// The processing is handled in idle(), i.e. outside of done(),
+// to avoid gInventory.notifyObservers recursion.
+//--------------------------------------------------------------------
+
+// virtual
void LLInitialWearablesFetch::done()
{
- // No longer need this observer hanging around.
+ // Delay processing the actual results of this so it's not handled within
+ // gInventory.notifyObservers. The results will be handled in the next
+ // idle tick instead.
gInventory.removeObserver(this);
+ gIdleCallbacks.addFunction(onIdle, this);
+}
+
+// static
+void LLInitialWearablesFetch::onIdle(void *data)
+{
+ gIdleCallbacks.deleteFunction(onIdle, data);
+ LLInitialWearablesFetch *self = reinterpret_cast<LLInitialWearablesFetch*>(data);
+ self->processContents();
+}
+void LLInitialWearablesFetch::processContents()
+{
// Fetch the wearable items from the Current Outfit Folder
LLInventoryModel::cat_array_t cat_array;
LLInventoryModel::item_array_t wearable_array;
@@ -2014,7 +2186,7 @@ void LLInitialWearablesFetch::done()
gInventory.collectDescendentsIf(mCompleteFolders.front(), cat_array, wearable_array,
LLInventoryModel::EXCLUDE_TRASH, is_wearable);
- LLAppearanceManager::setAttachmentInvLinkEnable(true);
+ LLAppearanceManager::instance().setAttachmentInvLinkEnable(true);
if (wearable_array.count() > 0)
{
LLAppearanceManager::instance().updateAppearanceFromCOF();
@@ -2023,7 +2195,7 @@ void LLInitialWearablesFetch::done()
{
processWearablesMessage();
// Create links for attachments that may have arrived before the COF existed.
- LLAppearanceManager::linkRegisteredAttachments();
+ LLAppearanceManager::instance().linkRegisteredAttachments();
}
delete this;
}