llmultigesture.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471
  1. /**
  2. * @file llmultigesture.cpp
  3. * @brief Gestures that are asset-based and can have multiple steps.
  4. *
  5. * $LicenseInfo:firstyear=2004&license=viewergpl$
  6. *
  7. * Copyright (c) 2004-2009, Linden Research, Inc.
  8. *
  9. * Second Life Viewer Source Code
  10. * The source code in this file ("Source Code") is provided by Linden Lab
  11. * to you under the terms of the GNU General Public License, version 2.0
  12. * ("GPL"), unless you have obtained a separate licensing agreement
  13. * ("Other License"), formally executed by you and Linden Lab. Terms of
  14. * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15. * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16. *
  17. * There are special exceptions to the terms and conditions of the GPL as
  18. * it is applied to this Source Code. View the full text of the exception
  19. * in the file doc/FLOSS-exception.txt in this software distribution, or
  20. * online at
  21. * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22. *
  23. * By copying, modifying or distributing this software, you acknowledge
  24. * that you have read and understood your obligations described above,
  25. * and agree to abide by those obligations.
  26. *
  27. * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28. * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29. * COMPLETENESS OR PERFORMANCE.
  30. * $/LicenseInfo$
  31. */
  32. #include "linden_common.h"
  33. #include <algorithm>
  34. #include "stdio.h"
  35. #include "llmultigesture.h"
  36. #include "lldatapacker.h"
  37. #include "llstl.h"
  38. constexpr S32 GESTURE_VERSION = 2;
  39. //---------------------------------------------------------------------------
  40. // LLMultiGesture
  41. //---------------------------------------------------------------------------
  42. LLMultiGesture::LLMultiGesture()
  43. : mKey(),
  44. mMask(),
  45. mTrigger(),
  46. mReplaceText(),
  47. mSteps(),
  48. mPlaying(false),
  49. mCurrentStep(0),
  50. mDoneCallback(NULL),
  51. mCallbackData(NULL)
  52. {
  53. reset();
  54. }
  55. LLMultiGesture::~LLMultiGesture()
  56. {
  57. std::for_each(mSteps.begin(), mSteps.end(), DeletePointer());
  58. mSteps.clear();
  59. }
  60. void LLMultiGesture::reset()
  61. {
  62. mPlaying = false;
  63. mCurrentStep = 0;
  64. mWaitTimer.reset();
  65. mWaitingTimer = false;
  66. mWaitingAnimations = false;
  67. mWaitingAtEnd = false;
  68. mRequestedAnimIDs.clear();
  69. mPlayingAnimIDs.clear();
  70. }
  71. S32 LLMultiGesture::getMaxSerialSize() const
  72. {
  73. S32 max_size = 0;
  74. // ASCII format, being very conservative about possible label lengths.
  75. max_size += 64; // Version S32
  76. max_size += 64; // Key U8
  77. max_size += 64; // Mask U32
  78. max_size += 256; // Trigger string
  79. max_size += 256; // Replace string
  80. max_size += 64; // Step count S32
  81. std::vector<LLGestureStep*>::const_iterator it;
  82. for (it = mSteps.begin(); it != mSteps.end(); ++it)
  83. {
  84. LLGestureStep* step = *it;
  85. max_size += 64; // type S32
  86. max_size += step->getMaxSerialSize();
  87. }
  88. return max_size;
  89. }
  90. bool LLMultiGesture::serialize(LLDataPacker& dp) const
  91. {
  92. dp.packS32(GESTURE_VERSION, "version");
  93. dp.packU8(mKey, "key");
  94. dp.packU32(mMask, "mask");
  95. dp.packString(mTrigger, "trigger");
  96. dp.packString(mReplaceText, "replace");
  97. S32 count = (S32)mSteps.size();
  98. dp.packS32(count, "step_count");
  99. for (S32 i = 0; i < count; ++i)
  100. {
  101. LLGestureStep* step = mSteps[i];
  102. dp.packS32(step->getType(), "step_type");
  103. if (!step->serialize(dp))
  104. {
  105. return false;
  106. }
  107. }
  108. return true;
  109. }
  110. bool LLMultiGesture::deserialize(LLDataPacker& dp)
  111. {
  112. S32 version;
  113. dp.unpackS32(version, "version");
  114. if (version != GESTURE_VERSION)
  115. {
  116. llwarns << "Bad LLMultiGesture version " << version << " should be "
  117. << GESTURE_VERSION << llendl;
  118. return false;
  119. }
  120. dp.unpackU8(mKey, "key");
  121. dp.unpackU32(mMask, "mask");
  122. dp.unpackString(mTrigger, "trigger");
  123. dp.unpackString(mReplaceText, "replace");
  124. S32 count;
  125. dp.unpackS32(count, "step_count");
  126. if (count < 0)
  127. {
  128. llwarns << "Bad LLMultiGesture step count " << count << llendl;
  129. return false;
  130. }
  131. for (S32 i = 0; i < count; ++i)
  132. {
  133. S32 type;
  134. dp.unpackS32(type, "step_type");
  135. EStepType step_type = (EStepType)type;
  136. switch (step_type)
  137. {
  138. case STEP_ANIMATION:
  139. {
  140. LLGestureStepAnimation* step = new LLGestureStepAnimation();
  141. if (!step->deserialize(dp))
  142. {
  143. delete step;
  144. return false;
  145. }
  146. mSteps.push_back(step);
  147. break;
  148. }
  149. case STEP_SOUND:
  150. {
  151. LLGestureStepSound* step = new LLGestureStepSound();
  152. if (!step->deserialize(dp))
  153. {
  154. delete step;
  155. return false;
  156. }
  157. mSteps.push_back(step);
  158. break;
  159. }
  160. case STEP_CHAT:
  161. {
  162. LLGestureStepChat* step = new LLGestureStepChat();
  163. if (!step->deserialize(dp))
  164. {
  165. delete step;
  166. return false;
  167. }
  168. mSteps.push_back(step);
  169. break;
  170. }
  171. case STEP_WAIT:
  172. {
  173. LLGestureStepWait* step = new LLGestureStepWait();
  174. if (!step->deserialize(dp))
  175. {
  176. delete step;
  177. return false;
  178. }
  179. mSteps.push_back(step);
  180. break;
  181. }
  182. default:
  183. {
  184. llwarns << "Bad LLMultiGesture step type " << type << llendl;
  185. return false;
  186. }
  187. }
  188. }
  189. return true;
  190. }
  191. void LLMultiGesture::dump()
  192. {
  193. llinfos << "key " << S32(mKey) << " mask " << U32(mMask) << " trigger "
  194. << mTrigger << " replace " << mReplaceText << llendl;
  195. for (U32 i = 0, count = mSteps.size(); i < count; ++i)
  196. {
  197. LLGestureStep* step = mSteps[i];
  198. if (step)
  199. {
  200. step->dump();
  201. }
  202. else
  203. {
  204. llwarns << "NULL step #" << i << llendl;
  205. }
  206. }
  207. }
  208. //---------------------------------------------------------------------------
  209. // LLGestureStepAnimation
  210. //---------------------------------------------------------------------------
  211. LLGestureStepAnimation::LLGestureStepAnimation()
  212. : LLGestureStep(),
  213. mAnimName("None"),
  214. mAnimAssetID(),
  215. mFlags(0x0)
  216. {
  217. }
  218. S32 LLGestureStepAnimation::getMaxSerialSize() const
  219. {
  220. #if 1
  221. // ASCII
  222. // 256 for anim name, 64 for asset Id, 64 for flags
  223. return 256 + 64 + 64;
  224. #else
  225. // Binary
  226. S32 max_size = mAnimName.length() + 1;
  227. max_size += sizeof(mAnimAssetID);
  228. max_size += sizeof(mFlags);
  229. return max_size;
  230. #endif
  231. }
  232. bool LLGestureStepAnimation::serialize(LLDataPacker& dp) const
  233. {
  234. dp.packString(mAnimName, "anim_name");
  235. dp.packUUID(mAnimAssetID, "asset_id");
  236. dp.packU32(mFlags, "flags");
  237. return true;
  238. }
  239. bool LLGestureStepAnimation::deserialize(LLDataPacker& dp)
  240. {
  241. dp.unpackString(mAnimName, "anim_name");
  242. // Apparently an earlier version of the gesture code added \r to the end
  243. // of the animation names. Get rid of it. JC
  244. if (!mAnimName.empty() && mAnimName[mAnimName.length() - 1] == '\r')
  245. {
  246. // Chop the last character
  247. mAnimName.resize(mAnimName.length() - 1);
  248. }
  249. dp.unpackUUID(mAnimAssetID, "asset_id");
  250. dp.unpackU32(mFlags, "flags");
  251. return true;
  252. }
  253. std::string LLGestureStepAnimation::getLabel() const
  254. {
  255. std::string label;
  256. if (mFlags & ANIM_FLAG_STOP)
  257. {
  258. label = "Stop Animation: ";
  259. }
  260. else
  261. {
  262. label = "Start Animation: ";
  263. }
  264. label += mAnimName;
  265. return label;
  266. }
  267. void LLGestureStepAnimation::dump()
  268. {
  269. llinfos << "step animation " << mAnimName << " id " << mAnimAssetID
  270. << " flags " << mFlags << llendl;
  271. }
  272. //---------------------------------------------------------------------------
  273. // LLGestureStepSound
  274. //---------------------------------------------------------------------------
  275. LLGestureStepSound::LLGestureStepSound()
  276. : LLGestureStep(),
  277. mSoundName("None"),
  278. mSoundAssetID(),
  279. mFlags(0x0)
  280. {
  281. }
  282. S32 LLGestureStepSound::getMaxSerialSize() const
  283. {
  284. S32 max_size = 0;
  285. max_size += 256; // sound name
  286. max_size += 64; // sound asset id
  287. max_size += 64; // flags
  288. /* binary
  289. max_size += mSoundName.length() + 1;
  290. max_size += sizeof(mSoundAssetID);
  291. max_size += sizeof(mFlags);
  292. */
  293. return max_size;
  294. }
  295. bool LLGestureStepSound::serialize(LLDataPacker& dp) const
  296. {
  297. dp.packString(mSoundName, "sound_name");
  298. dp.packUUID(mSoundAssetID, "asset_id");
  299. dp.packU32(mFlags, "flags");
  300. return true;
  301. }
  302. bool LLGestureStepSound::deserialize(LLDataPacker& dp)
  303. {
  304. dp.unpackString(mSoundName, "sound_name");
  305. dp.unpackUUID(mSoundAssetID, "asset_id");
  306. dp.unpackU32(mFlags, "flags");
  307. return true;
  308. }
  309. std::string LLGestureStepSound::getLabel() const
  310. {
  311. std::string label("Sound: ");
  312. label += mSoundName;
  313. return label;
  314. }
  315. void LLGestureStepSound::dump()
  316. {
  317. llinfos << "step sound " << mSoundName << " id " << mSoundAssetID
  318. << " flags " << mFlags << llendl;
  319. }
  320. //---------------------------------------------------------------------------
  321. // LLGestureStepChat
  322. //---------------------------------------------------------------------------
  323. LLGestureStepChat::LLGestureStepChat()
  324. : LLGestureStep(),
  325. mChatText(),
  326. mFlags(0x0)
  327. {
  328. }
  329. S32 LLGestureStepChat::getMaxSerialSize() const
  330. {
  331. S32 max_size = 0;
  332. max_size += 256; // chat text
  333. max_size += 64; // flags
  334. /* binary
  335. max_size += mChatText.length() + 1;
  336. max_size += sizeof(mFlags);
  337. */
  338. return max_size;
  339. }
  340. bool LLGestureStepChat::serialize(LLDataPacker& dp) const
  341. {
  342. dp.packString(mChatText, "chat_text");
  343. dp.packU32(mFlags, "flags");
  344. return true;
  345. }
  346. bool LLGestureStepChat::deserialize(LLDataPacker& dp)
  347. {
  348. dp.unpackString(mChatText, "chat_text");
  349. dp.unpackU32(mFlags, "flags");
  350. return true;
  351. }
  352. std::string LLGestureStepChat::getLabel() const
  353. {
  354. std::string label("Chat: ");
  355. label += mChatText;
  356. return label;
  357. }
  358. void LLGestureStepChat::dump()
  359. {
  360. llinfos << "step chat " << mChatText << " flags " << mFlags << llendl;
  361. }
  362. //---------------------------------------------------------------------------
  363. // LLGestureStepWait
  364. //---------------------------------------------------------------------------
  365. LLGestureStepWait::LLGestureStepWait()
  366. : LLGestureStep(),
  367. mWaitSeconds(0.f),
  368. mFlags(0x0)
  369. {
  370. }
  371. S32 LLGestureStepWait::getMaxSerialSize() const
  372. {
  373. S32 max_size = 0;
  374. max_size += 64; // wait seconds
  375. max_size += 64; // flags
  376. /* binary
  377. max_size += sizeof(mWaitSeconds);
  378. max_size += sizeof(mFlags);
  379. */
  380. return max_size;
  381. }
  382. bool LLGestureStepWait::serialize(LLDataPacker& dp) const
  383. {
  384. dp.packF32(mWaitSeconds, "wait_seconds");
  385. dp.packU32(mFlags, "flags");
  386. return true;
  387. }
  388. bool LLGestureStepWait::deserialize(LLDataPacker& dp)
  389. {
  390. dp.unpackF32(mWaitSeconds, "wait_seconds");
  391. dp.unpackU32(mFlags, "flags");
  392. return true;
  393. }
  394. std::string LLGestureStepWait::getLabel() const
  395. {
  396. std::string label("--- Wait: ");
  397. if (mFlags & WAIT_FLAG_TIME)
  398. {
  399. char buffer[64];
  400. snprintf(buffer, sizeof(buffer), "%.1f seconds", (double)mWaitSeconds);
  401. label += buffer;
  402. }
  403. else if (mFlags & WAIT_FLAG_ALL_ANIM)
  404. {
  405. label += "until animations are done";
  406. }
  407. return label;
  408. }
  409. void LLGestureStepWait::dump()
  410. {
  411. llinfos << "step wait " << mWaitSeconds << " flags " << mFlags << llendl;
  412. }