00001
00032 #include "linden_common.h"
00033
00034 #include <algorithm>
00035
00036 #include "stdio.h"
00037
00038 #include "llmultigesture.h"
00039
00040 #include "llerror.h"
00041 #include "lldatapacker.h"
00042 #include "llstl.h"
00043
00044 const S32 GESTURE_VERSION = 2;
00045
00046
00047
00048
00049 LLMultiGesture::LLMultiGesture()
00050 : mKey(),
00051 mMask(),
00052 mTrigger(),
00053 mReplaceText(),
00054 mSteps(),
00055 mPlaying(FALSE),
00056 mCurrentStep(0),
00057 mDoneCallback(NULL),
00058 mCallbackData(NULL)
00059 {
00060 reset();
00061 }
00062
00063 LLMultiGesture::~LLMultiGesture()
00064 {
00065 std::for_each(mSteps.begin(), mSteps.end(), DeletePointer());
00066 }
00067
00068 void LLMultiGesture::reset()
00069 {
00070 mPlaying = FALSE;
00071 mCurrentStep = 0;
00072 mWaitTimer.reset();
00073 mWaitingTimer = FALSE;
00074 mWaitingAnimations = FALSE;
00075 mWaitingAtEnd = FALSE;
00076 mRequestedAnimIDs.clear();
00077 mPlayingAnimIDs.clear();
00078 }
00079
00080 S32 LLMultiGesture::getMaxSerialSize() const
00081 {
00082 S32 max_size = 0;
00083
00084
00085
00086 max_size += 64;
00087 max_size += 64;
00088 max_size += 64;
00089 max_size += 256;
00090 max_size += 256;
00091
00092 max_size += 64;
00093
00094 std::vector<LLGestureStep*>::const_iterator it;
00095 for (it = mSteps.begin(); it != mSteps.end(); ++it)
00096 {
00097 LLGestureStep* step = *it;
00098 max_size += 64;
00099 max_size += step->getMaxSerialSize();
00100 }
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119 return max_size;
00120 }
00121
00122 BOOL LLMultiGesture::serialize(LLDataPacker& dp) const
00123 {
00124 dp.packS32(GESTURE_VERSION, "version");
00125 dp.packU8(mKey, "key");
00126 dp.packU32(mMask, "mask");
00127 dp.packString(mTrigger.c_str(), "trigger");
00128 dp.packString(mReplaceText.c_str(), "replace");
00129
00130 S32 count = (S32)mSteps.size();
00131 dp.packS32(count, "step_count");
00132 S32 i;
00133 for (i = 0; i < count; ++i)
00134 {
00135 LLGestureStep* step = mSteps[i];
00136
00137 dp.packS32(step->getType(), "step_type");
00138 BOOL ok = step->serialize(dp);
00139 if (!ok)
00140 {
00141 return FALSE;
00142 }
00143 }
00144 return TRUE;
00145 }
00146
00147 BOOL LLMultiGesture::deserialize(LLDataPacker& dp)
00148 {
00149 S32 version;
00150 dp.unpackS32(version, "version");
00151 if (version != GESTURE_VERSION)
00152 {
00153 llwarns << "Bad LLMultiGesture version " << version
00154 << " should be " << GESTURE_VERSION
00155 << llendl;
00156 return FALSE;
00157 }
00158
00159 dp.unpackU8(mKey, "key");
00160 dp.unpackU32(mMask, "mask");
00161
00162
00163 dp.unpackString(mTrigger, "trigger");
00164
00165 dp.unpackString(mReplaceText, "replace");
00166
00167 S32 count;
00168 dp.unpackS32(count, "step_count");
00169 if (count < 0)
00170 {
00171 llwarns << "Bad LLMultiGesture step count " << count << llendl;
00172 return FALSE;
00173 }
00174
00175 S32 i;
00176 for (i = 0; i < count; ++i)
00177 {
00178 S32 type;
00179 dp.unpackS32(type, "step_type");
00180
00181 EStepType step_type = (EStepType)type;
00182 switch(step_type)
00183 {
00184 case STEP_ANIMATION:
00185 {
00186 LLGestureStepAnimation* step = new LLGestureStepAnimation();
00187 BOOL ok = step->deserialize(dp);
00188 if (!ok) return FALSE;
00189 mSteps.push_back(step);
00190 break;
00191 }
00192 case STEP_SOUND:
00193 {
00194 LLGestureStepSound* step = new LLGestureStepSound();
00195 BOOL ok = step->deserialize(dp);
00196 if (!ok) return FALSE;
00197 mSteps.push_back(step);
00198 break;
00199 }
00200 case STEP_CHAT:
00201 {
00202 LLGestureStepChat* step = new LLGestureStepChat();
00203 BOOL ok = step->deserialize(dp);
00204 if (!ok) return FALSE;
00205 mSteps.push_back(step);
00206 break;
00207 }
00208 case STEP_WAIT:
00209 {
00210 LLGestureStepWait* step = new LLGestureStepWait();
00211 BOOL ok = step->deserialize(dp);
00212 if (!ok) return FALSE;
00213 mSteps.push_back(step);
00214 break;
00215 }
00216 default:
00217 {
00218 llwarns << "Bad LLMultiGesture step type " << type << llendl;
00219 return FALSE;
00220 }
00221 }
00222 }
00223 return TRUE;
00224 }
00225
00226 void LLMultiGesture::dump()
00227 {
00228 llinfos << "key " << S32(mKey) << " mask " << U32(mMask)
00229 << " trigger " << mTrigger
00230 << " replace " << mReplaceText
00231 << llendl;
00232 U32 i;
00233 for (i = 0; i < mSteps.size(); ++i)
00234 {
00235 LLGestureStep* step = mSteps[i];
00236 step->dump();
00237 }
00238 }
00239
00240
00241
00242
00243 LLGestureStepAnimation::LLGestureStepAnimation()
00244 : LLGestureStep(),
00245 mAnimName("None"),
00246 mAnimAssetID(),
00247 mFlags(0x0)
00248 { }
00249
00250 LLGestureStepAnimation::~LLGestureStepAnimation()
00251 { }
00252
00253 S32 LLGestureStepAnimation::getMaxSerialSize() const
00254 {
00255 S32 max_size = 0;
00256
00257
00258 max_size += 256;
00259 max_size += 64;
00260 max_size += 64;
00261
00262
00263
00264
00265
00266
00267 return max_size;
00268 }
00269
00270 BOOL LLGestureStepAnimation::serialize(LLDataPacker& dp) const
00271 {
00272 dp.packString(mAnimName.c_str(), "anim_name");
00273 dp.packUUID(mAnimAssetID, "asset_id");
00274 dp.packU32(mFlags, "flags");
00275 return TRUE;
00276 }
00277
00278 BOOL LLGestureStepAnimation::deserialize(LLDataPacker& dp)
00279 {
00280 dp.unpackString(mAnimName, "anim_name");
00281
00282
00283
00284 if (!mAnimName.empty() && mAnimName[mAnimName.length() - 1] == '\r')
00285 {
00286
00287 mAnimName.resize(mAnimName.length() - 1);
00288 }
00289
00290 dp.unpackUUID(mAnimAssetID, "asset_id");
00291 dp.unpackU32(mFlags, "flags");
00292 return TRUE;
00293 }
00294
00295 std::string LLGestureStepAnimation::getLabel() const
00296 {
00297 std::string label;
00298 if (mFlags & ANIM_FLAG_STOP)
00299 {
00300 label = "Stop Animation: ";
00301 }
00302 else
00303 {
00304 label = "Start Animation: ";
00305 }
00306 label += mAnimName;
00307 return label;
00308 }
00309
00310 void LLGestureStepAnimation::dump()
00311 {
00312 llinfos << "step animation " << mAnimName
00313 << " id " << mAnimAssetID
00314 << " flags " << mFlags
00315 << llendl;
00316 }
00317
00318
00319
00320
00321 LLGestureStepSound::LLGestureStepSound()
00322 : LLGestureStep(),
00323 mSoundName("None"),
00324 mSoundAssetID(),
00325 mFlags(0x0)
00326 { }
00327
00328 LLGestureStepSound::~LLGestureStepSound()
00329 { }
00330
00331 S32 LLGestureStepSound::getMaxSerialSize() const
00332 {
00333 S32 max_size = 0;
00334 max_size += 256;
00335 max_size += 64;
00336 max_size += 64;
00337
00338
00339
00340
00341
00342 return max_size;
00343 }
00344
00345 BOOL LLGestureStepSound::serialize(LLDataPacker& dp) const
00346 {
00347 dp.packString(mSoundName.c_str(), "sound_name");
00348 dp.packUUID(mSoundAssetID, "asset_id");
00349 dp.packU32(mFlags, "flags");
00350 return TRUE;
00351 }
00352
00353 BOOL LLGestureStepSound::deserialize(LLDataPacker& dp)
00354 {
00355 dp.unpackString(mSoundName, "sound_name");
00356
00357 dp.unpackUUID(mSoundAssetID, "asset_id");
00358 dp.unpackU32(mFlags, "flags");
00359 return TRUE;
00360 }
00361
00362 std::string LLGestureStepSound::getLabel() const
00363 {
00364 std::string label("Sound: ");
00365 label += mSoundName;
00366 return label;
00367 }
00368
00369 void LLGestureStepSound::dump()
00370 {
00371 llinfos << "step sound " << mSoundName
00372 << " id " << mSoundAssetID
00373 << " flags " << mFlags
00374 << llendl;
00375 }
00376
00377
00378
00379
00380
00381 LLGestureStepChat::LLGestureStepChat()
00382 : LLGestureStep(),
00383 mChatText(),
00384 mFlags(0x0)
00385 { }
00386
00387 LLGestureStepChat::~LLGestureStepChat()
00388 { }
00389
00390 S32 LLGestureStepChat::getMaxSerialSize() const
00391 {
00392 S32 max_size = 0;
00393 max_size += 256;
00394 max_size += 64;
00395
00396
00397
00398
00399 return max_size;
00400 }
00401
00402 BOOL LLGestureStepChat::serialize(LLDataPacker& dp) const
00403 {
00404 dp.packString(mChatText.c_str(), "chat_text");
00405 dp.packU32(mFlags, "flags");
00406 return TRUE;
00407 }
00408
00409 BOOL LLGestureStepChat::deserialize(LLDataPacker& dp)
00410 {
00411 dp.unpackString(mChatText, "chat_text");
00412
00413 dp.unpackU32(mFlags, "flags");
00414 return TRUE;
00415 }
00416
00417 std::string LLGestureStepChat::getLabel() const
00418 {
00419 std::string label("Chat: ");
00420 label += mChatText;
00421 return label;
00422 }
00423
00424 void LLGestureStepChat::dump()
00425 {
00426 llinfos << "step chat " << mChatText
00427 << " flags " << mFlags
00428 << llendl;
00429 }
00430
00431
00432
00433
00434
00435 LLGestureStepWait::LLGestureStepWait()
00436 : LLGestureStep(),
00437 mWaitSeconds(0.f),
00438 mFlags(0x0)
00439 { }
00440
00441 LLGestureStepWait::~LLGestureStepWait()
00442 { }
00443
00444 S32 LLGestureStepWait::getMaxSerialSize() const
00445 {
00446 S32 max_size = 0;
00447 max_size += 64;
00448 max_size += 64;
00449
00450
00451
00452
00453 return max_size;
00454 }
00455
00456 BOOL LLGestureStepWait::serialize(LLDataPacker& dp) const
00457 {
00458 dp.packF32(mWaitSeconds, "wait_seconds");
00459 dp.packU32(mFlags, "flags");
00460 return TRUE;
00461 }
00462
00463 BOOL LLGestureStepWait::deserialize(LLDataPacker& dp)
00464 {
00465 dp.unpackF32(mWaitSeconds, "wait_seconds");
00466 dp.unpackU32(mFlags, "flags");
00467 return TRUE;
00468 }
00469
00470 std::string LLGestureStepWait::getLabel() const
00471 {
00472 std::string label("--- Wait: ");
00473 if (mFlags & WAIT_FLAG_TIME)
00474 {
00475 char buffer[64];
00476 snprintf(buffer, sizeof(buffer), "%.1f seconds", (double)mWaitSeconds);
00477 label += buffer;
00478 }
00479 else if (mFlags & WAIT_FLAG_ALL_ANIM)
00480 {
00481 label += "until animations are done";
00482 }
00483
00484 return label;
00485 }
00486
00487
00488 void LLGestureStepWait::dump()
00489 {
00490 llinfos << "step wait " << mWaitSeconds
00491 << " flags " << mFlags
00492 << llendl;
00493 }