diff options
-rw-r--r-- | indra/newview/llappearancemgr.cpp | 179 | ||||
-rw-r--r-- | indra/newview/llappearancemgr.h | 181 | ||||
-rw-r--r-- | indra/newview/llwearableitemslist.cpp | 4 |
3 files changed, 187 insertions, 177 deletions
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 5e0d49ac12..c04c2e271f 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -1801,9 +1801,9 @@ void LLAppearanceMgr::wearInventoryCategory(LLInventoryCategory* category, bool llinfos << "wearInventoryCategory( " << category->getName() << " )" << llendl; - callAfterCategoryFetch(category->getUUID(),boost::bind(&LLAppearanceMgr::wearCategoryFinal, - &LLAppearanceMgr::instance(), - category->getUUID(), copy, append)); + callAfterCategoryFetch(category->getUUID(), boost::bind(&LLAppearanceMgr::wearCategoryFinal, + &LLAppearanceMgr::instance(), + category->getUUID(), copy, append)); } void LLAppearanceMgr::wearCategoryFinal(LLUUID& cat_id, bool copy_items, bool append) @@ -2727,6 +2727,179 @@ BOOL LLAppearanceMgr::getIsProtectedCOFItem(const LLUUID& obj_id) const */ } +// Shim class to allow arbitrary boost::bind +// expressions to be run as one-time idle callbacks. +// +// TODO: rework idle function spec to take a boost::function in the first place. +class OnIdleCallbackOneTime +{ +public: + OnIdleCallbackOneTime(nullary_func_t callable): + mCallable(callable) + { + } + static void onIdle(void *data) + { + gIdleCallbacks.deleteFunction(onIdle, data); + OnIdleCallbackOneTime* self = reinterpret_cast<OnIdleCallbackOneTime*>(data); + self->call(); + delete self; + } + void call() + { + mCallable(); + } +private: + nullary_func_t mCallable; +}; + +void doOnIdleOneTime(nullary_func_t callable) +{ + OnIdleCallbackOneTime* cb_functor = new OnIdleCallbackOneTime(callable); + gIdleCallbacks.addFunction(&OnIdleCallbackOneTime::onIdle,cb_functor); +} + +// Shim class to allow generic boost functions to be run as +// recurring idle callbacks. Callable should return true when done, +// false to continue getting called. +// +// TODO: rework idle function spec to take a boost::function in the first place. +class OnIdleCallbackRepeating +{ +public: + OnIdleCallbackRepeating(bool_func_t callable): + mCallable(callable) + { + } + // Will keep getting called until the callable returns true. + static void onIdle(void *data) + { + OnIdleCallbackRepeating* self = reinterpret_cast<OnIdleCallbackRepeating*>(data); + bool done = self->call(); + if (done) + { + gIdleCallbacks.deleteFunction(onIdle, data); + delete self; + } + } + bool call() + { + return mCallable(); + } +private: + bool_func_t mCallable; +}; + +void doOnIdleRepeating(bool_func_t callable) +{ + OnIdleCallbackRepeating* cb_functor = new OnIdleCallbackRepeating(callable); + gIdleCallbacks.addFunction(&OnIdleCallbackRepeating::onIdle,cb_functor); +} + +class CallAfterCategoryFetchStage2: public LLInventoryFetchItemsObserver +{ +public: + CallAfterCategoryFetchStage2(const uuid_vec_t& ids, + nullary_func_t callable) : + LLInventoryFetchItemsObserver(ids), + mCallable(callable) + { + } + ~CallAfterCategoryFetchStage2() + { + } + virtual void done() + { + llinfos << this << " done with incomplete " << mIncomplete.size() + << " complete " << mComplete.size() << " calling callable" << llendl; + + gInventory.removeObserver(this); + doOnIdleOneTime(mCallable); + delete this; + } +protected: + nullary_func_t mCallable; +}; + +class CallAfterCategoryFetchStage1: public LLInventoryFetchDescendentsObserver +{ +public: + CallAfterCategoryFetchStage1(const LLUUID& cat_id, nullary_func_t callable) : + LLInventoryFetchDescendentsObserver(cat_id), + 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(mComplete.front(), + cat_array, + item_array, + LLInventoryModel::EXCLUDE_TRASH); + S32 count = item_array.count(); + if(!count) + { + llwarns << "Nothing fetched in category " << mComplete.front() + << llendl; + //dec_busy_count(); + gInventory.removeObserver(this); + + // lets notify observers that loading is finished. + gAgentWearables.notifyLoadingFinished(); + delete this; + return; + } + + llinfos << "stage1 got " << item_array.count() << " items, passing to stage2 " << llendl; + uuid_vec_t ids; + for(S32 i = 0; i < count; ++i) + { + ids.push_back(item_array.get(i)->getUUID()); + } + + gInventory.removeObserver(this); + + // do the fetch + CallAfterCategoryFetchStage2 *stage2 = new CallAfterCategoryFetchStage2(ids, mCallable); + stage2->startFetch(); + if(stage2->isFinished()) + { + // 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: + nullary_func_t mCallable; +}; + +void callAfterCategoryFetch(const LLUUID& cat_id, nullary_func_t cb) +{ + CallAfterCategoryFetchStage1 *stage1 = new CallAfterCategoryFetchStage1(cat_id, cb); + stage1->startFetch(); + if (stage1->isFinished()) + { + stage1->done(); + } + else + { + gInventory.addObserver(stage1); + } +} + void wear_multiple(const uuid_vec_t& ids, bool replace) { LLPointer<LLInventoryCallback> cb = new LLUpdateAppearanceOnDestroy; diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h index a6cd129306..ca57d62446 100644 --- a/indra/newview/llappearancemgr.h +++ b/indra/newview/llappearancemgr.h @@ -242,182 +242,19 @@ private: 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 <typename T> -class OnIdleCallbackOneTime -{ -public: - OnIdleCallbackOneTime(T callable): - mCallable(callable) - { - } - static void onIdle(void *data) - { - gIdleCallbacks.deleteFunction(onIdle, data); - OnIdleCallbackOneTime<T>* self = reinterpret_cast<OnIdleCallbackOneTime<T>*>(data); - self->call(); - delete self; - } - void call() - { - mCallable(); - } -private: - T mCallable; -}; +typedef boost::function<void ()> nullary_func_t; +typedef boost::function<bool ()> bool_func_t; -template <typename T> -void doOnIdleOneTime(T callable) -{ - OnIdleCallbackOneTime<T>* cb_functor = new OnIdleCallbackOneTime<T>(callable); - gIdleCallbacks.addFunction(&OnIdleCallbackOneTime<T>::onIdle,cb_functor); -} - -// Shim class and template function to allow arbitrary boost::bind -// expressions to be run as recurring idle callbacks. -// Callable should return true when done, false to continue getting called. -template <typename T> -class OnIdleCallbackRepeating -{ -public: - OnIdleCallbackRepeating(T callable): - mCallable(callable) - { - } - // Will keep getting called until the callable returns true. - static void onIdle(void *data) - { - OnIdleCallbackRepeating<T>* self = reinterpret_cast<OnIdleCallbackRepeating<T>*>(data); - bool done = self->call(); - if (done) - { - gIdleCallbacks.deleteFunction(onIdle, data); - delete self; - } - } - bool call() - { - return mCallable(); - } -private: - T mCallable; -}; +// Call a given callable once in idle loop. +void doOnIdleOneTime(nullary_func_t callable); -template <typename T> -void doOnIdleRepeating(T callable) -{ - OnIdleCallbackRepeating<T>* cb_functor = new OnIdleCallbackRepeating<T>(callable); - gIdleCallbacks.addFunction(&OnIdleCallbackRepeating<T>::onIdle,cb_functor); -} +// Repeatedly call a callable in idle loop until it returns true. +void doOnIdleRepeating(bool_func_t callable); -template <class T> -class CallAfterCategoryFetchStage2: public LLInventoryFetchItemsObserver -{ -public: - CallAfterCategoryFetchStage2(const uuid_vec_t& ids, - T callable) : - LLInventoryFetchItemsObserver(ids), - mCallable(callable) - { - } - ~CallAfterCategoryFetchStage2() - { - } - virtual void done() - { - llinfos << this << " done with incomplete " << mIncomplete.size() - << " complete " << mComplete.size() << " calling callable" << llendl; - - gInventory.removeObserver(this); - doOnIdleOneTime(mCallable); - delete this; - } -protected: - T mCallable; -}; - -template <class T> -class CallAfterCategoryFetchStage1: public LLInventoryFetchDescendentsObserver -{ -public: - CallAfterCategoryFetchStage1(const LLUUID& cat_id, T callable) : - LLInventoryFetchDescendentsObserver(cat_id), - 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(mComplete.front(), - cat_array, - item_array, - LLInventoryModel::EXCLUDE_TRASH); - S32 count = item_array.count(); - if(!count) - { - llwarns << "Nothing fetched in category " << mComplete.front() - << llendl; - //dec_busy_count(); - gInventory.removeObserver(this); - - // lets notify observers that loading is finished. - gAgentWearables.notifyLoadingFinished(); - delete this; - return; - } - - llinfos << "stage1 got " << item_array.count() << " items, passing to stage2 " << llendl; - uuid_vec_t ids; - for(S32 i = 0; i < count; ++i) - { - ids.push_back(item_array.get(i)->getUUID()); - } - - gInventory.removeObserver(this); - - // do the fetch - CallAfterCategoryFetchStage2<T> *stage2 = new CallAfterCategoryFetchStage2<T>(ids, mCallable); - stage2->startFetch(); - if(stage2->isFinished()) - { - // 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 <class T> -void callAfterCategoryFetch(const LLUUID& cat_id, T callable) -{ - CallAfterCategoryFetchStage1<T> *stage1 = new CallAfterCategoryFetchStage1<T>(cat_id, callable); - stage1->startFetch(); - if (stage1->isFinished()) - { - stage1->done(); - } - else - { - gInventory.addObserver(stage1); - } -} +// Invoke a given callable after category contents are fully fetched. +void callAfterCategoryFetch(const LLUUID& cat_id, nullary_func_t cb); +// Wear all items in a uuid vector. void wear_multiple(const uuid_vec_t& ids, bool replace); #endif diff --git a/indra/newview/llwearableitemslist.cpp b/indra/newview/llwearableitemslist.cpp index 6a9a00f1c1..fe8c09e329 100644 --- a/indra/newview/llwearableitemslist.cpp +++ b/indra/newview/llwearableitemslist.cpp @@ -725,8 +725,8 @@ LLContextMenu* LLWearableItemsList::ContextMenu::createMenu() functor_t take_off = boost::bind(&LLAppearanceMgr::removeItemFromAvatar, LLAppearanceMgr::getInstance(), _1); // Register handlers common for all wearable types. - registrar.add("Wearable.Wear", boost::bind(wear_multiple, ids, false)); - registrar.add("Wearable.Add", boost::bind(wear_multiple, ids, true)); + registrar.add("Wearable.Wear", boost::bind(wear_multiple, ids, true)); + registrar.add("Wearable.Add", boost::bind(wear_multiple, ids, false)); registrar.add("Wearable.Edit", boost::bind(handleMultiple, LLAgentWearables::editWearable, ids)); registrar.add("Wearable.CreateNew", boost::bind(createNewWearable, selected_id)); registrar.add("Wearable.ShowOriginal", boost::bind(show_item_original, selected_id)); |