summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
authorBrad Payne (Vir Linden) <vir@lindenlab.com>2009-11-17 10:33:47 -0500
committerBrad Payne (Vir Linden) <vir@lindenlab.com>2009-11-17 10:33:47 -0500
commit9c823a1d40392dc00bdfb1f09220a5065d764f40 (patch)
tree5c82a05913786b0401f30a94b40d9c1e4a44bd51 /indra/newview
parent6f52f1e502cf030ceb4e14963fdda1021ea33023 (diff)
Deferring work to idle time to avoid recursive notifyObservers calls - added wrapper class to defer an arbitrary boost::bind or other callable
--HG-- branch : avatar-pipeline
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/llagentwearables.cpp18
-rw-r--r--indra/newview/llappearancemgr.cpp18
-rw-r--r--indra/newview/llappearancemgr.h33
-rw-r--r--indra/newview/llinventorybridge.cpp12
4 files changed, 68 insertions, 13 deletions
diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp
index 17e7eea2f1..a171f75b17 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 @@ public:
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 80ac9e4085..a23d21f84b 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -95,8 +95,9 @@ public:
mCopyItems(copy_items),
mAppend(append)
{}
- ~LLOutfitObserver() {}
- virtual void done(); //public
+ ~LLOutfitObserver();
+ virtual void done();
+ void doWearCategory();
protected:
LLUUID mCatID;
@@ -104,8 +105,20 @@ protected:
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.
if(mCopyItems)
@@ -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 88d3320d1f..f39fbd7b1a 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 @@ private:
#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 d7be09efa9..f406547620 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -1682,6 +1682,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)
@@ -1700,6 +1711,7 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
cb);
}
#endif
+ }
}
else
{