diff options
Diffstat (limited to 'indra/newview/llgesturemgr.cpp')
-rwxr-xr-x[-rw-r--r--] | indra/newview/llgesturemgr.cpp | 265 |
1 files changed, 242 insertions, 23 deletions
diff --git a/indra/newview/llgesturemgr.cpp b/indra/newview/llgesturemgr.cpp index f658287fb1..119872ec29 100644..100755 --- a/indra/newview/llgesturemgr.cpp +++ b/indra/newview/llgesturemgr.cpp @@ -33,8 +33,11 @@ #include <algorithm> // library +#include "llaudioengine.h" #include "lldatapacker.h" +#include "llfloaterreg.h" #include "llinventory.h" +#include "llkeyframemotion.h" #include "llmultigesture.h" #include "llnotificationsutil.h" #include "llstl.h" @@ -49,8 +52,9 @@ #include "llviewermessage.h" #include "llvoavatarself.h" #include "llviewerstats.h" -#include "llnearbychatbar.h" +#include "llfloaterimnearbychat.h" #include "llappearancemgr.h" +#include "llgesturelistener.h" // Longest time, in seconds, to wait for all animations to stop playing const F32 MAX_WAIT_ANIM_SECS = 30.f; @@ -68,6 +72,7 @@ LLGestureMgr::LLGestureMgr() mLoadingCount(0) { gInventory.addObserver(this); + mListener.reset(new LLGestureListener()); } @@ -161,7 +166,7 @@ void LLGestureMgr::activateGestures(LLViewerInventoryItem::item_array_t& items) continue; } else - { // Make gesture active and persistent through login sessions. -spatters 07-12-06 + { // Make gesture active and persistent through login sessions. -Aura 07-12-06 activateGesture(item->getUUID()); } @@ -252,19 +257,19 @@ void LLGestureMgr::activateGestureWithAsset(const LLUUID& item_id, if( !gAssetStorage ) { - llwarns << "LLGestureMgr::activateGestureWithAsset without valid gAssetStorage" << llendl; + LL_WARNS() << "LLGestureMgr::activateGestureWithAsset without valid gAssetStorage" << LL_ENDL; return; } // If gesture is already active, nothing to do. if (isGestureActive(item_id)) { - llwarns << "Tried to loadGesture twice " << item_id << llendl; + LL_WARNS() << "Tried to loadGesture twice " << item_id << LL_ENDL; return; } // if (asset_id.isNull()) // { -// llwarns << "loadGesture() - gesture has no asset" << llendl; +// LL_WARNS() << "loadGesture() - gesture has no asset" << LL_ENDL; // return; // } @@ -294,13 +299,19 @@ void LLGestureMgr::activateGestureWithAsset(const LLUUID& item_id, } +void notify_update_label(const LLUUID& base_item_id) +{ + gInventory.addChangedMask(LLInventoryObserver::LABEL, base_item_id); + LLGestureMgr::instance().notifyObservers(); +} + void LLGestureMgr::deactivateGesture(const LLUUID& 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; + LL_WARNS() << "deactivateGesture for inactive gesture " << item_id << LL_ENDL; return; } @@ -317,7 +328,6 @@ void LLGestureMgr::deactivateGesture(const LLUUID& item_id) } mActive.erase(it); - gInventory.addChangedMask(LLInventoryObserver::LABEL, base_item_id); // Inform the database of this change LLMessageSystem* msg = gMessageSystem; @@ -333,9 +343,11 @@ void LLGestureMgr::deactivateGesture(const LLUUID& item_id) gAgent.sendReliableMessage(); - LLAppearanceMgr::instance().removeCOFItemLinks(base_item_id, false); + LLPointer<LLInventoryCallback> cb = + new LLBoostFuncInventoryCallback(no_op_inventory_func, + boost::bind(notify_update_label,base_item_id)); - notifyObservers(); + LLAppearanceMgr::instance().removeCOFItemLinks(base_item_id, cb); } @@ -464,7 +476,7 @@ void LLGestureMgr::replaceGesture(const LLUUID& item_id, LLMultiGesture* new_ges item_map_t::iterator it = mActive.find(base_item_id); if (it == mActive.end()) { - llwarns << "replaceGesture for inactive gesture " << base_item_id << llendl; + LL_WARNS() << "replaceGesture for inactive gesture " << base_item_id << LL_ENDL; return; } @@ -506,7 +518,7 @@ void LLGestureMgr::replaceGesture(const LLUUID& item_id, const LLUUID& new_asset item_map_t::iterator it = LLGestureMgr::instance().mActive.find(base_item_id); if (it == mActive.end()) { - llwarns << "replaceGesture for inactive gesture " << base_item_id << llendl; + LL_WARNS() << "replaceGesture for inactive gesture " << base_item_id << LL_ENDL; return; } @@ -526,6 +538,66 @@ void LLGestureMgr::playGesture(LLMultiGesture* gesture) gesture->mPlaying = TRUE; mPlaying.push_back(gesture); + // Load all needed assets to minimize the delays + // when gesture is playing. + for (std::vector<LLGestureStep*>::iterator steps_it = gesture->mSteps.begin(); + steps_it != gesture->mSteps.end(); + ++steps_it) + { + LLGestureStep* step = *steps_it; + switch(step->getType()) + { + case STEP_ANIMATION: + { + LLGestureStepAnimation* anim_step = (LLGestureStepAnimation*)step; + const LLUUID& anim_id = anim_step->mAnimAssetID; + + // Don't request the animation if this step stops it or if it is already in Static VFS + if (!(anim_id.isNull() + || anim_step->mFlags & ANIM_FLAG_STOP + || gAssetStorage->hasLocalAsset(anim_id, LLAssetType::AT_ANIMATION))) + { + mLoadingAssets.insert(anim_id); + + LLUUID* id = new LLUUID(gAgentID); + gAssetStorage->getAssetData(anim_id, + LLAssetType::AT_ANIMATION, + onAssetLoadComplete, + (void *)id, + TRUE); + } + break; + } + case STEP_SOUND: + { + LLGestureStepSound* sound_step = (LLGestureStepSound*)step; + const LLUUID& sound_id = sound_step->mSoundAssetID; + if (!(sound_id.isNull() + || gAssetStorage->hasLocalAsset(sound_id, LLAssetType::AT_SOUND))) + { + mLoadingAssets.insert(sound_id); + + gAssetStorage->getAssetData(sound_id, + LLAssetType::AT_SOUND, + onAssetLoadComplete, + NULL, + TRUE); + } + break; + } + case STEP_CHAT: + case STEP_WAIT: + case STEP_EOF: + { + break; + } + default: + { + LL_WARNS() << "Unknown gesture step type: " << step->getType() << LL_ENDL; + } + } + } + // And get it going stepGesture(gesture); @@ -741,7 +813,7 @@ void LLGestureMgr::stepGesture(LLMultiGesture* gesture) { return; } - if (!isAgentAvatarValid()) return; + if (!isAgentAvatarValid() || hasLoadingAssets(gesture)) return; // Of the ones that started playing, have any stopped? @@ -842,8 +914,8 @@ void LLGestureMgr::stepGesture(LLMultiGesture* gesture) else if (gesture->mWaitTimer.getElapsedTimeF32() > MAX_WAIT_ANIM_SECS) { // we've waited too long for an animation - llinfos << "Waited too long for animations to stop, continuing gesture." - << llendl; + LL_INFOS() << "Waited too long for animations to stop, continuing gesture." + << LL_ENDL; gesture->mWaitingAnimations = FALSE; gesture->mCurrentStep++; } @@ -933,7 +1005,8 @@ void LLGestureMgr::runStep(LLMultiGesture* gesture, LLGestureStep* step) const BOOL animate = FALSE; - LLNearbyChatBar::getInstance()->sendChatFromViewer(chat_text, CHAT_TYPE_NORMAL, animate); + (LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat"))-> + sendChatFromViewer(chat_text, CHAT_TYPE_NORMAL, animate); gesture->mCurrentStep++; break; @@ -1063,7 +1136,7 @@ void LLGestureMgr::onLoadComplete(LLVFS *vfs, } else { - llwarns << "Unable to load gesture" << llendl; + LL_WARNS() << "Unable to load gesture" << LL_ENDL; self.mActive.erase(item_id); @@ -1073,8 +1146,6 @@ void LLGestureMgr::onLoadComplete(LLVFS *vfs, } else { - LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED ); - if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status || LL_ERR_FILE_EMPTY == status) { @@ -1085,12 +1156,104 @@ void LLGestureMgr::onLoadComplete(LLVFS *vfs, LLDelayedGestureError::gestureFailedToLoad( item_id ); } - llwarns << "Problem loading gesture: " << status << llendl; + LL_WARNS() << "Problem loading gesture: " << status << LL_ENDL; LLGestureMgr::instance().mActive.erase(item_id); } } +// static +void LLGestureMgr::onAssetLoadComplete(LLVFS *vfs, + const LLUUID& asset_uuid, + LLAssetType::EType type, + void* user_data, S32 status, LLExtStat ext_status) +{ + LLGestureMgr& self = LLGestureMgr::instance(); + + // Complete the asset loading process depending on the type and + // remove the asset id from pending downloads list. + switch(type) + { + case LLAssetType::AT_ANIMATION: + { + LLKeyframeMotion::onLoadComplete(vfs, asset_uuid, type, user_data, status, ext_status); + + self.mLoadingAssets.erase(asset_uuid); + + break; + } + case LLAssetType::AT_SOUND: + { + LLAudioEngine::assetCallback(vfs, asset_uuid, type, user_data, status, ext_status); + + self.mLoadingAssets.erase(asset_uuid); + + break; + } + default: + { + LL_WARNS() << "Unexpected asset type: " << type << LL_ENDL; + + // We don't want to return from this callback without + // an animation or sound callback being fired + // and *user_data handled to avoid memory leaks. + llassert(type == LLAssetType::AT_ANIMATION || type == LLAssetType::AT_SOUND); + } + } +} + +// static +bool LLGestureMgr::hasLoadingAssets(LLMultiGesture* gesture) +{ + LLGestureMgr& self = LLGestureMgr::instance(); + + for (std::vector<LLGestureStep*>::iterator steps_it = gesture->mSteps.begin(); + steps_it != gesture->mSteps.end(); + ++steps_it) + { + LLGestureStep* step = *steps_it; + switch(step->getType()) + { + case STEP_ANIMATION: + { + LLGestureStepAnimation* anim_step = (LLGestureStepAnimation*)step; + const LLUUID& anim_id = anim_step->mAnimAssetID; + + if (!(anim_id.isNull() + || anim_step->mFlags & ANIM_FLAG_STOP + || self.mLoadingAssets.find(anim_id) == self.mLoadingAssets.end())) + { + return true; + } + break; + } + case STEP_SOUND: + { + LLGestureStepSound* sound_step = (LLGestureStepSound*)step; + const LLUUID& sound_id = sound_step->mSoundAssetID; + + if (!(sound_id.isNull() + || self.mLoadingAssets.find(sound_id) == self.mLoadingAssets.end())) + { + return true; + } + break; + } + case STEP_CHAT: + case STEP_WAIT: + case STEP_EOF: + { + break; + } + default: + { + LL_WARNS() << "Unknown gesture step type: " << step->getType() << LL_ENDL; + } + } + } + + return false; +} void LLGestureMgr::stopGesture(LLMultiGesture* gesture) { @@ -1166,7 +1329,7 @@ void LLGestureMgr::removeObserver(LLGestureManagerObserver* observer) // from the list. void LLGestureMgr::notifyObservers() { - lldebugs << "LLGestureMgr::notifyObservers" << llendl; + LL_DEBUGS() << "LLGestureMgr::notifyObservers" << LL_ENDL; for(std::vector<LLGestureManagerObserver*>::iterator iter = mObservers.begin(); iter != mObservers.end(); @@ -1181,6 +1344,7 @@ BOOL LLGestureMgr::matchPrefix(const std::string& in_str, std::string* out_str) { S32 in_len = in_str.length(); + //return whole trigger, if received text equals to it item_map_t::iterator it; for (it = mActive.begin(); it != mActive.end(); ++it) { @@ -1188,7 +1352,24 @@ BOOL LLGestureMgr::matchPrefix(const std::string& in_str, std::string* out_str) if (gesture) { const std::string& trigger = gesture->getTrigger(); - + if (!LLStringUtil::compareInsensitive(in_str, trigger)) + { + *out_str = trigger; + return TRUE; + } + } + } + + //return common chars, if more than one trigger matches the prefix + std::string rest_of_match = ""; + std::string buf = ""; + for (it = mActive.begin(); it != mActive.end(); ++it) + { + LLMultiGesture* gesture = (*it).second; + if (gesture) + { + const std::string& trigger = gesture->getTrigger(); + if (in_len > (S32)trigger.length()) { // too short, bail out @@ -1199,11 +1380,49 @@ BOOL LLGestureMgr::matchPrefix(const std::string& in_str, std::string* out_str) LLStringUtil::truncate(trigger_trunc, in_len); if (!LLStringUtil::compareInsensitive(in_str, trigger_trunc)) { - *out_str = trigger; - return TRUE; + if (rest_of_match.compare("") == 0) + { + rest_of_match = trigger.substr(in_str.size()); + } + std::string cur_rest_of_match = trigger.substr(in_str.size()); + buf = ""; + S32 i=0; + + while (i<rest_of_match.length() && i<cur_rest_of_match.length()) + { + if (rest_of_match[i]==cur_rest_of_match[i]) + { + buf.push_back(rest_of_match[i]); + } + else + { + if(i==0) + { + rest_of_match = ""; + } + break; + } + i++; + } + if (rest_of_match.compare("") == 0) + { + return TRUE; + } + if (buf.compare("") != 0) + { + rest_of_match = buf; + } + } } } + + if (rest_of_match.compare("") != 0) + { + *out_str = in_str+rest_of_match; + return TRUE; + } + return FALSE; } |