diff options
Diffstat (limited to 'indra')
| -rw-r--r-- | indra/llmessage/llassetstorage.cpp | 23 | ||||
| -rw-r--r-- | indra/newview/llgesturemgr.cpp | 156 | ||||
| -rw-r--r-- | indra/newview/llgesturemgr.h | 19 | 
3 files changed, 191 insertions, 7 deletions
| diff --git a/indra/llmessage/llassetstorage.cpp b/indra/llmessage/llassetstorage.cpp index 27a368df3d..69d092de76 100644 --- a/indra/llmessage/llassetstorage.cpp +++ b/indra/llmessage/llassetstorage.cpp @@ -398,6 +398,12 @@ BOOL LLAssetStorage::hasLocalAsset(const LLUUID &uuid, const LLAssetType::EType  bool LLAssetStorage::findInStaticVFSAndInvokeCallback(const LLUUID& uuid, LLAssetType::EType type,  													  LLGetAssetCallback callback, void *user_data)  { +	if (user_data) +	{ +		// The *user_data should not be passed without a callback to clean it up. +		llassert(callback != NULL) +	} +  	BOOL exists = mStaticVFS->getExists(uuid, type);  	if (exists)  	{ @@ -432,15 +438,26 @@ void LLAssetStorage::getAssetData(const LLUUID uuid, LLAssetType::EType type, LL  	llinfos << "ASSET_TRACE requesting " << uuid << " type " << LLAssetType::lookup(type) << llendl; +	if (user_data) +	{ +		// The *user_data should not be passed without a callback to clean it up. +		llassert(callback != NULL) +	} +  	if (mShutDown)  	{  		llinfos << "ASSET_TRACE cancelled " << uuid << " type " << LLAssetType::lookup(type) << " shutting down" << llendl; -		return; // don't get the asset or do any callbacks, we are shutting down + +		if (callback) +		{ +			callback(mVFS, uuid, type, user_data, LL_ERR_ASSET_REQUEST_FAILED, LL_EXSTAT_NONE); +		} +		return;  	} -		 +  	if (uuid.isNull())  	{ -		// Special case early out for NULL uuid +		// Special case early out for NULL uuid and for shutting down  		if (callback)  		{  			callback(mVFS, uuid, type, user_data, LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE, LL_EXSTAT_NULL_UUID); diff --git a/indra/newview/llgesturemgr.cpp b/indra/newview/llgesturemgr.cpp index f658287fb1..2f9856c650 100644 --- a/indra/newview/llgesturemgr.cpp +++ b/indra/newview/llgesturemgr.cpp @@ -33,8 +33,10 @@  #include <algorithm>  // library +#include "llaudioengine.h"  #include "lldatapacker.h"  #include "llinventory.h" +#include "llkeyframemotion.h"  #include "llmultigesture.h"  #include "llnotificationsutil.h"  #include "llstl.h" @@ -526,6 +528,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: +			{ +				llwarns << "Unknown gesture step type: " << step->getType() << llendl; +			} +		} +	} +  	// And get it going  	stepGesture(gesture); @@ -741,7 +803,7 @@ void LLGestureMgr::stepGesture(LLMultiGesture* gesture)  	{  		return;  	} -	if (!isAgentAvatarValid()) return; +	if (!isAgentAvatarValid() || hasLoadingAssets(gesture)) return;  	// Of the ones that started playing, have any stopped? @@ -1091,6 +1153,98 @@ void LLGestureMgr::onLoadComplete(LLVFS *vfs,  	}  } +// 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: +		{ +			llwarns << "Unexpected asset type: " << type << llendl; + +			// 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: +			{ +				llwarns << "Unknown gesture step type: " << step->getType() << llendl; +			} +		} +	} + +	return false; +}  void LLGestureMgr::stopGesture(LLMultiGesture* gesture)  { diff --git a/indra/newview/llgesturemgr.h b/indra/newview/llgesturemgr.h index b9935efeb3..5930841cbc 100644 --- a/indra/newview/llgesturemgr.h +++ b/indra/newview/llgesturemgr.h @@ -154,9 +154,20 @@ protected:  	// Used by loadGesture  	static void onLoadComplete(LLVFS *vfs, -						   const LLUUID& asset_uuid, -						   LLAssetType::EType type, -						   void* user_data, S32 status, LLExtStat ext_status); +							   const LLUUID& asset_uuid, +							   LLAssetType::EType type, +							   void* user_data, S32 status, LLExtStat ext_status); + +	// Used by playGesture to load an asset file +	// required to play a gesture step +	static void onAssetLoadComplete(LLVFS *vfs, +									const LLUUID& asset_uuid, +									LLAssetType::EType type, +									void* user_data, S32 status, LLExtStat ext_status); + +	// Checks whether all animation and sound assets +	// needed to play a gesture are loaded. +	static bool hasLoadingAssets(LLMultiGesture* gesture);  private:  	// Active gestures. @@ -172,6 +183,8 @@ private:  	callback_map_t mCallbackMap;  	std::vector<LLMultiGesture*> mPlaying;	  	BOOL mValid; + +	std::set<LLUUID> mLoadingAssets;  };  #endif | 
