/indra/newview/llviewergesture.cpp

https://bitbucket.org/lindenlab/viewer-beta/ · C++ · 204 lines · 135 code · 31 blank · 38 comment · 23 complexity · 74950b2cd28c70cffafa8f382c6d491a MD5 · raw file

  1. /**
  2. * @file llviewergesture.cpp
  3. * @brief LLViewerGesture class implementation
  4. *
  5. * $LicenseInfo:firstyear=2002&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. #include "llviewerprecompiledheaders.h"
  27. #include "llviewergesture.h"
  28. #include "llaudioengine.h"
  29. #include "lldir.h"
  30. #include "llviewerinventory.h"
  31. #include "sound_ids.h" // for testing
  32. #include "llkeyboard.h" // for key shortcuts for testing
  33. #include "llinventorymodel.h"
  34. #include "llvoavatar.h"
  35. #include "llxfermanager.h"
  36. #include "llviewermessage.h" // send_guid_sound_trigger
  37. #include "llviewernetwork.h"
  38. #include "llagent.h"
  39. #include "llnearbychatbar.h"
  40. // Globals
  41. LLViewerGestureList gGestureList;
  42. const F32 LLViewerGesture::SOUND_VOLUME = 1.f;
  43. LLViewerGesture::LLViewerGesture()
  44. : LLGesture()
  45. { }
  46. LLViewerGesture::LLViewerGesture(KEY key, MASK mask, const std::string &trigger,
  47. const LLUUID &sound_item_id,
  48. const std::string &animation,
  49. const std::string &output_string)
  50. : LLGesture(key, mask, trigger, sound_item_id, animation, output_string)
  51. {
  52. }
  53. LLViewerGesture::LLViewerGesture(U8 **buffer, S32 max_size)
  54. : LLGesture(buffer, max_size)
  55. {
  56. }
  57. LLViewerGesture::LLViewerGesture(const LLViewerGesture &rhs)
  58. : LLGesture((LLGesture)rhs)
  59. {
  60. }
  61. BOOL LLViewerGesture::trigger(KEY key, MASK mask)
  62. {
  63. if (mKey == key && mMask == mask)
  64. {
  65. doTrigger( TRUE );
  66. return TRUE;
  67. }
  68. else
  69. {
  70. return FALSE;
  71. }
  72. }
  73. BOOL LLViewerGesture::trigger(const std::string &trigger_string)
  74. {
  75. // Assumes trigger_string is lowercase
  76. if (mTriggerLower == trigger_string)
  77. {
  78. doTrigger( FALSE );
  79. return TRUE;
  80. }
  81. else
  82. {
  83. return FALSE;
  84. }
  85. }
  86. // private
  87. void LLViewerGesture::doTrigger( BOOL send_chat )
  88. {
  89. if (mSoundItemID != LLUUID::null)
  90. {
  91. LLViewerInventoryItem *item;
  92. item = gInventory.getItem(mSoundItemID);
  93. if (item)
  94. {
  95. send_sound_trigger(item->getAssetUUID(), SOUND_VOLUME);
  96. }
  97. }
  98. if (!mAnimation.empty())
  99. {
  100. // AFK animations trigger the special "away" state, which
  101. // includes agent control settings. JC
  102. if (mAnimation == "enter_away_from_keyboard_state" || mAnimation == "away")
  103. {
  104. gAgent.setAFK();
  105. }
  106. else
  107. {
  108. LLUUID anim_id = gAnimLibrary.stringToAnimState(mAnimation);
  109. gAgent.sendAnimationRequest(anim_id, ANIM_REQUEST_START);
  110. }
  111. }
  112. if (send_chat && !mOutputString.empty())
  113. {
  114. // Don't play nodding animation, since that might not blend
  115. // with the gesture animation.
  116. LLNearbyChatBar::getInstance()->sendChatFromViewer(mOutputString, CHAT_TYPE_NORMAL, FALSE);
  117. }
  118. }
  119. LLViewerGestureList::LLViewerGestureList()
  120. : LLGestureList()
  121. {
  122. mIsLoaded = FALSE;
  123. }
  124. // helper for deserialize that creates the right LLGesture subclass
  125. LLGesture *LLViewerGestureList::create_gesture(U8 **buffer, S32 max_size)
  126. {
  127. return new LLViewerGesture(buffer, max_size);
  128. }
  129. // See if the prefix matches any gesture. If so, return TRUE
  130. // and place the full text of the gesture trigger into
  131. // output_str
  132. BOOL LLViewerGestureList::matchPrefix(const std::string& in_str, std::string* out_str)
  133. {
  134. S32 in_len = in_str.length();
  135. std::string in_str_lc = in_str;
  136. LLStringUtil::toLower(in_str_lc);
  137. for (S32 i = 0; i < count(); i++)
  138. {
  139. LLGesture* gesture = get(i);
  140. const std::string &trigger = gesture->getTrigger();
  141. if (in_len > (S32)trigger.length())
  142. {
  143. // too short, bail out
  144. continue;
  145. }
  146. std::string trigger_trunc = utf8str_truncate(trigger, in_len);
  147. LLStringUtil::toLower(trigger_trunc);
  148. if (in_str_lc == trigger_trunc)
  149. {
  150. *out_str = trigger;
  151. return TRUE;
  152. }
  153. }
  154. return FALSE;
  155. }
  156. // static
  157. void LLViewerGestureList::xferCallback(void *data, S32 size, void** /*user_data*/, S32 status)
  158. {
  159. if (LL_ERR_NOERR == status)
  160. {
  161. U8 *buffer = (U8 *)data;
  162. U8 *end = gGestureList.deserialize(buffer, size);
  163. if (end - buffer > size)
  164. {
  165. llerrs << "Read off of end of array, error in serialization" << llendl;
  166. }
  167. gGestureList.mIsLoaded = TRUE;
  168. }
  169. else
  170. {
  171. llwarns << "Unable to load gesture list!" << llendl;
  172. }
  173. }