llgesturemgr.cpp 34 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387
  1. /**
  2. * @file llgesturemgr.cpp
  3. * @brief Manager for playing gestures on the viewer
  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 "llviewerprecompiledheaders.h"
  33. #include "boost/tokenizer.hpp"
  34. #include "llgesturemgr.h"
  35. #include "llcallbacklist.h"
  36. #include "lldatapacker.h"
  37. #include "llfilesystem.h"
  38. #include "llfloatergesture.h"
  39. #include "llinventory.h"
  40. #include "llmultigesture.h"
  41. #include "llnotifications.h"
  42. #include "llagent.h"
  43. #include "llchatbar.h"
  44. #include "llinventorymodel.h"
  45. //MK
  46. #include "mkrlinterface.h"
  47. //mk
  48. #include "llviewermessage.h" // send_sound_trigger()
  49. #include "llviewerstats.h"
  50. #include "llvoavatarself.h"
  51. LLGestureManager gGestureManager;
  52. // Longest time, in seconds, to wait for all animations to stop playing
  53. constexpr F32 MAX_WAIT_ANIM_SECS = 30.f;
  54. // Delay before notifying a failure to load a gesture
  55. constexpr F32 MAX_NAME_WAIT_TIME = 5.0f;
  56. ///////////////////////////////////////////////////////////////////////////////
  57. // LLGestureInventoryFetchObserver helper class
  58. ///////////////////////////////////////////////////////////////////////////////
  59. class LLGestureInventoryFetchObserver final : public LLInventoryFetchObserver
  60. {
  61. public:
  62. LLGestureInventoryFetchObserver()
  63. {
  64. }
  65. void done() override
  66. {
  67. // We have downloaded all the items, so refresh the floater
  68. LLFloaterGesture::refreshAll();
  69. gInventory.removeObserver(this);
  70. delete this;
  71. }
  72. };
  73. ///////////////////////////////////////////////////////////////////////////////
  74. // LLDelayedGestureError class: helper for reporting delayed load failures
  75. ///////////////////////////////////////////////////////////////////////////////
  76. class LLDelayedGestureError
  77. {
  78. public:
  79. /**
  80. * @brief Generates a missing gesture error
  81. * @param id UUID of missing gesture
  82. * Delays message for up to 5 seconds if UUID cannot be immediately
  83. * converted to a text description
  84. */
  85. static void gestureMissing(const LLUUID& id);
  86. /**
  87. * @brief Generates a gesture failed to load error
  88. * @param id UUID of missing gesture
  89. * Delays message for up to 5 seconds if UUID cannot be immediately
  90. * converted to a text description
  91. */
  92. static void gestureFailedToLoad(const LLUUID& id);
  93. private:
  94. struct LLErrorEntry
  95. {
  96. LLErrorEntry(const std::string& notify, const LLUUID& item)
  97. : mTimer(),
  98. mNotifyName(notify),
  99. mItemID(item)
  100. {
  101. }
  102. LLTimer mTimer;
  103. std::string mNotifyName;
  104. LLUUID mItemID;
  105. };
  106. static bool doDialog(const LLErrorEntry& ent, bool uuid_ok = false);
  107. static void enqueue(const LLErrorEntry& ent);
  108. static void onIdle(void* userdata);
  109. private:
  110. typedef std::list<LLErrorEntry> error_queue_t;
  111. static error_queue_t sQueue;
  112. };
  113. LLDelayedGestureError::error_queue_t LLDelayedGestureError::sQueue;
  114. //static
  115. void LLDelayedGestureError::gestureMissing(const LLUUID& id)
  116. {
  117. LLErrorEntry ent("GestureMissing", id);
  118. if (!doDialog(ent))
  119. {
  120. enqueue(ent);
  121. }
  122. }
  123. //static
  124. void LLDelayedGestureError::gestureFailedToLoad(const LLUUID& id)
  125. {
  126. LLErrorEntry ent("UnableToLoadGesture", id);
  127. if (!doDialog(ent))
  128. {
  129. enqueue(ent);
  130. }
  131. }
  132. //static
  133. void LLDelayedGestureError::enqueue(const LLErrorEntry& ent)
  134. {
  135. if (sQueue.empty())
  136. {
  137. gIdleCallbacks.addFunction(onIdle, NULL);
  138. }
  139. sQueue.emplace_back(ent);
  140. }
  141. //static
  142. void LLDelayedGestureError::onIdle(void* userdata)
  143. {
  144. if (!sQueue.empty())
  145. {
  146. LLErrorEntry ent = sQueue.front();
  147. sQueue.pop_front();
  148. if (!doDialog(ent, false))
  149. {
  150. enqueue(ent);
  151. }
  152. }
  153. else
  154. {
  155. // Nothing to do anymore
  156. gIdleCallbacks.deleteFunction(onIdle, NULL);
  157. }
  158. }
  159. //static
  160. bool LLDelayedGestureError::doDialog(const LLErrorEntry& ent, bool uuid_ok)
  161. {
  162. LLSD args;
  163. LLInventoryItem* item = gInventory.getItem(ent.mItemID);
  164. if (item)
  165. {
  166. args["NAME"] = item->getName();
  167. }
  168. else
  169. {
  170. if (uuid_ok || ent.mTimer.getElapsedTimeF32() > MAX_NAME_WAIT_TIME)
  171. {
  172. args["NAME"] = ent.mItemID.asString();
  173. }
  174. else
  175. {
  176. return false;
  177. }
  178. }
  179. gNotifications.add(ent.mNotifyName, args);
  180. return true;
  181. }
  182. ///////////////////////////////////////////////////////////////////////////////
  183. // LLGestureManager class proper
  184. ///////////////////////////////////////////////////////////////////////////////
  185. LLGestureManager::LLGestureManager()
  186. : mValid(false),
  187. mLoadingCount(0)
  188. {
  189. }
  190. // We own the data for gestures, so clean them up.
  191. LLGestureManager::~LLGestureManager()
  192. {
  193. for (item_map_t::iterator it = mActive.begin(); it != mActive.end(); ++it)
  194. {
  195. LLMultiGesture* gesturep = it->second;
  196. if (gesturep)
  197. {
  198. delete gesturep;
  199. }
  200. }
  201. }
  202. void LLGestureManager::load(const LLSD& gestures)
  203. {
  204. LL_DEBUGS("Gestures") << "Loading " << gestures.size() << " gestures."
  205. << LL_ENDL;
  206. uuid_vec_t item_ids;
  207. for (LLSD::array_const_iterator it = gestures.beginArray(),
  208. end = gestures.endArray();
  209. it != end; ++it)
  210. {
  211. const LLSD& entry = *it;
  212. LLUUID item_id;
  213. if (entry.has("item_id"))
  214. {
  215. item_id = entry["item_id"].asUUID();
  216. }
  217. if (item_id.isNull()) continue;
  218. LLUUID asset_id;
  219. if (entry.has("asset_id"))
  220. {
  221. asset_id = entry["asset_id"].asUUID();
  222. }
  223. if (asset_id.isNull()) continue;
  224. // NOTE: false, false -> do not inform server and do not deactivate
  225. // similar gesture.
  226. activateGestureWithAsset(item_id, asset_id, false, false);
  227. // We need to fetch the inventory items for these gestures so we have
  228. // the names to populate the UI.
  229. item_ids.emplace_back(item_id);
  230. }
  231. LLGestureInventoryFetchObserver* fetch =
  232. new LLGestureInventoryFetchObserver();
  233. fetch->fetchItems(item_ids);
  234. // Deletes itself when done
  235. gInventory.addObserver(fetch);
  236. }
  237. // Use this version when you have the item_id but not the asset_id, and you
  238. // KNOW the inventory is loaded.
  239. void LLGestureManager::activateGesture(const LLUUID& item_id)
  240. {
  241. LLViewerInventoryItem* item = gInventory.getItem(item_id);
  242. if (!item)
  243. {
  244. llwarns << "No item found for gesture: " << item_id << llendl;
  245. return;
  246. }
  247. LL_DEBUGS("Gestures") << "Activating gesture: " << item_id << LL_ENDL;
  248. mLoadingCount = 1;
  249. mDeactivateSimilarNames.clear();
  250. // true, false -> Inform server, do not deactivate similar gesture
  251. LLUUID asset_id = item->getAssetUUID();
  252. activateGestureWithAsset(item_id, asset_id, true, false);
  253. }
  254. void LLGestureManager::activateGestures(LLViewerInventoryItem::item_array_t& items)
  255. {
  256. LLMessageSystem* msg = gMessageSystemp;
  257. if (!msg) return; // Paranoia
  258. // Load up the assets
  259. S32 count = 0;
  260. LLViewerInventoryItem::item_array_t::const_iterator it;
  261. for (it = items.begin(); it != items.end(); ++it)
  262. {
  263. LLViewerInventoryItem* item = *it;
  264. if (!isGestureActive(item->getUUID()))
  265. {
  266. // Make gesture active and persistent through login sessions
  267. // -spatters 07-12-06
  268. activateGesture(item->getUUID());
  269. ++count;
  270. }
  271. }
  272. mLoadingCount = count;
  273. mDeactivateSimilarNames.clear();
  274. for (it = items.begin(); it != items.end(); ++it)
  275. {
  276. LLViewerInventoryItem* item = *it;
  277. if (!isGestureActive(item->getUUID()))
  278. {
  279. activateGestureWithAsset(item->getUUID(), item->getAssetUUID(),
  280. // Do not inform server, we will do that
  281. // in bulk, but do deactivate any similar
  282. // gesture.
  283. false, true);
  284. }
  285. }
  286. // Inform the database of this change
  287. bool start_message = true;
  288. for (it = items.begin(); it != items.end(); ++it)
  289. {
  290. LLViewerInventoryItem* item = *it;
  291. if (isGestureActive(item->getUUID()))
  292. {
  293. continue;
  294. }
  295. if (start_message)
  296. {
  297. msg->newMessage("ActivateGestures");
  298. msg->nextBlock("AgentData");
  299. msg->addUUID("AgentID", gAgentID);
  300. msg->addUUID("SessionID", gAgentSessionID);
  301. msg->addU32("Flags", 0x0);
  302. start_message = false;
  303. }
  304. msg->nextBlock("Data");
  305. msg->addUUID("ItemID", item->getUUID());
  306. msg->addUUID("AssetID", item->getAssetUUID());
  307. msg->addU32("GestureFlags", 0x0);
  308. if (msg->getCurrentSendTotal() > MTUBYTES)
  309. {
  310. gAgent.sendReliableMessage();
  311. start_message = true;
  312. }
  313. }
  314. if (!start_message)
  315. {
  316. gAgent.sendReliableMessage();
  317. }
  318. }
  319. struct LLLoadInfo
  320. {
  321. LLUUID mItemID;
  322. bool mInformServer;
  323. bool mDeactivateSimilar;
  324. };
  325. // If inform_server is true, will send a message upstream to update the
  326. // user_gesture_active table.
  327. void LLGestureManager::activateGestureWithAsset(const LLUUID& item_id,
  328. const LLUUID& asset_id,
  329. bool inform_server,
  330. bool deactivate_similar)
  331. {
  332. const LLUUID& base_item_id = gInventory.getLinkedItemID(item_id);
  333. if (!gAssetStoragep)
  334. {
  335. llwarns << "No valid asset storage !" << llendl;
  336. return;
  337. }
  338. // If gesture is already active, nothing to do.
  339. if (isGestureActive(base_item_id))
  340. {
  341. llwarns << "Tried to load gesture twice " << base_item_id << llendl;
  342. return;
  343. }
  344. #if 0
  345. if (asset_id.isNull())
  346. {
  347. llwarns << "Gesture has no asset !" << llendl;
  348. return;
  349. }
  350. #endif
  351. // For now, put NULL into the item map. We will build a gesture class
  352. // object when the asset data arrives.
  353. mActive[base_item_id] = NULL;
  354. // Copy the UUID
  355. if (asset_id.notNull())
  356. {
  357. LLLoadInfo* info = new LLLoadInfo;
  358. info->mItemID = base_item_id;
  359. info->mInformServer = inform_server;
  360. info->mDeactivateSimilar = deactivate_similar;
  361. gAssetStoragep->getAssetData(asset_id, LLAssetType::AT_GESTURE,
  362. onLoadComplete, (void*)info,
  363. true); // high priority
  364. }
  365. else
  366. {
  367. notifyObservers();
  368. }
  369. }
  370. void LLGestureManager::deactivateGesture(const LLUUID& item_id)
  371. {
  372. const LLUUID& base_item_id = gInventory.getLinkedItemID(item_id);
  373. item_map_t::iterator it = mActive.find(base_item_id);
  374. if (it == mActive.end())
  375. {
  376. llwarns << "Gesture " << base_item_id << " was already inactive."
  377. << llendl;
  378. return;
  379. }
  380. LL_DEBUGS("Gestures") << "Deactivating gesture: " << item_id << LL_ENDL;
  381. // mActive owns this gesture pointer, so clean up memory.
  382. LLMultiGesture* gesturep = it->second;
  383. // Can be NULL gestures in the map
  384. if (gesturep)
  385. {
  386. stopGesture(gesturep);
  387. delete gesturep;
  388. }
  389. mActive.erase(it);
  390. gInventory.addChangedMask(LLInventoryObserver::LABEL, base_item_id);
  391. // Inform the database of this change
  392. LLMessageSystem* msg = gMessageSystemp;
  393. msg->newMessage("DeactivateGestures");
  394. msg->nextBlock("AgentData");
  395. msg->addUUID("AgentID", gAgentID);
  396. msg->addUUID("SessionID", gAgentSessionID);
  397. msg->addU32("Flags", 0x0);
  398. msg->nextBlock("Data");
  399. msg->addUUID("ItemID", base_item_id);
  400. msg->addU32("GestureFlags", 0x0);
  401. gAgent.sendReliableMessage();
  402. notifyObservers();
  403. }
  404. void LLGestureManager::deactivateSimilarGestures(LLMultiGesture* in,
  405. const LLUUID& in_item_id)
  406. {
  407. const LLUUID& base_in_item_id = gInventory.getLinkedItemID(in_item_id);
  408. uuid_vec_t gest_item_ids;
  409. // Deactivate all gestures that match
  410. item_map_t::iterator it;
  411. for (it = mActive.begin(); it != mActive.end(); )
  412. {
  413. const LLUUID& item_id = it->first;
  414. LLMultiGesture* gest = it->second;
  415. // Do not deactivate the gesture we are looking for duplicates of
  416. // (for replaceGesture)
  417. if (!gest || item_id == base_in_item_id)
  418. {
  419. // legal, can have null pointers in list
  420. ++it;
  421. }
  422. else if ((!gest->mTrigger.empty() && gest->mTrigger == in->mTrigger) ||
  423. (gest->mKey != KEY_NONE && gest->mKey == in->mKey &&
  424. gest->mMask == in->mMask))
  425. {
  426. gest_item_ids.emplace_back(item_id);
  427. stopGesture(gest);
  428. delete gest;
  429. mActive.erase(it++);
  430. gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id);
  431. }
  432. else
  433. {
  434. ++it;
  435. }
  436. }
  437. if (!gest_item_ids.empty())
  438. {
  439. // Inform database of the change
  440. LLMessageSystem* msg = gMessageSystemp;
  441. bool start_message = true;
  442. for (uuid_vec_t::const_iterator it = gest_item_ids.begin(),
  443. end = gest_item_ids.end();
  444. it != end; ++it)
  445. {
  446. if (start_message)
  447. {
  448. msg->newMessage("DeactivateGestures");
  449. msg->nextBlock("AgentData");
  450. msg->addUUID("AgentID", gAgentID);
  451. msg->addUUID("SessionID", gAgentSessionID);
  452. msg->addU32("Flags", 0x0);
  453. start_message = false;
  454. }
  455. msg->nextBlock("Data");
  456. msg->addUUID("ItemID", *it);
  457. msg->addU32("GestureFlags", 0x0);
  458. if (msg->getCurrentSendTotal() > MTUBYTES)
  459. {
  460. gAgent.sendReliableMessage();
  461. start_message = true;
  462. }
  463. }
  464. if (!start_message)
  465. {
  466. gAgent.sendReliableMessage();
  467. }
  468. // Add to the list of names for the user.
  469. for (uuid_vec_t::const_iterator it = gest_item_ids.begin(),
  470. end = gest_item_ids.end();
  471. it != end; ++it)
  472. {
  473. LLViewerInventoryItem* item = gInventory.getItem(*it);
  474. if (item)
  475. {
  476. mDeactivateSimilarNames.append(item->getName());
  477. mDeactivateSimilarNames.append("\n");
  478. }
  479. }
  480. }
  481. notifyObservers();
  482. }
  483. bool LLGestureManager::isGestureActive(const LLUUID& item_id)
  484. {
  485. const LLUUID& base_item_id = gInventory.getLinkedItemID(item_id);
  486. item_map_t::iterator it = mActive.find(base_item_id);
  487. return it != mActive.end();
  488. }
  489. bool LLGestureManager::isGesturePlaying(const LLUUID& item_id)
  490. {
  491. const LLUUID& base_item_id = gInventory.getLinkedItemID(item_id);
  492. item_map_t::iterator it = mActive.find(base_item_id);
  493. if (it == mActive.end()) return false;
  494. LLMultiGesture* gesturep = it->second;
  495. return gesturep && gesturep->mPlaying;
  496. }
  497. void LLGestureManager::replaceGesture(const LLUUID& item_id,
  498. LLMultiGesture* new_gesturep,
  499. const LLUUID& asset_id)
  500. {
  501. const LLUUID& base_item_id = gInventory.getLinkedItemID(item_id);
  502. item_map_t::iterator it = mActive.find(base_item_id);
  503. if (it == mActive.end())
  504. {
  505. llwarns << "Gesture " << base_item_id
  506. << " is inactive: cannot replace !" << llendl;
  507. return;
  508. }
  509. LLMultiGesture* old_gesturep = it->second;
  510. stopGesture(old_gesturep);
  511. mActive.erase(base_item_id);
  512. mActive[base_item_id] = new_gesturep;
  513. // replaceGesture(const LLUUID& item_id, const LLUUID& new_asset_id) below
  514. // replaces Ids without replacing the gesture...
  515. if (old_gesturep != new_gesturep)
  516. {
  517. delete old_gesturep;
  518. }
  519. if (asset_id.notNull())
  520. {
  521. mLoadingCount = 1;
  522. mDeactivateSimilarNames.clear();
  523. LLLoadInfo* info = new LLLoadInfo;
  524. info->mItemID = base_item_id;
  525. info->mInformServer = true;
  526. info->mDeactivateSimilar = false;
  527. gAssetStoragep->getAssetData(asset_id, LLAssetType::AT_GESTURE,
  528. onLoadComplete, (void*)info,
  529. true); // high priority
  530. }
  531. notifyObservers();
  532. }
  533. void LLGestureManager::replaceGesture(const LLUUID& item_id,
  534. const LLUUID& new_asset_id)
  535. {
  536. const LLUUID& base_item_id = gInventory.getLinkedItemID(item_id);
  537. item_map_t::iterator it = gGestureManager.mActive.find(base_item_id);
  538. if (it == mActive.end())
  539. {
  540. llwarns << "Gesture " << base_item_id
  541. << " is inactive: cannot replace !" << llendl;
  542. return;
  543. }
  544. // mActive owns this gesture pointer, so clean up memory.
  545. LLMultiGesture* gesturep = it->second;
  546. gGestureManager.replaceGesture(base_item_id, gesturep, new_asset_id);
  547. }
  548. void LLGestureManager::playGesture(LLMultiGesture* gesturep)
  549. {
  550. if (!gesturep) return;
  551. //MK
  552. if (gRLenabled && gRLInterface.contains("sendgesture")) return;
  553. //mk
  554. // Reset gesture to first step
  555. gesturep->reset();
  556. // Add to list of playing
  557. gesturep->mPlaying = true;
  558. mPlaying.push_back(gesturep);
  559. // And get it going
  560. stepGesture(gesturep);
  561. notifyObservers();
  562. }
  563. // Convenience function that looks up the item_id for you.
  564. void LLGestureManager::playGesture(const LLUUID& item_id)
  565. {
  566. const LLUUID& base_item_id = gInventory.getLinkedItemID(item_id);
  567. item_map_t::iterator it = mActive.find(base_item_id);
  568. if (it != mActive.end())
  569. {
  570. LLMultiGesture* gesturep = it->second;
  571. if (gesturep)
  572. {
  573. playGesture(gesturep);
  574. }
  575. }
  576. }
  577. // Iterates through space delimited tokens in string, triggering any gestures
  578. // found. Generates a revised string that has the found tokens replaced by
  579. // their replacement strings and when a replacement is found (as a minor side
  580. // effect) has multiple spaces in a row replaced by single spaces.
  581. bool LLGestureManager::triggerAndReviseString(const std::string& utf8str,
  582. std::string* revised_string)
  583. {
  584. std::string tokenized = utf8str;
  585. bool found_gestures = false;
  586. bool first_token = true;
  587. typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
  588. boost::char_separator<char> sep(" ");
  589. tokenizer tokens(tokenized, sep);
  590. tokenizer::iterator token_iter;
  591. for (token_iter = tokens.begin(); token_iter != tokens.end(); ++token_iter)
  592. {
  593. const char* cur_token = token_iter->c_str();
  594. LLMultiGesture* gesturep = NULL;
  595. // Only pay attention to the first gesture in the string.
  596. if (!found_gestures)
  597. {
  598. // Collect gestures that match
  599. std::vector <LLMultiGesture*> matching;
  600. for (item_map_t::iterator it = mActive.begin(),
  601. end = mActive.end();
  602. it != end; ++it)
  603. {
  604. gesturep = it->second;
  605. // Gesture asset data might not have arrived yet
  606. if (!gesturep) continue;
  607. if (LLStringUtil::compareInsensitive(gesturep->mTrigger,
  608. cur_token) == 0)
  609. {
  610. matching.push_back(gesturep);
  611. }
  612. }
  613. gesturep = NULL;
  614. if (matching.size())
  615. {
  616. found_gestures = true;
  617. // Choose one at random
  618. S32 random = ll_rand(matching.size());
  619. gesturep = matching[random];
  620. playGesture(gesturep);
  621. if (!gesturep->mReplaceText.empty())
  622. {
  623. if (!first_token && revised_string)
  624. {
  625. revised_string->append(" ");
  626. }
  627. // Do not muck with the user's capitalization if we do not
  628. // have to.
  629. if (LLStringUtil::compareInsensitive(cur_token,
  630. gesturep->mReplaceText) == 0)
  631. {
  632. if (revised_string)
  633. {
  634. revised_string->append(cur_token);
  635. }
  636. }
  637. else if (revised_string)
  638. {
  639. revised_string->append(gesturep->mReplaceText);
  640. }
  641. }
  642. }
  643. }
  644. if (!gesturep)
  645. {
  646. // This token does not match a gesture. Pass it through to the
  647. // output.
  648. if (!first_token && revised_string)
  649. {
  650. revised_string->append(" ");
  651. }
  652. if (revised_string)
  653. {
  654. revised_string->append(cur_token);
  655. }
  656. }
  657. first_token = false;
  658. }
  659. // If no gesture is involved, restore the original text to preserve spacing
  660. if (revised_string && !found_gestures)
  661. {
  662. revised_string->assign(utf8str);
  663. }
  664. return found_gestures;
  665. }
  666. bool LLGestureManager::triggerGesture(KEY key, MASK mask)
  667. {
  668. std::vector <LLMultiGesture*> matching;
  669. // Collect matching gestures
  670. for (item_map_t::iterator it = mActive.begin(); it != mActive.end(); ++it)
  671. {
  672. LLMultiGesture* gesturep = it->second;
  673. if (gesturep && gesturep->mKey == key && gesturep->mMask == mask)
  674. {
  675. matching.push_back(gesturep);
  676. }
  677. }
  678. // Choose one and play it
  679. if (matching.size() > 0)
  680. {
  681. U32 random = ll_rand(matching.size());
  682. LLMultiGesture* gesturep = matching[random];
  683. playGesture(gesturep);
  684. return true;
  685. }
  686. return false;
  687. }
  688. S32 LLGestureManager::getPlayingCount() const
  689. {
  690. return mPlaying.size();
  691. }
  692. struct IsGesturePlaying
  693. {
  694. bool operator()(const LLMultiGesture* gesturep) const
  695. {
  696. return gesturep->mPlaying;
  697. }
  698. };
  699. void LLGestureManager::update()
  700. {
  701. for (S32 i = 0, count = mPlaying.size(); i < count; ++i)
  702. {
  703. stepGesture(mPlaying[i]);
  704. }
  705. // Clear out gestures that are done, by moving all the ones that are still
  706. // playing to the front.
  707. std::vector<LLMultiGesture*>::iterator new_end;
  708. new_end = std::partition(mPlaying.begin(), mPlaying.end(),
  709. IsGesturePlaying());
  710. // Something finished playing
  711. if (new_end != mPlaying.end())
  712. {
  713. // Delete the completed gestures that want deletion
  714. for (std::vector<LLMultiGesture*>::iterator it = new_end;
  715. it != mPlaying.end(); ++it)
  716. {
  717. LLMultiGesture* gesturep = *it;
  718. if (gesturep && gesturep->mDoneCallback)
  719. {
  720. gesturep->mDoneCallback(gesturep, gesturep->mCallbackData);
  721. }
  722. }
  723. // And take done gestures out of the playing list
  724. mPlaying.erase(new_end, mPlaying.end());
  725. notifyObservers();
  726. }
  727. }
  728. // Run all steps until you're either done or hit a wait.
  729. void LLGestureManager::stepGesture(LLMultiGesture* gesturep)
  730. {
  731. if (!gesturep || !isAgentAvatarValid())
  732. {
  733. return;
  734. }
  735. LLVOAvatar::anim_it_t play_it;
  736. // Of the ones that started playing, have any stopped ?
  737. for (uuid_list_t::iterator it = gesturep->mPlayingAnimIDs.begin();
  738. it != gesturep->mPlayingAnimIDs.end(); )
  739. {
  740. // Look in signaled animations (simulator's view of what is currently
  741. // playing.
  742. play_it = gAgentAvatarp->mSignaledAnimations.find(*it);
  743. if (play_it != gAgentAvatarp->mSignaledAnimations.end())
  744. {
  745. ++it;
  746. }
  747. else
  748. {
  749. // Not found, so not currently playing or scheduled to play: delete
  750. // from the triggered set
  751. gesturep->mPlayingAnimIDs.erase(it++);
  752. }
  753. }
  754. // Of all the animations that we asked the sim to start for us, pick up the
  755. // ones that have actually started.
  756. for (uuid_list_t::iterator it = gesturep->mRequestedAnimIDs.begin();
  757. it != gesturep->mRequestedAnimIDs.end(); )
  758. {
  759. play_it = gAgentAvatarp->mSignaledAnimations.find(*it);
  760. if (play_it != gAgentAvatarp->mSignaledAnimations.end())
  761. {
  762. // Hooray, this animation has started playing ! Copy into playing.
  763. gesturep->mPlayingAnimIDs.emplace(*it);
  764. gesturep->mRequestedAnimIDs.erase(it++);
  765. }
  766. else
  767. {
  768. // Nope, not playing yet
  769. ++it;
  770. }
  771. }
  772. // Run the current steps
  773. bool waiting = false;
  774. while (!waiting && gesturep->mPlaying)
  775. {
  776. // Get the current step, if there is one. Otherwise enter the waiting
  777. // at end state.
  778. LLGestureStep* step = NULL;
  779. if (gesturep->mCurrentStep < (S32)gesturep->mSteps.size())
  780. {
  781. step = gesturep->mSteps[gesturep->mCurrentStep];
  782. llassert(step != NULL);
  783. }
  784. else
  785. {
  786. // Step stays null, we are off the end
  787. gesturep->mWaitingAtEnd = true;
  788. }
  789. // If we are waiting at the end, wait for all gestures to stop playing.
  790. // *TODO: wait for all sounds to complete as well.
  791. if (gesturep->mWaitingAtEnd)
  792. {
  793. // Neither do we have any pending requests, nor are they still
  794. // playing.
  795. if (gesturep->mRequestedAnimIDs.empty() &&
  796. gesturep->mPlayingAnimIDs.empty())
  797. {
  798. // All animations are done playing
  799. gesturep->mWaitingAtEnd = false;
  800. gesturep->mPlaying = false;
  801. }
  802. else
  803. {
  804. waiting = true;
  805. }
  806. continue;
  807. }
  808. // If we are waiting on our animations to stop, poll for completion.
  809. if (gesturep->mWaitingAnimations)
  810. {
  811. // Neither do we have any pending requests, nor are they still
  812. // playing.
  813. if (gesturep->mRequestedAnimIDs.empty() &&
  814. gesturep->mPlayingAnimIDs.empty())
  815. {
  816. // All animations are done playing
  817. gesturep->mWaitingAnimations = false;
  818. ++gesturep->mCurrentStep;
  819. }
  820. else if (gesturep->mWaitTimer.getElapsedTimeF32() >
  821. MAX_WAIT_ANIM_SECS)
  822. {
  823. // We have waited too long for an animation
  824. llinfos << "Waited too long for animations to stop, continuing gesture."
  825. << llendl;
  826. gesturep->mWaitingAnimations = false;
  827. ++gesturep->mCurrentStep;
  828. }
  829. else
  830. {
  831. waiting = true;
  832. }
  833. continue;
  834. }
  835. // If we are waiting a fixed amount of time, check for timer expiration
  836. if (gesturep->mWaitingTimer)
  837. {
  838. // We are waiting for a certain amount of time to pass
  839. LLGestureStepWait* wait_step = (LLGestureStepWait*)step;
  840. F32 elapsed = gesturep->mWaitTimer.getElapsedTimeF32();
  841. if (elapsed > wait_step->mWaitSeconds)
  842. {
  843. // Wait is done, continue execution
  844. gesturep->mWaitingTimer = false;
  845. ++gesturep->mCurrentStep;
  846. }
  847. else
  848. {
  849. // We are waiting, so execution is done for now
  850. waiting = true;
  851. }
  852. continue;
  853. }
  854. // Not waiting, do normal execution
  855. runStep(gesturep, step);
  856. }
  857. }
  858. void LLGestureManager::runStep(LLMultiGesture* gesturep, LLGestureStep* step)
  859. {
  860. switch (step->getType())
  861. {
  862. case STEP_ANIMATION:
  863. {
  864. LLGestureStepAnimation* anim_step = (LLGestureStepAnimation*)step;
  865. if (anim_step->mAnimAssetID.isNull())
  866. {
  867. ++gesturep->mCurrentStep;
  868. }
  869. if (anim_step->mFlags & ANIM_FLAG_STOP)
  870. {
  871. gAgent.sendAnimationRequest(anim_step->mAnimAssetID,
  872. ANIM_REQUEST_STOP);
  873. // Remove it from our request set in case we just requested it
  874. uuid_list_t::iterator set_it =
  875. gesturep->mRequestedAnimIDs.find(anim_step->mAnimAssetID);
  876. if (set_it != gesturep->mRequestedAnimIDs.end())
  877. {
  878. gesturep->mRequestedAnimIDs.erase(set_it);
  879. }
  880. }
  881. else
  882. {
  883. gAgent.sendAnimationRequest(anim_step->mAnimAssetID,
  884. ANIM_REQUEST_START);
  885. // Indicate that we've requested this animation to play as
  886. // part of this gesture (but it would not start playing for at
  887. // least one round-trip to simulator).
  888. gesturep->mRequestedAnimIDs.emplace(anim_step->mAnimAssetID);
  889. }
  890. ++gesturep->mCurrentStep;
  891. break;
  892. }
  893. case STEP_SOUND:
  894. {
  895. LLGestureStepSound* sound_step = (LLGestureStepSound*)step;
  896. const LLUUID& sound_id = sound_step->mSoundAssetID;
  897. send_sound_trigger(sound_id, 1.f); // 100% relative volume
  898. ++gesturep->mCurrentStep;
  899. break;
  900. }
  901. case STEP_CHAT:
  902. {
  903. LLGestureStepChat* chat_step = (LLGestureStepChat*)step;
  904. std::string chat_text = chat_step->mChatText;
  905. // Do not animate the nodding, as this might not blend with other
  906. // playing animations.
  907. constexpr bool animate = false;
  908. //MK
  909. if (gRLenabled && gRLInterface.contains("sendchat") &&
  910. chat_text.find("/me ") != 0 && chat_text.find("/me'") != 0)
  911. {
  912. chat_text = gRLInterface.crunchEmote(chat_text, 20);
  913. }
  914. //mk
  915. if (gChatBarp)
  916. {
  917. gChatBarp->sendChatFromViewer(chat_text, CHAT_TYPE_NORMAL,
  918. animate);
  919. }
  920. ++gesturep->mCurrentStep;
  921. break;
  922. }
  923. case STEP_WAIT:
  924. {
  925. LLGestureStepWait* wait_step = (LLGestureStepWait*)step;
  926. if (wait_step->mFlags & WAIT_FLAG_TIME)
  927. {
  928. gesturep->mWaitingTimer = true;
  929. gesturep->mWaitTimer.reset();
  930. }
  931. else if (wait_step->mFlags & WAIT_FLAG_ALL_ANIM)
  932. {
  933. gesturep->mWaitingAnimations = true;
  934. // Use the wait timer as a deadlock breaker for animation
  935. // waits.
  936. gesturep->mWaitTimer.reset();
  937. }
  938. else
  939. {
  940. ++gesturep->mCurrentStep;
  941. }
  942. // Do not increment instruction pointer until wait is complete.
  943. break;
  944. }
  945. default:
  946. break;
  947. }
  948. }
  949. //static
  950. void LLGestureManager::onLoadComplete(const LLUUID& asset_uuid,
  951. LLAssetType::EType type, void* user_data,
  952. S32 status, LLExtStat)
  953. {
  954. if (!user_data) return;
  955. LLLoadInfo* info = (LLLoadInfo*)user_data;
  956. LLUUID item_id = info->mItemID;
  957. bool inform_server = info->mInformServer;
  958. bool deactivate_similar = info->mDeactivateSimilar;
  959. delete info;
  960. --gGestureManager.mLoadingCount;
  961. if (status == 0)
  962. {
  963. LLFileSystem file(asset_uuid);
  964. S32 size = file.getSize();
  965. char* buffer = (char*)malloc(size + 1);
  966. if (!buffer)
  967. {
  968. llwarns << "Memory allocation failed !" << llendl;
  969. return;
  970. }
  971. file.read((U8*)buffer, size);
  972. // ensure there's a trailing NULL so strlen will work.
  973. buffer[size] = '\0';
  974. LLMultiGesture* gesturep = new LLMultiGesture();
  975. LLDataPackerAsciiBuffer dp(buffer, size + 1);
  976. if (gesturep->deserialize(dp))
  977. {
  978. if (deactivate_similar)
  979. {
  980. gGestureManager.deactivateSimilarGestures(gesturep, item_id);
  981. // Display deactivation message if this was the last of the
  982. // bunch.
  983. if (gGestureManager.mLoadingCount == 0 &&
  984. gGestureManager.mDeactivateSimilarNames.length() > 0)
  985. {
  986. // We are done with this set of deactivations
  987. LLSD args;
  988. args["NAMES"] = gGestureManager.mDeactivateSimilarNames;
  989. gNotifications.add("DeactivatedGesturesTrigger", args);
  990. }
  991. }
  992. // Gesture may be present already...
  993. item_map_t::iterator it = gGestureManager.mActive.find(item_id);
  994. if (it != gGestureManager.mActive.end())
  995. {
  996. // In case someone manages to activate, deactivate and then
  997. // activate gesture again before the asset finishes loading...
  998. // LLLoadInfo will have a different pointer, asset storage will
  999. // see it as a different request, resulting in two callbacks.
  1000. LLMultiGesture* old_gesturep = it->second;
  1001. if (old_gesturep && old_gesturep != gesturep)
  1002. {
  1003. // deactivateSimilarGestures() did not turn this one off
  1004. // because of matching item_id.
  1005. gGestureManager.stopGesture(old_gesturep);
  1006. delete old_gesturep;
  1007. }
  1008. }
  1009. // Everything has been successful. Add to the active list.
  1010. gGestureManager.mActive[item_id] = gesturep;
  1011. gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id);
  1012. if (inform_server)
  1013. {
  1014. // Inform the database of this change
  1015. LLMessageSystem* msg = gMessageSystemp;
  1016. msg->newMessage("ActivateGestures");
  1017. msg->nextBlock("AgentData");
  1018. msg->addUUID("AgentID", gAgentID);
  1019. msg->addUUID("SessionID", gAgentSessionID);
  1020. msg->addU32("Flags", 0x0);
  1021. msg->nextBlock("Data");
  1022. msg->addUUID("ItemID", item_id);
  1023. msg->addUUID("AssetID", asset_uuid);
  1024. msg->addU32("GestureFlags", 0x0);
  1025. gAgent.sendReliableMessage();
  1026. }
  1027. gGestureManager.notifyObservers();
  1028. }
  1029. else
  1030. {
  1031. llwarns << "Unable to load gesture" << llendl;
  1032. gGestureManager.mActive.erase(item_id);
  1033. delete gesturep;
  1034. }
  1035. free((void*)buffer);
  1036. }
  1037. else
  1038. {
  1039. gViewerStats.incStat(LLViewerStats::ST_DOWNLOAD_FAILED);
  1040. notifyLoadFailed(item_id, status);
  1041. llwarns << "Problem loading gesture: " << status << llendl;
  1042. gGestureManager.mActive.erase(item_id);
  1043. }
  1044. }
  1045. //static
  1046. void LLGestureManager::notifyLoadFailed(const LLUUID& item_id, S32 status)
  1047. {
  1048. if (status == LL_ERR_FILE_EMPTY ||
  1049. status == LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE)
  1050. {
  1051. LLDelayedGestureError::gestureMissing(item_id);
  1052. }
  1053. else
  1054. {
  1055. LLDelayedGestureError::gestureFailedToLoad(item_id);
  1056. }
  1057. }
  1058. void LLGestureManager::stopGesture(LLMultiGesture* gesturep)
  1059. {
  1060. if (!gesturep) return;
  1061. // Stop any animations that this gesture is currently playing
  1062. for (uuid_list_t::iterator it = gesturep->mRequestedAnimIDs.begin(),
  1063. end = gesturep->mRequestedAnimIDs.end();
  1064. it != end; ++it)
  1065. {
  1066. const LLUUID& anim_id = *it;
  1067. gAgent.sendAnimationRequest(anim_id, ANIM_REQUEST_STOP);
  1068. }
  1069. for (uuid_list_t::iterator it = gesturep->mPlayingAnimIDs.begin(),
  1070. end = gesturep->mPlayingAnimIDs.end();
  1071. it != end; ++it)
  1072. {
  1073. const LLUUID& anim_id = *it;
  1074. gAgent.sendAnimationRequest(anim_id, ANIM_REQUEST_STOP);
  1075. }
  1076. std::vector<LLMultiGesture*>::iterator it;
  1077. it = std::find(mPlaying.begin(), mPlaying.end(), gesturep);
  1078. while (it != mPlaying.end())
  1079. {
  1080. mPlaying.erase(it);
  1081. it = std::find(mPlaying.begin(), mPlaying.end(), gesturep);
  1082. }
  1083. gesturep->reset();
  1084. if (gesturep->mDoneCallback)
  1085. {
  1086. gesturep->mDoneCallback(gesturep, gesturep->mCallbackData);
  1087. }
  1088. notifyObservers();
  1089. }
  1090. void LLGestureManager::stopGesture(const LLUUID& item_id)
  1091. {
  1092. const LLUUID& base_item_id = gInventory.getLinkedItemID(item_id);
  1093. item_map_t::iterator it = mActive.find(base_item_id);
  1094. if (it != mActive.end())
  1095. {
  1096. LLMultiGesture* gesturep = it->second;
  1097. if (gesturep)
  1098. {
  1099. stopGesture(gesturep);
  1100. }
  1101. }
  1102. }
  1103. void LLGestureManager::addObserver(LLGestureManagerObserver* observer)
  1104. {
  1105. mObservers.push_back(observer);
  1106. }
  1107. void LLGestureManager::removeObserver(LLGestureManagerObserver* observer)
  1108. {
  1109. std::vector<LLGestureManagerObserver*>::iterator it;
  1110. it = std::find(mObservers.begin(), mObservers.end(), observer);
  1111. if (it != mObservers.end())
  1112. {
  1113. mObservers.erase(it);
  1114. }
  1115. }
  1116. // Call this method when it is time to update everyone on a new state. Copy the
  1117. // list because an observer could respond by removing itself from the list.
  1118. void LLGestureManager::notifyObservers()
  1119. {
  1120. std::vector<LLGestureManagerObserver*> observers = mObservers;
  1121. std::vector<LLGestureManagerObserver*>::iterator it;
  1122. for (it = observers.begin(); it != observers.end(); ++it)
  1123. {
  1124. LLGestureManagerObserver* observer = *it;
  1125. if (observer)
  1126. {
  1127. observer->changed();
  1128. }
  1129. }
  1130. }
  1131. bool LLGestureManager::matchPrefix(const std::string& in_str,
  1132. std::string* out_str)
  1133. {
  1134. // Return whole trigger, if received text equals to it
  1135. for (item_map_t::iterator it = mActive.begin(), end = mActive.end();
  1136. it != end; ++it)
  1137. {
  1138. LLMultiGesture* gesturep = it->second;
  1139. if (gesturep)
  1140. {
  1141. const std::string& trigger = gesturep->getTrigger();
  1142. if (!LLStringUtil::compareInsensitive(in_str, trigger))
  1143. {
  1144. *out_str = trigger;
  1145. return true;
  1146. }
  1147. }
  1148. }
  1149. // Return common chars, if more than one trigger matches the prefix
  1150. std::string rest_of_match, buf;
  1151. size_t in_len = in_str.length();
  1152. for (item_map_t::iterator it = mActive.begin(), end = mActive.end();
  1153. it != end; ++it)
  1154. {
  1155. LLMultiGesture* gesturep = it->second;
  1156. if (gesturep)
  1157. {
  1158. const std::string& trigger = gesturep->getTrigger();
  1159. if (in_len > trigger.length())
  1160. {
  1161. // Too short, bail out
  1162. continue;
  1163. }
  1164. std::string trigger_trunc = trigger;
  1165. LLStringUtil::truncate(trigger_trunc, in_len);
  1166. if (!LLStringUtil::compareInsensitive(in_str, trigger_trunc))
  1167. {
  1168. if (rest_of_match.empty())
  1169. {
  1170. rest_of_match = trigger.substr(in_str.size());
  1171. }
  1172. std::string cur_rest_of_match = trigger.substr(in_str.size());
  1173. buf.clear();
  1174. S32 i = 0;
  1175. while (i < (S32)rest_of_match.length() &&
  1176. i < (S32)cur_rest_of_match.length())
  1177. {
  1178. if (rest_of_match[i] == cur_rest_of_match[i])
  1179. {
  1180. buf.push_back(rest_of_match[i]);
  1181. }
  1182. else
  1183. {
  1184. if (i == 0)
  1185. {
  1186. rest_of_match.clear();
  1187. }
  1188. break;
  1189. }
  1190. ++i;
  1191. }
  1192. if (rest_of_match.empty())
  1193. {
  1194. return false;
  1195. }
  1196. if (!buf.empty())
  1197. {
  1198. rest_of_match = buf;
  1199. }
  1200. }
  1201. }
  1202. }
  1203. if (!rest_of_match.empty())
  1204. {
  1205. *out_str = in_str + rest_of_match;
  1206. return true;
  1207. }
  1208. return false;
  1209. }
  1210. void LLGestureManager::getItemIDs(uuid_vec_t* ids)
  1211. {
  1212. for (item_map_t::const_iterator it = mActive.begin(), end = mActive.end();
  1213. it != end; ++it)
  1214. {
  1215. ids->emplace_back(it->first);
  1216. }
  1217. }