PageRenderTime 347ms CodeModel.GetById 80ms app.highlight 173ms RepoModel.GetById 89ms app.codeStats 0ms

/indra/llcharacter/llmultigesture.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 509 lines | 351 code | 65 blank | 93 comment | 20 complexity | 050f139b7e45e671d36f68724e7e0ad4 MD5 | raw file
  1/** 
  2 * @file llmultigesture.cpp
  3 * @brief Gestures that are asset-based and can have multiple steps.
  4 *
  5 * $LicenseInfo:firstyear=2004&license=viewerlgpl$
  6 * Second Life Viewer Source Code
  7 * Copyright (C) 2010, Linden Research, Inc.
  8 * 
  9 * This library is free software; you can redistribute it and/or
 10 * modify it under the terms of the GNU Lesser General Public
 11 * License as published by the Free Software Foundation;
 12 * version 2.1 of the License only.
 13 * 
 14 * This library is distributed in the hope that it will be useful,
 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 17 * Lesser General Public License for more details.
 18 * 
 19 * You should have received a copy of the GNU Lesser General Public
 20 * License along with this library; if not, write to the Free Software
 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 22 * 
 23 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 24 * $/LicenseInfo$
 25 */
 26
 27#include "linden_common.h"
 28
 29#include <algorithm>
 30
 31#include "stdio.h"
 32
 33#include "llmultigesture.h"
 34
 35#include "llerror.h"
 36#include "lldatapacker.h"
 37#include "llstl.h"
 38
 39const S32 GESTURE_VERSION = 2;
 40
 41//---------------------------------------------------------------------------
 42// LLMultiGesture
 43//---------------------------------------------------------------------------
 44LLMultiGesture::LLMultiGesture()
 45:	mKey(),
 46	mMask(),
 47	mName(),
 48	mTrigger(),
 49	mReplaceText(),
 50	mSteps(),
 51	mPlaying(FALSE),
 52	mCurrentStep(0),
 53	mDoneCallback(NULL),
 54	mCallbackData(NULL)
 55{
 56	reset();
 57}
 58
 59LLMultiGesture::~LLMultiGesture()
 60{
 61	std::for_each(mSteps.begin(), mSteps.end(), DeletePointer());
 62}
 63
 64void LLMultiGesture::reset()
 65{
 66	mPlaying = FALSE;
 67	mCurrentStep = 0;
 68	mWaitTimer.reset();
 69	mWaitingTimer = FALSE;
 70	mWaitingAnimations = FALSE;
 71	mWaitingAtEnd = FALSE;
 72	mRequestedAnimIDs.clear();
 73	mPlayingAnimIDs.clear();
 74}
 75
 76S32 LLMultiGesture::getMaxSerialSize() const
 77{
 78	S32 max_size = 0;
 79
 80	// ascii format, being very conservative about possible
 81	// label lengths.
 82	max_size += 64;		// version S32
 83	max_size += 64;		// key U8
 84	max_size += 64;		// mask U32
 85	max_size += 256;	// trigger string
 86	max_size += 256;	// replace string
 87
 88	max_size += 64;		// step count S32
 89
 90	std::vector<LLGestureStep*>::const_iterator it;
 91	for (it = mSteps.begin(); it != mSteps.end(); ++it)
 92	{
 93		LLGestureStep* step = *it;
 94		max_size += 64;	// type S32
 95		max_size += step->getMaxSerialSize();
 96	}
 97
 98	/* binary format
 99	max_size += sizeof(S32);	// version
100	max_size += sizeof(mKey);
101	max_size += sizeof(mMask);
102	max_size += mTrigger.length() + 1;	// for null
103
104	max_size += sizeof(S32);	// step count
105
106	std::vector<LLGestureStep*>::const_iterator it;
107	for (it = mSteps.begin(); it != mSteps.end(); ++it)
108	{
109		LLGestureStep* step = *it;
110		max_size += sizeof(S32);	// type
111		max_size += step->getMaxSerialSize();
112	}
113	*/
114	
115	return max_size;
116}
117
118BOOL LLMultiGesture::serialize(LLDataPacker& dp) const
119{
120	dp.packS32(GESTURE_VERSION, "version");
121	dp.packU8(mKey, "key");
122	dp.packU32(mMask, "mask");
123	dp.packString(mTrigger, "trigger");
124	dp.packString(mReplaceText, "replace");
125
126	S32 count = (S32)mSteps.size();
127	dp.packS32(count, "step_count");
128	S32 i;
129	for (i = 0; i < count; ++i)
130	{
131		LLGestureStep* step = mSteps[i];
132
133		dp.packS32(step->getType(), "step_type");
134		BOOL ok = step->serialize(dp);
135		if (!ok)
136		{
137			return FALSE;
138		}
139	}
140	return TRUE;
141}
142
143BOOL LLMultiGesture::deserialize(LLDataPacker& dp)
144{
145	S32 version;
146	dp.unpackS32(version, "version");
147	if (version != GESTURE_VERSION)
148	{
149		llwarns << "Bad LLMultiGesture version " << version
150			<< " should be " << GESTURE_VERSION
151			<< llendl;
152		return FALSE;
153	}
154
155	dp.unpackU8(mKey, "key");
156	dp.unpackU32(mMask, "mask");
157
158	
159	dp.unpackString(mTrigger, "trigger");
160
161	dp.unpackString(mReplaceText, "replace");
162
163	S32 count;
164	dp.unpackS32(count, "step_count");
165	if (count < 0)
166	{
167		llwarns << "Bad LLMultiGesture step count " << count << llendl;
168		return FALSE;
169	}
170
171	S32 i;
172	for (i = 0; i < count; ++i)
173	{
174		S32 type;
175		dp.unpackS32(type, "step_type");
176
177		EStepType step_type = (EStepType)type;
178		switch(step_type)
179		{
180		case STEP_ANIMATION:
181			{
182				LLGestureStepAnimation* step = new LLGestureStepAnimation();
183				BOOL ok = step->deserialize(dp);
184				if (!ok) return FALSE;
185				mSteps.push_back(step);
186				break;
187			}
188		case STEP_SOUND:
189			{
190				LLGestureStepSound* step = new LLGestureStepSound();
191				BOOL ok = step->deserialize(dp);
192				if (!ok) return FALSE;
193				mSteps.push_back(step);
194				break;
195			}
196		case STEP_CHAT:
197			{
198				LLGestureStepChat* step = new LLGestureStepChat();
199				BOOL ok = step->deserialize(dp);
200				if (!ok) return FALSE;
201				mSteps.push_back(step);
202				break;
203			}
204		case STEP_WAIT:
205			{
206				LLGestureStepWait* step = new LLGestureStepWait();
207				BOOL ok = step->deserialize(dp);
208				if (!ok) return FALSE;
209				mSteps.push_back(step);
210				break;
211			}
212		default:
213			{
214				llwarns << "Bad LLMultiGesture step type " << type << llendl;
215				return FALSE;
216			}
217		}
218	}
219	return TRUE;
220}
221
222void LLMultiGesture::dump()
223{
224	llinfos << "key " << S32(mKey) << " mask " << U32(mMask) 
225		<< " trigger " << mTrigger
226		<< " replace " << mReplaceText
227		<< llendl;
228	U32 i;
229	for (i = 0; i < mSteps.size(); ++i)
230	{
231		LLGestureStep* step = mSteps[i];
232		step->dump();
233	}
234}
235
236//---------------------------------------------------------------------------
237// LLGestureStepAnimation
238//---------------------------------------------------------------------------
239LLGestureStepAnimation::LLGestureStepAnimation()
240:	LLGestureStep(),
241	mAnimName("None"), 
242	mAnimAssetID(),
243	mFlags(0x0)
244{ }
245
246LLGestureStepAnimation::~LLGestureStepAnimation()
247{ }
248
249S32 LLGestureStepAnimation::getMaxSerialSize() const
250{
251	S32 max_size = 0;
252
253	// ascii
254	max_size += 256;	// anim name
255	max_size += 64;		// anim asset id
256	max_size += 64;		// flags
257
258	/* binary
259	max_size += mAnimName.length() + 1;
260	max_size += sizeof(mAnimAssetID);
261	max_size += sizeof(mFlags);
262	*/
263	return max_size;
264}
265
266BOOL LLGestureStepAnimation::serialize(LLDataPacker& dp) const
267{
268	dp.packString(mAnimName, "anim_name");
269	dp.packUUID(mAnimAssetID, "asset_id");
270	dp.packU32(mFlags, "flags");
271	return TRUE;
272}
273
274BOOL LLGestureStepAnimation::deserialize(LLDataPacker& dp)
275{
276	dp.unpackString(mAnimName, "anim_name");
277
278	// Apparently an earlier version of the gesture code added \r to the end
279	// of the animation names.  Get rid of it.  JC
280	if (!mAnimName.empty() && mAnimName[mAnimName.length() - 1] == '\r')
281	{
282		// chop the last character
283		mAnimName.resize(mAnimName.length() - 1);
284	}
285
286	dp.unpackUUID(mAnimAssetID, "asset_id");
287	dp.unpackU32(mFlags, "flags");
288	return TRUE;
289}
290// *NOTE: result is translated in LLPreviewGesture::getLabel()
291std::vector<std::string> LLGestureStepAnimation::getLabel() const 
292{
293	std::vector<std::string> strings;
294	
295//	std::string label;
296	if (mFlags & ANIM_FLAG_STOP)
297	{
298		strings.push_back( "AnimFlagStop");
299
300//		label = "Stop Animation: ";
301	}
302	else
303	{
304		strings.push_back( "AnimFlagStart");
305
306//		label = "Start Animation: "; 
307	}
308	strings.push_back( mAnimName);
309//	label += mAnimName;
310	return strings;
311}
312
313void LLGestureStepAnimation::dump()
314{
315	llinfos << "step animation " << mAnimName
316		<< " id " << mAnimAssetID
317		<< " flags " << mFlags
318		<< llendl;
319}
320
321//---------------------------------------------------------------------------
322// LLGestureStepSound
323//---------------------------------------------------------------------------
324LLGestureStepSound::LLGestureStepSound()
325:	LLGestureStep(),
326	mSoundName("None"),
327	mSoundAssetID(),
328	mFlags(0x0)
329{ }
330
331LLGestureStepSound::~LLGestureStepSound()
332{ }
333
334S32 LLGestureStepSound::getMaxSerialSize() const
335{
336	S32 max_size = 0;
337	max_size += 256;	// sound name
338	max_size += 64;		// sound asset id
339	max_size += 64;		// flags
340	/* binary
341	max_size += mSoundName.length() + 1;
342	max_size += sizeof(mSoundAssetID);
343	max_size += sizeof(mFlags);
344	*/
345	return max_size;
346}
347
348BOOL LLGestureStepSound::serialize(LLDataPacker& dp) const
349{
350	dp.packString(mSoundName, "sound_name");
351	dp.packUUID(mSoundAssetID, "asset_id");
352	dp.packU32(mFlags, "flags");
353	return TRUE;
354}
355
356BOOL LLGestureStepSound::deserialize(LLDataPacker& dp)
357{
358	dp.unpackString(mSoundName, "sound_name");
359
360	dp.unpackUUID(mSoundAssetID, "asset_id");
361	dp.unpackU32(mFlags, "flags");
362	return TRUE;
363}
364// *NOTE: result is translated in LLPreviewGesture::getLabel()
365std::vector<std::string> LLGestureStepSound::getLabel() const
366{
367	std::vector<std::string> strings;
368	strings.push_back( "Sound");
369	strings.push_back( mSoundName);	
370//	std::string label("Sound: ");
371//	label += mSoundName;
372	return strings;
373}
374
375void LLGestureStepSound::dump()
376{
377	llinfos << "step sound " << mSoundName
378		<< " id " << mSoundAssetID
379		<< " flags " << mFlags
380		<< llendl;
381}
382
383
384//---------------------------------------------------------------------------
385// LLGestureStepChat
386//---------------------------------------------------------------------------
387LLGestureStepChat::LLGestureStepChat()
388:	LLGestureStep(),
389	mChatText(),
390	mFlags(0x0)
391{ }
392
393LLGestureStepChat::~LLGestureStepChat()
394{ }
395
396S32 LLGestureStepChat::getMaxSerialSize() const
397{
398	S32 max_size = 0;
399	max_size += 256;	// chat text
400	max_size += 64;		// flags
401	/* binary
402	max_size += mChatText.length() + 1;
403	max_size += sizeof(mFlags);
404	*/
405	return max_size;
406}
407
408BOOL LLGestureStepChat::serialize(LLDataPacker& dp) const
409{
410	dp.packString(mChatText, "chat_text");
411	dp.packU32(mFlags, "flags");
412	return TRUE;
413}
414
415BOOL LLGestureStepChat::deserialize(LLDataPacker& dp)
416{
417	dp.unpackString(mChatText, "chat_text");
418
419	dp.unpackU32(mFlags, "flags");
420	return TRUE;
421}
422// *NOTE: result is translated in LLPreviewGesture::getLabel()
423std::vector<std::string> LLGestureStepChat::getLabel() const
424{
425	std::vector<std::string> strings;
426	strings.push_back("Chat");
427	strings.push_back(mChatText);
428	return strings;
429}
430
431void LLGestureStepChat::dump()
432{
433	llinfos << "step chat " << mChatText
434		<< " flags " << mFlags
435		<< llendl;
436}
437
438
439//---------------------------------------------------------------------------
440// LLGestureStepWait
441//---------------------------------------------------------------------------
442LLGestureStepWait::LLGestureStepWait()
443:	LLGestureStep(),
444	mWaitSeconds(0.f),
445	mFlags(0x0)
446{ }
447
448LLGestureStepWait::~LLGestureStepWait()
449{ }
450
451S32 LLGestureStepWait::getMaxSerialSize() const
452{
453	S32 max_size = 0;
454	max_size += 64;		// wait seconds
455	max_size += 64;		// flags
456	/* binary
457	max_size += sizeof(mWaitSeconds);
458	max_size += sizeof(mFlags);
459	*/
460	return max_size;
461}
462
463BOOL LLGestureStepWait::serialize(LLDataPacker& dp) const
464{
465	dp.packF32(mWaitSeconds, "wait_seconds");
466	dp.packU32(mFlags, "flags");
467	return TRUE;
468}
469
470BOOL LLGestureStepWait::deserialize(LLDataPacker& dp)
471{
472	dp.unpackF32(mWaitSeconds, "wait_seconds");
473	dp.unpackU32(mFlags, "flags");
474	return TRUE;
475}
476// *NOTE: result is translated in LLPreviewGesture::getLabel()
477std::vector<std::string> LLGestureStepWait::getLabel() const
478{
479	std::vector<std::string> strings;
480	strings.push_back( "Wait" );
481	
482//	std::string label("--- Wait: ");
483	if (mFlags & WAIT_FLAG_TIME)
484	{
485		char buffer[64];		/* Flawfinder: ignore */
486		snprintf(buffer, sizeof(buffer), "%.1f seconds", (double)mWaitSeconds);	/* Flawfinder: ignore */
487		strings.push_back(buffer);
488//		label += buffer;
489	}
490	else if (mFlags & WAIT_FLAG_ALL_ANIM)
491	{
492		strings.push_back("until animations are done");
493	//	label += "until animations are done";
494	}
495	else
496	{
497		strings.push_back("");
498	}
499
500	return strings;
501}
502
503
504void LLGestureStepWait::dump()
505{
506	llinfos << "step wait " << mWaitSeconds
507		<< " flags " << mFlags
508		<< llendl;
509}