PageRenderTime 42ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/indra/newview/llmediadataclient.h

https://bitbucket.org/lindenlab/viewer-beta/
C Header | 412 lines | 249 code | 83 blank | 80 comment | 9 complexity | 63971ec2a7f2b7dff3801efa2ace8d73 MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llmediadataclient.h
  3. * @brief class for queueing up requests to the media service
  4. *
  5. * $LicenseInfo:firstyear=2007&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. #ifndef LL_LLMEDIADATACLIENT_H
  27. #define LL_LLMEDIADATACLIENT_H
  28. #include "llhttpclient.h"
  29. #include <set>
  30. #include "llrefcount.h"
  31. #include "llpointer.h"
  32. #include "lleventtimer.h"
  33. // Link seam for LLVOVolume
  34. class LLMediaDataClientObject : public LLRefCount
  35. {
  36. public:
  37. // Get the number of media data items
  38. virtual U8 getMediaDataCount() const = 0;
  39. // Get the media data at index, as an LLSD
  40. virtual LLSD getMediaDataLLSD(U8 index) const = 0;
  41. // Return true if the current URL for the face in the media data matches the specified URL.
  42. virtual bool isCurrentMediaUrl(U8 index, const std::string &url) const = 0;
  43. // Get this object's UUID
  44. virtual LLUUID getID() const = 0;
  45. // Navigate back to previous URL
  46. virtual void mediaNavigateBounceBack(U8 index) = 0;
  47. // Does this object have media?
  48. virtual bool hasMedia() const = 0;
  49. // Update the object's media data to the given array
  50. virtual void updateObjectMediaData(LLSD const &media_data_array, const std::string &version_string) = 0;
  51. // Return the total "interest" of the media (on-screen area)
  52. virtual F64 getMediaInterest() const = 0;
  53. // Return the given cap url
  54. virtual std::string getCapabilityUrl(const std::string &name) const = 0;
  55. // Return whether the object has been marked dead
  56. virtual bool isDead() const = 0;
  57. // Returns a media version number for the object
  58. virtual U32 getMediaVersion() const = 0;
  59. // Returns whether the object is "interesting enough" to fetch
  60. virtual bool isInterestingEnough() const = 0;
  61. // Returns whether we've seen this object yet or not
  62. virtual bool isNew() const = 0;
  63. // smart pointer
  64. typedef LLPointer<LLMediaDataClientObject> ptr_t;
  65. };
  66. // This object creates a priority queue for requests.
  67. // Abstracts the Cap URL, the request, and the responder
  68. class LLMediaDataClient : public LLRefCount
  69. {
  70. public:
  71. LOG_CLASS(LLMediaDataClient);
  72. const static F32 QUEUE_TIMER_DELAY;// = 1.0; // seconds(s)
  73. const static F32 UNAVAILABLE_RETRY_TIMER_DELAY;// = 5.0; // secs
  74. const static U32 MAX_RETRIES;// = 4;
  75. const static U32 MAX_SORTED_QUEUE_SIZE;// = 10000;
  76. const static U32 MAX_ROUND_ROBIN_QUEUE_SIZE;// = 10000;
  77. // Constructor
  78. LLMediaDataClient(F32 queue_timer_delay = QUEUE_TIMER_DELAY,
  79. F32 retry_timer_delay = UNAVAILABLE_RETRY_TIMER_DELAY,
  80. U32 max_retries = MAX_RETRIES,
  81. U32 max_sorted_queue_size = MAX_SORTED_QUEUE_SIZE,
  82. U32 max_round_robin_queue_size = MAX_ROUND_ROBIN_QUEUE_SIZE);
  83. F32 getRetryTimerDelay() const { return mRetryTimerDelay; }
  84. // Returns true iff the queue is empty
  85. virtual bool isEmpty() const;
  86. // Returns true iff the given object is in the queue
  87. virtual bool isInQueue(const LLMediaDataClientObject::ptr_t &object);
  88. // Remove the given object from the queue. Returns true iff the given object is removed.
  89. virtual void removeFromQueue(const LLMediaDataClientObject::ptr_t &object);
  90. // Called only by the Queue timer and tests (potentially)
  91. virtual bool processQueueTimer();
  92. protected:
  93. // Destructor
  94. virtual ~LLMediaDataClient(); // use unref
  95. class Responder;
  96. // Request (pure virtual base class for requests in the queue)
  97. class Request : public LLRefCount
  98. {
  99. public:
  100. // Subclasses must implement this to build a payload for their request type.
  101. virtual LLSD getPayload() const = 0;
  102. // and must create the correct type of responder.
  103. virtual Responder *createResponder() = 0;
  104. virtual std::string getURL() { return ""; }
  105. enum Type {
  106. GET,
  107. UPDATE,
  108. NAVIGATE,
  109. ANY
  110. };
  111. protected:
  112. // The only way to create one of these is through a subclass.
  113. Request(Type in_type, LLMediaDataClientObject *obj, LLMediaDataClient *mdc, S32 face = -1);
  114. public:
  115. LLMediaDataClientObject *getObject() const { return mObject; }
  116. U32 getNum() const { return mNum; }
  117. U32 getRetryCount() const { return mRetryCount; }
  118. void incRetryCount() { mRetryCount++; }
  119. Type getType() const { return mType; }
  120. F64 getScore() const { return mScore; }
  121. // Note: may return empty string!
  122. std::string getCapability() const;
  123. const char *getCapName() const;
  124. const char *getTypeAsString() const;
  125. // Re-enqueue thyself
  126. void reEnqueue();
  127. F32 getRetryTimerDelay() const;
  128. U32 getMaxNumRetries() const;
  129. bool isObjectValid() const { return mObject.notNull() && (!mObject->isDead()); }
  130. bool isNew() const { return isObjectValid() && mObject->isNew(); }
  131. void updateScore();
  132. void markDead();
  133. bool isDead();
  134. void startTracking();
  135. void stopTracking();
  136. friend std::ostream& operator<<(std::ostream &s, const Request &q);
  137. const LLUUID &getID() const { return mObjectID; }
  138. S32 getFace() const { return mFace; }
  139. bool isMatch (const Request* other, Type match_type = ANY) const
  140. {
  141. return ((match_type == ANY) || (mType == other->mType)) &&
  142. (mFace == other->mFace) &&
  143. (mObjectID == other->mObjectID);
  144. }
  145. protected:
  146. LLMediaDataClientObject::ptr_t mObject;
  147. private:
  148. Type mType;
  149. // Simple tracking
  150. U32 mNum;
  151. static U32 sNum;
  152. U32 mRetryCount;
  153. F64 mScore;
  154. LLUUID mObjectID;
  155. S32 mFace;
  156. // Back pointer to the MDC...not a ref!
  157. LLMediaDataClient *mMDC;
  158. };
  159. typedef LLPointer<Request> request_ptr_t;
  160. // Responder
  161. class Responder : public LLHTTPClient::Responder
  162. {
  163. public:
  164. Responder(const request_ptr_t &request);
  165. //If we get back an error (not found, etc...), handle it here
  166. virtual void error(U32 status, const std::string& reason);
  167. //If we get back a normal response, handle it here. Default just logs it.
  168. virtual void result(const LLSD& content);
  169. request_ptr_t &getRequest() { return mRequest; }
  170. private:
  171. request_ptr_t mRequest;
  172. };
  173. class RetryTimer : public LLEventTimer
  174. {
  175. public:
  176. RetryTimer(F32 time, request_ptr_t);
  177. virtual BOOL tick();
  178. private:
  179. // back-pointer
  180. request_ptr_t mRequest;
  181. };
  182. protected:
  183. typedef std::list<request_ptr_t> request_queue_t;
  184. typedef std::set<request_ptr_t> request_set_t;
  185. // Subclasses must override to return a cap name
  186. virtual const char *getCapabilityName() const = 0;
  187. // Puts the request into a queue, appropriately handling duplicates, etc.
  188. virtual void enqueue(Request*) = 0;
  189. virtual void serviceQueue();
  190. virtual request_queue_t *getQueue() { return &mQueue; };
  191. // Gets the next request, removing it from the queue
  192. virtual request_ptr_t dequeue();
  193. virtual bool canServiceRequest(request_ptr_t request) { return true; };
  194. // Returns a request to the head of the queue (should only be used for requests that came from dequeue
  195. virtual void pushBack(request_ptr_t request);
  196. void trackRequest(request_ptr_t request);
  197. void stopTrackingRequest(request_ptr_t request);
  198. request_queue_t mQueue;
  199. const F32 mQueueTimerDelay;
  200. const F32 mRetryTimerDelay;
  201. const U32 mMaxNumRetries;
  202. const U32 mMaxSortedQueueSize;
  203. const U32 mMaxRoundRobinQueueSize;
  204. // Set for keeping track of requests that aren't in either queue. This includes:
  205. // Requests that have been sent and are awaiting a response (pointer held by the Responder)
  206. // Requests that are waiting for their retry timers to fire (pointer held by the retry timer)
  207. request_set_t mUnQueuedRequests;
  208. void startQueueTimer();
  209. void stopQueueTimer();
  210. private:
  211. static F64 getObjectScore(const LLMediaDataClientObject::ptr_t &obj);
  212. friend std::ostream& operator<<(std::ostream &s, const Request &q);
  213. friend std::ostream& operator<<(std::ostream &s, const request_queue_t &q);
  214. class QueueTimer : public LLEventTimer
  215. {
  216. public:
  217. QueueTimer(F32 time, LLMediaDataClient *mdc);
  218. virtual BOOL tick();
  219. private:
  220. // back-pointer
  221. LLPointer<LLMediaDataClient> mMDC;
  222. };
  223. void setIsRunning(bool val) { mQueueTimerIsRunning = val; }
  224. bool mQueueTimerIsRunning;
  225. template <typename T> friend typename T::iterator find_matching_request(T &c, const LLMediaDataClient::Request *request, LLMediaDataClient::Request::Type match_type = LLMediaDataClient::Request::ANY);
  226. template <typename T> friend typename T::iterator find_matching_request(T &c, const LLUUID &id, LLMediaDataClient::Request::Type match_type = LLMediaDataClient::Request::ANY);
  227. template <typename T> friend void remove_matching_requests(T &c, const LLUUID &id, LLMediaDataClient::Request::Type match_type = LLMediaDataClient::Request::ANY);
  228. };
  229. // MediaDataClient specific for the ObjectMedia cap
  230. class LLObjectMediaDataClient : public LLMediaDataClient
  231. {
  232. public:
  233. LOG_CLASS(LLObjectMediaDataClient);
  234. LLObjectMediaDataClient(F32 queue_timer_delay = QUEUE_TIMER_DELAY,
  235. F32 retry_timer_delay = UNAVAILABLE_RETRY_TIMER_DELAY,
  236. U32 max_retries = MAX_RETRIES,
  237. U32 max_sorted_queue_size = MAX_SORTED_QUEUE_SIZE,
  238. U32 max_round_robin_queue_size = MAX_ROUND_ROBIN_QUEUE_SIZE)
  239. : LLMediaDataClient(queue_timer_delay, retry_timer_delay, max_retries),
  240. mCurrentQueueIsTheSortedQueue(true)
  241. {}
  242. void fetchMedia(LLMediaDataClientObject *object);
  243. void updateMedia(LLMediaDataClientObject *object);
  244. class RequestGet: public Request
  245. {
  246. public:
  247. RequestGet(LLMediaDataClientObject *obj, LLMediaDataClient *mdc);
  248. /*virtual*/ LLSD getPayload() const;
  249. /*virtual*/ Responder *createResponder();
  250. };
  251. class RequestUpdate: public Request
  252. {
  253. public:
  254. RequestUpdate(LLMediaDataClientObject *obj, LLMediaDataClient *mdc);
  255. /*virtual*/ LLSD getPayload() const;
  256. /*virtual*/ Responder *createResponder();
  257. };
  258. // Returns true iff the queue is empty
  259. virtual bool isEmpty() const;
  260. // Returns true iff the given object is in the queue
  261. virtual bool isInQueue(const LLMediaDataClientObject::ptr_t &object);
  262. // Remove the given object from the queue. Returns true iff the given object is removed.
  263. virtual void removeFromQueue(const LLMediaDataClientObject::ptr_t &object);
  264. virtual bool processQueueTimer();
  265. virtual bool canServiceRequest(request_ptr_t request);
  266. protected:
  267. // Subclasses must override to return a cap name
  268. virtual const char *getCapabilityName() const;
  269. virtual request_queue_t *getQueue();
  270. // Puts the request into the appropriate queue
  271. virtual void enqueue(Request*);
  272. class Responder : public LLMediaDataClient::Responder
  273. {
  274. public:
  275. Responder(const request_ptr_t &request)
  276. : LLMediaDataClient::Responder(request) {}
  277. virtual void result(const LLSD &content);
  278. };
  279. private:
  280. // The Get/Update data client needs a second queue to avoid object updates starving load-ins.
  281. void swapCurrentQueue();
  282. request_queue_t mRoundRobinQueue;
  283. bool mCurrentQueueIsTheSortedQueue;
  284. // Comparator for sorting
  285. static bool compareRequestScores(const request_ptr_t &o1, const request_ptr_t &o2);
  286. void sortQueue();
  287. };
  288. // MediaDataClient specific for the ObjectMediaNavigate cap
  289. class LLObjectMediaNavigateClient : public LLMediaDataClient
  290. {
  291. public:
  292. LOG_CLASS(LLObjectMediaNavigateClient);
  293. // NOTE: from llmediaservice.h
  294. static const int ERROR_PERMISSION_DENIED_CODE = 8002;
  295. LLObjectMediaNavigateClient(F32 queue_timer_delay = QUEUE_TIMER_DELAY,
  296. F32 retry_timer_delay = UNAVAILABLE_RETRY_TIMER_DELAY,
  297. U32 max_retries = MAX_RETRIES,
  298. U32 max_sorted_queue_size = MAX_SORTED_QUEUE_SIZE,
  299. U32 max_round_robin_queue_size = MAX_ROUND_ROBIN_QUEUE_SIZE)
  300. : LLMediaDataClient(queue_timer_delay, retry_timer_delay, max_retries)
  301. {}
  302. void navigate(LLMediaDataClientObject *object, U8 texture_index, const std::string &url);
  303. // Puts the request into the appropriate queue
  304. virtual void enqueue(Request*);
  305. class RequestNavigate: public Request
  306. {
  307. public:
  308. RequestNavigate(LLMediaDataClientObject *obj, LLMediaDataClient *mdc, U8 texture_index, const std::string &url);
  309. /*virtual*/ LLSD getPayload() const;
  310. /*virtual*/ Responder *createResponder();
  311. /*virtual*/ std::string getURL() { return mURL; }
  312. private:
  313. std::string mURL;
  314. };
  315. protected:
  316. // Subclasses must override to return a cap name
  317. virtual const char *getCapabilityName() const;
  318. class Responder : public LLMediaDataClient::Responder
  319. {
  320. public:
  321. Responder(const request_ptr_t &request)
  322. : LLMediaDataClient::Responder(request) {}
  323. virtual void error(U32 status, const std::string& reason);
  324. virtual void result(const LLSD &content);
  325. private:
  326. void mediaNavigateBounceBack();
  327. };
  328. };
  329. #endif // LL_LLMEDIADATACLIENT_H