diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index 17e7eea2f1259e3d18c4e5b26aa40eb24016e87d..a171f75b175ed1267de6b8b8508e54746a9f7661 100644 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -62,7 +62,7 @@ class LLInitialWearablesFetch : public LLInventoryFetchDescendentsObserver { public: LLInitialWearablesFetch() {} - ~LLInitialWearablesFetch() {} + ~LLInitialWearablesFetch(); virtual void done(); struct InitialWearableData @@ -84,7 +84,6 @@ class LLInitialWearablesFetch : public LLInventoryFetchDescendentsObserver protected: void processWearablesMessage(); void processContents(); - static void onIdle(void *userdata); }; LLAgentWearables gAgentWearables; @@ -2013,6 +2012,11 @@ void LLAgentWearables::updateServer() // to avoid gInventory.notifyObservers recursion. //-------------------------------------------------------------------- +LLInitialWearablesFetch::~LLInitialWearablesFetch() +{ + llinfos << "~LLInitialWearablesFetch" << llendl; +} + // virtual void LLInitialWearablesFetch::done() { @@ -2020,15 +2024,7 @@ void LLInitialWearablesFetch::done() // 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(); + doOnIdle(boost::bind(&LLInitialWearablesFetch::processContents,this)); } void LLInitialWearablesFetch::processContents() diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 80ac9e4085b02e0b52976f7f3bce5f40af9c7af8..a23d21f84bc9479b85531c2c71a6372c83aa8fb4 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -95,8 +95,9 @@ class LLOutfitObserver : public LLInventoryFetchObserver mCopyItems(copy_items), mAppend(append) {} - ~LLOutfitObserver() {} - virtual void done(); //public + ~LLOutfitObserver(); + virtual void done(); + void doWearCategory(); protected: LLUUID mCatID; @@ -104,7 +105,19 @@ class LLOutfitObserver : public LLInventoryFetchObserver bool mAppend; }; +LLOutfitObserver::~LLOutfitObserver() +{ + llinfos << "~LLOutfitObserver" << llendl; +} + +// BAP is LLOutfitObserver getting deleted here? void LLOutfitObserver::done() +{ + gInventory.removeObserver(this); + doOnIdle(boost::bind(&LLOutfitObserver::doWearCategory,this)); +} + +void LLOutfitObserver::doWearCategory() { // We now have an outfit ready to be copied to agent inventory. Do // it, and wear that outfit normally. @@ -175,6 +188,7 @@ void LLOutfitObserver::done() // Wear the inventory category. LLAppearanceManager::instance().wearInventoryCategoryOnAvatar(gInventory.getCategory(mCatID), mAppend); } + delete this; } class LLOutfitFetch : public LLInventoryFetchDescendentsObserver diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h index 88d3320d1fa3d853f27bd4ffac169f275dee76b6..f39fbd7b1a953d24c589af8bb7252d79dbecc847 100644 --- a/indra/newview/llappearancemgr.h +++ b/indra/newview/llappearancemgr.h @@ -36,6 +36,7 @@ #include "llsingleton.h" #include "llinventorymodel.h" #include "llviewerinventory.h" +#include "llcallbacklist.h" class LLWearable; struct LLWearableHoldingPattern; @@ -111,4 +112,36 @@ class LLAppearanceManager: public LLSingleton<LLAppearanceManager> #define SUPPORT_ENSEMBLES 0 +// Shim class and template function to allow arbitrary boost::bind +// expressions to be run as one-time idle callbacks. +template <typename T> +class OnIdleCallback +{ +public: + OnIdleCallback(T callable): + mCallable(callable) + { + } + static void onIdle(void *data) + { + gIdleCallbacks.deleteFunction(onIdle, data); + OnIdleCallback<T>* self = reinterpret_cast<OnIdleCallback<T>*>(data); + self->call(); + delete self; + } + void call() + { + mCallable(); + } +private: + T mCallable; +}; + +template <typename T> +void doOnIdle(T callable) +{ + OnIdleCallback<T>* cb_functor = new OnIdleCallback<T>(callable); + gIdleCallbacks.addFunction(&OnIdleCallback<T>::onIdle,cb_functor); +} + #endif diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 2a1fdb081e514f33069d6bac2ad1323981c37ab5..aa38b19c5e9dfc1ecf58efbc80005f2abb7dc454 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -1672,6 +1672,17 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, // if target is an outfit or current outfit folder we use link if (move_is_into_current_outfit || move_is_into_outfit) { + if (inv_cat->getPreferredType() == LLFolderType::FT_NONE) + { + if (move_is_into_current_outfit) + { + // traverse category and add all contents to currently worn. + BOOL append = true; + LLAppearanceManager::instance().wearInventoryCategory(inv_cat, false, append); + } + } + else + { #if SUPPORT_ENSEMBLES // BAP - should skip if dup. if (move_is_into_current_outfit) @@ -1690,6 +1701,7 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, cb); } #endif + } } else {