diff options
Diffstat (limited to 'indra/newview/llappearancemgr.h')
-rw-r--r-- | indra/newview/llappearancemgr.h | 295 |
1 files changed, 189 insertions, 106 deletions
diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h index e7442537d2..40b8844731 100644 --- a/indra/newview/llappearancemgr.h +++ b/indra/newview/llappearancemgr.h @@ -2,25 +2,31 @@ * @file llappearancemgr.h * @brief Manager for initiating appearance changes on the viewer * - * $LicenseInfo:firstyear=2004&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. + * $LicenseInfo:firstyear=2004&license=viewergpl$ + * + * Copyright (c) 2004-2009, Linden Research, Inc. * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ */ @@ -28,27 +34,21 @@ #define LL_LLAPPEARANCEMGR_H #include "llsingleton.h" - -#include "llagentwearables.h" -#include "llcallbacklist.h" #include "llinventorymodel.h" #include "llinventoryobserver.h" #include "llviewerinventory.h" +#include "llcallbacklist.h" class LLWearable; class LLWearableHoldingPattern; class LLInventoryCallback; -class LLOutfitUnLockTimer; class LLAppearanceMgr: public LLSingleton<LLAppearanceMgr> { friend class LLSingleton<LLAppearanceMgr>; - friend class LLOutfitUnLockTimer; public: - typedef std::vector<LLInventoryModel::item_array_t> wearables_by_type_t; - - void updateAppearanceFromCOF(bool update_base_outfit_ordering = false); + void updateAppearanceFromCOF(); bool needToSaveCOF(); void updateCOF(const LLUUID& category, bool append = false); void wearInventoryCategory(LLInventoryCategory* category, bool copy, bool append); @@ -56,11 +56,6 @@ public: void wearCategoryFinal(LLUUID& cat_id, bool copy_items, bool append); void wearOutfitByName(const std::string& name); void changeOutfit(bool proceed, const LLUUID& category, bool append); - void replaceCurrentOutfit(const LLUUID& new_outfit); - void renameOutfit(const LLUUID& outfit_id); - void takeOffOutfit(const LLUUID& cat_id); - void addCategoryToCurrentOutfit(const LLUUID& cat_id); - void enforceItemCountLimits(); // Copy all items and the src category itself. void shallowCopyCategory(const LLUUID& src_id, const LLUUID& dst_id, @@ -69,18 +64,6 @@ public: // Return whether this folder contains minimal contents suitable for making a full outfit. BOOL getCanMakeFolderIntoOutfit(const LLUUID& folder_id); - // Determine whether a given outfit can be removed. - bool getCanRemoveOutfit(const LLUUID& outfit_cat_id); - - // Determine whether we're wearing any of the outfit contents (excluding body parts). - static bool getCanRemoveFromCOF(const LLUUID& outfit_cat_id); - - // Determine whether we can add anything (but body parts) from the outfit contents to COF. - static bool getCanAddToCOF(const LLUUID& outfit_cat_id); - - // Determine whether we can replace current outfit with the given one. - bool getCanReplaceCOF(const LLUUID& outfit_cat_id); - // Copy all items in a category. void shallowCopyCategoryContents(const LLUUID& src_id, const LLUUID& dst_id, LLPointer<LLInventoryCallback> cb); @@ -92,12 +75,6 @@ public: const LLViewerInventoryItem *getBaseOutfitLink(); bool getBaseOutfitName(std::string &name); - // find the UUID of the currently worn outfit (Base Outfit) - const LLUUID getBaseOutfitUUID(); - - // Wear/attach an item (from a user's inventory) on the agent - bool wearItemOnAvatar(const LLUUID& item_to_wear, bool do_update = true, bool replace = false, LLPointer<LLInventoryCallback> cb = NULL); - // Update the displayed outfit name in UI. void updatePanelOutfitName(const std::string& name); @@ -121,12 +98,11 @@ public: LLPointer<LLInventoryCallback> cb); // Add COF link to individual item. - void addCOFItemLink(const LLUUID& item_id, bool do_update = true, LLPointer<LLInventoryCallback> cb = NULL); - void addCOFItemLink(const LLInventoryItem *item, bool do_update = true, LLPointer<LLInventoryCallback> cb = NULL); + void addCOFItemLink(const LLUUID& item_id, bool do_update = true); + void addCOFItemLink(const LLInventoryItem *item, bool do_update = true); // Remove COF entries void removeCOFItemLinks(const LLUUID& item_id, bool do_update = true); - void removeCOFLinksOfType(LLWearableType::EType type, bool do_update = true); // Add COF link to ensemble folder. void addEnsembleLink(LLInventoryCategory* item, bool do_update = true); @@ -147,33 +123,6 @@ public: // Create initial outfits from library. void autopopulateOutfits(); - void wearBaseOutfit(); - - // Overrides the base outfit with the content from COF - // @return false if there is no base outfit - bool updateBaseOutfit(); - - //Remove clothing or detach an object from the agent (a bodypart cannot be removed) - void removeItemFromAvatar(const LLUUID& item_id); - - - LLUUID makeNewOutfitLinks(const std::string& new_folder_name,bool show_panel = true); - - bool moveWearable(LLViewerInventoryItem* item, bool closer_to_body); - - static void sortItemsByActualDescription(LLInventoryModel::item_array_t& items); - - //Divvy items into arrays by wearable type - static void divvyWearablesByType(const LLInventoryModel::item_array_t& items, wearables_by_type_t& items_by_type); - - //Check ordering information on wearables stored in links' descriptions and update if it is invalid - // COF is processed if cat_id is not specified - void updateClothingOrderingInfo(LLUUID cat_id = LLUUID::null, bool update_base_outfit_ordering = false); - - bool isOutfitLocked() { return mOutfitLocked; } - - bool isInUpdateAppearanceFromCOF() { return mIsInUpdateAppearanceFromCOF; } - protected: LLAppearanceMgr(); ~LLAppearanceMgr(); @@ -196,22 +145,9 @@ private: void purgeCategory(const LLUUID& category, bool keep_outfit_links); void purgeBaseOutfitLink(const LLUUID& category); - static void onOutfitRename(const LLSD& notification, const LLSD& response); - - void setOutfitLocked(bool locked); - std::set<LLUUID> mRegisteredAttachments; bool mAttachmentInvLinkEnabled; bool mOutfitIsDirty; - bool mIsInUpdateAppearanceFromCOF; // to detect recursive calls. - - /** - * Lock for blocking operations on outfit until server reply or timeout exceed - * to avoid unsynchronized outfit state or performing duplicate operations. - */ - bool mOutfitLocked; - - std::auto_ptr<LLOutfitUnLockTimer> mUnlockOutfitTimer; ////////////////////////////////////////////////////////////////////////////////// // Item-specific convenience functions @@ -220,23 +156,17 @@ public: BOOL getIsInCOF(const LLUUID& obj_id) const; // Is this in the COF and can the user delete it from the COF? BOOL getIsProtectedCOFItem(const LLUUID& obj_id) const; - - /** - * Checks if COF contains link to specified object. - */ - static bool isLinkInCOF(const LLUUID& obj_id); }; class LLUpdateAppearanceOnDestroy: public LLInventoryCallback { public: - LLUpdateAppearanceOnDestroy(bool update_base_outfit_ordering = false); + LLUpdateAppearanceOnDestroy(); virtual ~LLUpdateAppearanceOnDestroy(); /* virtual */ void fire(const LLUUID& inv_item); private: U32 mFireCount; - bool mUpdateBaseOrder; }; @@ -244,19 +174,172 @@ private: LLUUID findDescendentCategoryIDByName(const LLUUID& parent_id,const std::string& name); -typedef boost::function<void ()> nullary_func_t; -typedef boost::function<bool ()> bool_func_t; +// 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; +}; + +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 LLInventoryFetchObserver +{ +public: + CallAfterCategoryFetchStage2(T callable): + mCallable(callable) + { + } + ~CallAfterCategoryFetchStage2() + { + } + virtual void done() + { + gInventory.removeObserver(this); + doOnIdleOneTime(mCallable); + delete this; + } +protected: + T mCallable; +}; -// Invoke a given callable after category contents are fully fetched. -void callAfterCategoryFetch(const LLUUID& cat_id, nullary_func_t cb); +template <class T> +class CallAfterCategoryFetchStage1: public LLInventoryFetchDescendentsObserver +{ +public: + CallAfterCategoryFetchStage1(T callable): + 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); + delete this; + return; + } + + CallAfterCategoryFetchStage2<T> *stage2 = new CallAfterCategoryFetchStage2<T>(mCallable); + 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 + stage2->fetch(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: + T mCallable; +}; -// Wear all items in a uuid vector. -void wear_multiple(const uuid_vec_t& ids, bool replace); +template <class T> +void callAfterCategoryFetch(const LLUUID& cat_id, T callable) +{ + CallAfterCategoryFetchStage1<T> *stage1 = new CallAfterCategoryFetchStage1<T>(callable); + uuid_vec_t folders; + folders.push_back(cat_id); + stage1->fetch(folders); + if (stage1->isEverythingComplete()) + { + stage1->done(); + } + else + { + gInventory.addObserver(stage1); + } +} #endif |