diff options
Diffstat (limited to 'indra/newview/llgesturemgr.cpp')
-rw-r--r-- | indra/newview/llgesturemgr.cpp | 236 |
1 files changed, 165 insertions, 71 deletions
diff --git a/indra/newview/llgesturemgr.cpp b/indra/newview/llgesturemgr.cpp index 59274c8638..fbacbd704f 100644 --- a/indra/newview/llgesturemgr.cpp +++ b/indra/newview/llgesturemgr.cpp @@ -37,12 +37,12 @@ // system #include <functional> #include <algorithm> -#include <boost/tokenizer.hpp> // library #include "lldatapacker.h" #include "llinventory.h" #include "llmultigesture.h" +#include "llnotificationsutil.h" #include "llstl.h" #include "llstring.h" // todo: remove #include "llvfile.h" @@ -52,30 +52,34 @@ #include "llagent.h" #include "lldelayedgestureerror.h" #include "llinventorymodel.h" -#include "llnotify.h" #include "llviewermessage.h" #include "llvoavatarself.h" #include "llviewerstats.h" #include "llnearbychatbar.h" +#include "llappearancemgr.h" // Longest time, in seconds, to wait for all animations to stop playing const F32 MAX_WAIT_ANIM_SECS = 30.f; +// If this gesture is a link, get the base gesture that this link points to, +// otherwise just return this id. +static const LLUUID& get_linked_uuid(const LLUUID& item_id); // Lightweight constructor. // init() does the heavy lifting. -LLGestureManager::LLGestureManager() +LLGestureMgr::LLGestureMgr() : mValid(FALSE), mPlaying(), mActive(), mLoadingCount(0) { + mRetryIfMissing = true; gInventory.addObserver(this); } // We own the data for gestures, so clean them up. -LLGestureManager::~LLGestureManager() +LLGestureMgr::~LLGestureMgr() { item_map_t::iterator it; for (it = mActive.begin(); it != mActive.end(); ++it) @@ -89,15 +93,50 @@ LLGestureManager::~LLGestureManager() } -void LLGestureManager::init() +void LLGestureMgr::init() { // TODO } +void LLGestureMgr::changed(U32 mask) +{ + LLInventoryFetchObserver::changed(mask); + + if (mask & LLInventoryObserver::GESTURE) + { + // If there was a gesture label changed, update all the names in the + // active gestures and then notify observers + if (mask & LLInventoryObserver::LABEL) + { + for(item_map_t::iterator it = mActive.begin(); it != mActive.end(); ++it) + { + if(it->second) + { + LLViewerInventoryItem* item = gInventory.getItem(it->first); + if(item) + { + it->second->mName = item->getName(); + } + } + } + notifyObservers(); + } + // If there was a gesture added or removed notify observers + // STRUCTURE denotes that the inventory item has been moved + // In the case of deleting gesture, it is moved to the trash + else if(mask & LLInventoryObserver::ADD || + mask & LLInventoryObserver::REMOVE || + mask & LLInventoryObserver::STRUCTURE) + { + notifyObservers(); + } + } +} + // Use this version when you have the item_id but not the asset_id, // and you KNOW the inventory is loaded. -void LLGestureManager::activateGesture(const LLUUID& item_id) +void LLGestureMgr::activateGesture(const LLUUID& item_id) { LLViewerInventoryItem* item = gInventory.getItem(item_id); if (!item) return; @@ -113,7 +152,7 @@ void LLGestureManager::activateGesture(const LLUUID& item_id) } -void LLGestureManager::activateGestures(LLViewerInventoryItem::item_array_t& items) +void LLGestureMgr::activateGestures(LLViewerInventoryItem::item_array_t& items) { // Load up the assets S32 count = 0; @@ -206,14 +245,19 @@ struct LLLoadInfo // If inform_server is true, will send a message upstream to update // the user_gesture_active table. -void LLGestureManager::activateGestureWithAsset(const LLUUID& item_id, +/** + * It will load a gesture from remote storage + */ +void LLGestureMgr::activateGestureWithAsset(const LLUUID& item_id, const LLUUID& asset_id, BOOL inform_server, BOOL deactivate_similar) { + const LLUUID& base_item_id = get_linked_uuid(item_id); + if( !gAssetStorage ) { - llwarns << "LLGestureManager::activateGestureWithAsset without valid gAssetStorage" << llendl; + llwarns << "LLGestureMgr::activateGestureWithAsset without valid gAssetStorage" << llendl; return; } // If gesture is already active, nothing to do. @@ -231,13 +275,13 @@ void LLGestureManager::activateGestureWithAsset(const LLUUID& item_id, // For now, put NULL into the item map. We'll build a gesture // class object when the asset data arrives. - mActive[item_id] = NULL; + mActive[base_item_id] = NULL; // Copy the UUID if (asset_id.notNull()) { LLLoadInfo* info = new LLLoadInfo; - info->mItemID = item_id; + info->mItemID = base_item_id; info->mInformServer = inform_server; info->mDeactivateSimilar = deactivate_similar; @@ -255,9 +299,10 @@ void LLGestureManager::activateGestureWithAsset(const LLUUID& item_id, } -void LLGestureManager::deactivateGesture(const LLUUID& item_id) +void LLGestureMgr::deactivateGesture(const LLUUID& item_id) { - item_map_t::iterator it = mActive.find(item_id); + const LLUUID& base_item_id = get_linked_uuid(item_id); + item_map_t::iterator it = mActive.find(base_item_id); if (it == mActive.end()) { llwarns << "deactivateGesture for inactive gesture " << item_id << llendl; @@ -277,7 +322,7 @@ void LLGestureManager::deactivateGesture(const LLUUID& item_id) } mActive.erase(it); - gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id); + gInventory.addChangedMask(LLInventoryObserver::LABEL, base_item_id); // Inform the database of this change LLMessageSystem* msg = gMessageSystem; @@ -293,13 +338,16 @@ void LLGestureManager::deactivateGesture(const LLUUID& item_id) gAgent.sendReliableMessage(); + LLAppearanceMgr::instance().removeCOFItemLinks(base_item_id, false); + notifyObservers(); } -void LLGestureManager::deactivateSimilarGestures(LLMultiGesture* in, const LLUUID& in_item_id) +void LLGestureMgr::deactivateSimilarGestures(LLMultiGesture* in, const LLUUID& in_item_id) { - std::vector<LLUUID> gest_item_ids; + const LLUUID& base_in_item_id = get_linked_uuid(in_item_id); + uuid_vec_t gest_item_ids; // Deactivate all gestures that match item_map_t::iterator it; @@ -310,7 +358,7 @@ void LLGestureManager::deactivateSimilarGestures(LLMultiGesture* in, const LLUUI // Don't deactivate the gesture we are looking for duplicates of // (for replaceGesture) - if (!gest || item_id == in_item_id) + if (!gest || item_id == base_in_item_id) { // legal, can have null pointers in list ++it; @@ -338,7 +386,7 @@ void LLGestureManager::deactivateSimilarGestures(LLMultiGesture* in, const LLUUI // Inform database of the change LLMessageSystem* msg = gMessageSystem; BOOL start_message = TRUE; - std::vector<LLUUID>::const_iterator vit = gest_item_ids.begin(); + uuid_vec_t::const_iterator vit = gest_item_ids.begin(); while (vit != gest_item_ids.end()) { if (start_message) @@ -383,16 +431,19 @@ void LLGestureManager::deactivateSimilarGestures(LLMultiGesture* in, const LLUUI } -BOOL LLGestureManager::isGestureActive(const LLUUID& item_id) +BOOL LLGestureMgr::isGestureActive(const LLUUID& item_id) { - item_map_t::iterator it = mActive.find(item_id); + const LLUUID& base_item_id = get_linked_uuid(item_id); + item_map_t::iterator it = mActive.find(base_item_id); return (it != mActive.end()); } -BOOL LLGestureManager::isGesturePlaying(const LLUUID& item_id) +BOOL LLGestureMgr::isGesturePlaying(const LLUUID& item_id) { - item_map_t::iterator it = mActive.find(item_id); + const LLUUID& base_item_id = get_linked_uuid(item_id); + + item_map_t::iterator it = mActive.find(base_item_id); if (it == mActive.end()) return FALSE; LLMultiGesture* gesture = (*it).second; @@ -401,21 +452,33 @@ BOOL LLGestureManager::isGesturePlaying(const LLUUID& item_id) return gesture->mPlaying; } -void LLGestureManager::replaceGesture(const LLUUID& item_id, LLMultiGesture* new_gesture, const LLUUID& asset_id) +BOOL LLGestureMgr::isGesturePlaying(LLMultiGesture* gesture) +{ + if(!gesture) + { + return FALSE; + } + + return gesture->mPlaying; +} + +void LLGestureMgr::replaceGesture(const LLUUID& item_id, LLMultiGesture* new_gesture, const LLUUID& asset_id) { - item_map_t::iterator it = mActive.find(item_id); + const LLUUID& base_item_id = get_linked_uuid(item_id); + + item_map_t::iterator it = mActive.find(base_item_id); if (it == mActive.end()) { - llwarns << "replaceGesture for inactive gesture " << item_id << llendl; + llwarns << "replaceGesture for inactive gesture " << base_item_id << llendl; return; } LLMultiGesture* old_gesture = (*it).second; stopGesture(old_gesture); - mActive.erase(item_id); + mActive.erase(base_item_id); - mActive[item_id] = new_gesture; + mActive[base_item_id] = new_gesture; delete old_gesture; old_gesture = NULL; @@ -426,7 +489,7 @@ void LLGestureManager::replaceGesture(const LLUUID& item_id, LLMultiGesture* new mDeactivateSimilarNames.clear(); LLLoadInfo* info = new LLLoadInfo; - info->mItemID = item_id; + info->mItemID = base_item_id; info->mInformServer = TRUE; info->mDeactivateSimilar = FALSE; @@ -441,21 +504,23 @@ void LLGestureManager::replaceGesture(const LLUUID& item_id, LLMultiGesture* new notifyObservers(); } -void LLGestureManager::replaceGesture(const LLUUID& item_id, const LLUUID& new_asset_id) +void LLGestureMgr::replaceGesture(const LLUUID& item_id, const LLUUID& new_asset_id) { - item_map_t::iterator it = LLGestureManager::instance().mActive.find(item_id); + const LLUUID& base_item_id = get_linked_uuid(item_id); + + item_map_t::iterator it = LLGestureMgr::instance().mActive.find(base_item_id); if (it == mActive.end()) { - llwarns << "replaceGesture for inactive gesture " << item_id << llendl; + llwarns << "replaceGesture for inactive gesture " << base_item_id << llendl; return; } // mActive owns this gesture pointer, so clean up memory. LLMultiGesture* gesture = (*it).second; - LLGestureManager::instance().replaceGesture(item_id, gesture, new_asset_id); + LLGestureMgr::instance().replaceGesture(base_item_id, gesture, new_asset_id); } -void LLGestureManager::playGesture(LLMultiGesture* gesture) +void LLGestureMgr::playGesture(LLMultiGesture* gesture) { if (!gesture) return; @@ -474,9 +539,11 @@ void LLGestureManager::playGesture(LLMultiGesture* gesture) // Convenience function that looks up the item_id for you. -void LLGestureManager::playGesture(const LLUUID& item_id) +void LLGestureMgr::playGesture(const LLUUID& item_id) { - item_map_t::iterator it = mActive.find(item_id); + const LLUUID& base_item_id = get_linked_uuid(item_id); + + item_map_t::iterator it = mActive.find(base_item_id); if (it == mActive.end()) return; LLMultiGesture* gesture = (*it).second; @@ -489,7 +556,7 @@ void LLGestureManager::playGesture(const LLUUID& item_id) // Iterates through space delimited tokens in string, triggering any gestures found. // Generates a revised string that has the found tokens replaced by their replacement strings // and (as a minor side effect) has multiple spaces in a row replaced by single spaces. -BOOL LLGestureManager::triggerAndReviseString(const std::string &utf8str, std::string* revised_string) +BOOL LLGestureMgr::triggerAndReviseString(const std::string &utf8str, std::string* revised_string) { std::string tokenized = utf8str; @@ -582,7 +649,7 @@ BOOL LLGestureManager::triggerAndReviseString(const std::string &utf8str, std::s } -BOOL LLGestureManager::triggerGesture(KEY key, MASK mask) +BOOL LLGestureMgr::triggerGesture(KEY key, MASK mask) { std::vector <LLMultiGesture *> matching; item_map_t::iterator it; @@ -616,7 +683,7 @@ BOOL LLGestureManager::triggerGesture(KEY key, MASK mask) } -S32 LLGestureManager::getPlayingCount() const +S32 LLGestureMgr::getPlayingCount() const { return mPlaying.size(); } @@ -630,7 +697,7 @@ struct IsGesturePlaying : public std::unary_function<LLMultiGesture*, bool> } }; -void LLGestureManager::update() +void LLGestureMgr::update() { S32 i; for (i = 0; i < (S32)mPlaying.size(); ++i) @@ -673,14 +740,13 @@ void LLGestureManager::update() // Run all steps until you're either done or hit a wait. -void LLGestureManager::stepGesture(LLMultiGesture* gesture) +void LLGestureMgr::stepGesture(LLMultiGesture* gesture) { if (!gesture) { return; } - LLVOAvatar* avatar = gAgent.getAvatarObject(); - if (!avatar) return; + if (!isAgentAvatarValid()) return; // Of the ones that started playing, have any stopped? @@ -691,8 +757,8 @@ void LLGestureManager::stepGesture(LLMultiGesture* gesture) { // look in signaled animations (simulator's view of what is // currently playing. - LLVOAvatar::AnimIterator play_it = avatar->mSignaledAnimations.find(*gest_it); - if (play_it != avatar->mSignaledAnimations.end()) + LLVOAvatar::AnimIterator play_it = gAgentAvatarp->mSignaledAnimations.find(*gest_it); + if (play_it != gAgentAvatarp->mSignaledAnimations.end()) { ++gest_it; } @@ -710,8 +776,8 @@ void LLGestureManager::stepGesture(LLMultiGesture* gesture) gest_it != gesture->mRequestedAnimIDs.end(); ) { - LLVOAvatar::AnimIterator play_it = avatar->mSignaledAnimations.find(*gest_it); - if (play_it != avatar->mSignaledAnimations.end()) + LLVOAvatar::AnimIterator play_it = gAgentAvatarp->mSignaledAnimations.find(*gest_it); + if (play_it != gAgentAvatarp->mSignaledAnimations.end()) { // Hooray, this animation has started playing! // Copy into playing. @@ -821,7 +887,7 @@ void LLGestureManager::stepGesture(LLMultiGesture* gesture) } -void LLGestureManager::runStep(LLMultiGesture* gesture, LLGestureStep* step) +void LLGestureMgr::runStep(LLMultiGesture* gesture, LLGestureStep* step) { switch(step->getType()) { @@ -908,7 +974,7 @@ void LLGestureManager::runStep(LLMultiGesture* gesture, LLGestureStep* step) // static -void LLGestureManager::onLoadComplete(LLVFS *vfs, +void LLGestureMgr::onLoadComplete(LLVFS *vfs, const LLUUID& asset_uuid, LLAssetType::EType type, void* user_data, S32 status, LLExtStat ext_status) @@ -921,8 +987,8 @@ void LLGestureManager::onLoadComplete(LLVFS *vfs, delete info; info = NULL; - - LLGestureManager::instance().mLoadingCount--; + LLGestureMgr& self = LLGestureMgr::instance(); + self.mLoadingCount--; if (0 == status) { @@ -944,16 +1010,16 @@ void LLGestureManager::onLoadComplete(LLVFS *vfs, { if (deactivate_similar) { - LLGestureManager::instance().deactivateSimilarGestures(gesture, item_id); + self.deactivateSimilarGestures(gesture, item_id); // Display deactivation message if this was the last of the bunch. - if (LLGestureManager::instance().mLoadingCount == 0 - && LLGestureManager::instance().mDeactivateSimilarNames.length() > 0) + if (self.mLoadingCount == 0 + && self.mDeactivateSimilarNames.length() > 0) { // we're done with this set of deactivations LLSD args; - args["NAMES"] = LLGestureManager::instance().mDeactivateSimilarNames; - LLNotifications::instance().add("DeactivatedGesturesTrigger", args); + args["NAMES"] = self.mDeactivateSimilarNames; + LLNotificationsUtil::add("DeactivatedGesturesTrigger", args); } } @@ -965,9 +1031,11 @@ void LLGestureManager::onLoadComplete(LLVFS *vfs, else { // Watch this item and set gesture name when item exists in inventory - LLGestureManager::instance().watchItem(item_id); + item_ref_t ids; + ids.push_back(item_id); + self.fetchItems(ids); } - LLGestureManager::instance().mActive[item_id] = gesture; + self.mActive[item_id] = gesture; // Everything has been successful. Add to the active list. gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id); @@ -989,14 +1057,21 @@ void LLGestureManager::onLoadComplete(LLVFS *vfs, gAgent.sendReliableMessage(); } + callback_map_t::iterator i_cb = self.mCallbackMap.find(item_id); + + if(i_cb != self.mCallbackMap.end()) + { + i_cb->second(gesture); + self.mCallbackMap.erase(i_cb); + } - LLGestureManager::instance().notifyObservers(); + self.notifyObservers(); } else { llwarns << "Unable to load gesture" << llendl; - LLGestureManager::instance().mActive.erase(item_id); + self.mActive.erase(item_id); delete gesture; gesture = NULL; @@ -1018,12 +1093,12 @@ void LLGestureManager::onLoadComplete(LLVFS *vfs, llwarns << "Problem loading gesture: " << status << llendl; - LLGestureManager::instance().mActive.erase(item_id); + LLGestureMgr::instance().mActive.erase(item_id); } } -void LLGestureManager::stopGesture(LLMultiGesture* gesture) +void LLGestureMgr::stopGesture(LLMultiGesture* gesture) { if (!gesture) return; @@ -1063,9 +1138,11 @@ void LLGestureManager::stopGesture(LLMultiGesture* gesture) } -void LLGestureManager::stopGesture(const LLUUID& item_id) +void LLGestureMgr::stopGesture(const LLUUID& item_id) { - item_map_t::iterator it = mActive.find(item_id); + const LLUUID& base_item_id = get_linked_uuid(item_id); + + item_map_t::iterator it = mActive.find(base_item_id); if (it == mActive.end()) return; LLMultiGesture* gesture = (*it).second; @@ -1075,12 +1152,12 @@ void LLGestureManager::stopGesture(const LLUUID& item_id) } -void LLGestureManager::addObserver(LLGestureManagerObserver* observer) +void LLGestureMgr::addObserver(LLGestureManagerObserver* observer) { mObservers.push_back(observer); } -void LLGestureManager::removeObserver(LLGestureManagerObserver* observer) +void LLGestureMgr::removeObserver(LLGestureManagerObserver* observer) { std::vector<LLGestureManagerObserver*>::iterator it; it = std::find(mObservers.begin(), mObservers.end(), observer); @@ -1093,9 +1170,9 @@ void LLGestureManager::removeObserver(LLGestureManagerObserver* observer) // Call this method when it's time to update everyone on a new state. // Copy the list because an observer could respond by removing itself // from the list. -void LLGestureManager::notifyObservers() +void LLGestureMgr::notifyObservers() { - lldebugs << "LLGestureManager::notifyObservers" << llendl; + lldebugs << "LLGestureMgr::notifyObservers" << llendl; std::vector<LLGestureManagerObserver*> observers = mObservers; @@ -1107,7 +1184,7 @@ void LLGestureManager::notifyObservers() } } -BOOL LLGestureManager::matchPrefix(const std::string& in_str, std::string* out_str) +BOOL LLGestureMgr::matchPrefix(const std::string& in_str, std::string* out_str) { S32 in_len = in_str.length(); @@ -1138,7 +1215,7 @@ BOOL LLGestureManager::matchPrefix(const std::string& in_str, std::string* out_s } -void LLGestureManager::getItemIDs(std::vector<LLUUID>* ids) +void LLGestureMgr::getItemIDs(uuid_vec_t* ids) { item_map_t::const_iterator it; for (it = mActive.begin(); it != mActive.end(); ++it) @@ -1147,8 +1224,9 @@ void LLGestureManager::getItemIDs(std::vector<LLUUID>* ids) } } -void LLGestureManager::done() +void LLGestureMgr::done() { + bool notify = false; for(item_map_t::iterator it = mActive.begin(); it != mActive.end(); ++it) { if(it->second && it->second->mName.empty()) @@ -1157,8 +1235,24 @@ void LLGestureManager::done() if(item) { it->second->mName = item->getName(); + notify = true; } } } - notifyObservers(); + if(notify) + { + notifyObservers(); + } } + +// static +const LLUUID& get_linked_uuid(const LLUUID &item_id) +{ + LLViewerInventoryItem* item = gInventory.getItem(item_id); + if (item && item->getIsLinkType()) + { + return item->getLinkedUUID(); + } + return item_id; +} + |