diff options
Diffstat (limited to 'linden/indra/newview/llmediadataclient.h')
-rw-r--r-- | linden/indra/newview/llmediadataclient.h | 341 |
1 files changed, 341 insertions, 0 deletions
diff --git a/linden/indra/newview/llmediadataclient.h b/linden/indra/newview/llmediadataclient.h new file mode 100644 index 0000000..0ed7c57 --- /dev/null +++ b/linden/indra/newview/llmediadataclient.h | |||
@@ -0,0 +1,341 @@ | |||
1 | /** | ||
2 | * @file llmediadataclient.h | ||
3 | * @brief class for queueing up requests to the media service | ||
4 | * | ||
5 | * $LicenseInfo:firstyear=2007&license=viewergpl$ | ||
6 | * | ||
7 | * Copyright (c) 2007-2010, 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://secondlife.com/developers/opensource/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://secondlife.com/developers/opensource/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 | */ | ||
33 | |||
34 | #ifndef LL_LLMEDIADATACLIENT_H | ||
35 | #define LL_LLMEDIADATACLIENT_H | ||
36 | |||
37 | #include "llhttpclient.h" | ||
38 | #include <queue> | ||
39 | //#include "llrefcount.h" | ||
40 | //#include "llpointer.h" | ||
41 | //#include "lleventtimer.h" | ||
42 | |||
43 | |||
44 | // Link seam for LLVOVolume | ||
45 | class LLMediaDataClientObject : public LLRefCount | ||
46 | { | ||
47 | public: | ||
48 | // Get the number of media data items | ||
49 | virtual U8 getMediaDataCount() const = 0; | ||
50 | // Get the media data at index, as an LLSD | ||
51 | virtual LLSD getMediaDataLLSD(U8 index) const = 0; | ||
52 | // Get this object's UUID | ||
53 | virtual LLUUID getID() const = 0; | ||
54 | // Navigate back to previous URL | ||
55 | virtual void mediaNavigateBounceBack(U8 index) = 0; | ||
56 | // Does this object have media? | ||
57 | virtual bool hasMedia() const = 0; | ||
58 | // Update the object's media data to the given array | ||
59 | virtual void updateObjectMediaData(LLSD const &media_data_array, const std::string &version_string) = 0; | ||
60 | // Return the total "interest" of the media (on-screen area) | ||
61 | virtual F64 getMediaInterest() const = 0; | ||
62 | // Return the given cap url | ||
63 | virtual std::string getCapabilityUrl(const std::string &name) const = 0; | ||
64 | // Return whether the object has been marked dead | ||
65 | virtual bool isDead() const = 0; | ||
66 | // Returns a media version number for the object | ||
67 | virtual U32 getMediaVersion() const = 0; | ||
68 | // Returns whether the object is "interesting enough" to fetch | ||
69 | virtual bool isInterestingEnough() const = 0; | ||
70 | // Returns whether we've seen this object yet or not | ||
71 | virtual bool isNew() const = 0; | ||
72 | |||
73 | // smart pointer | ||
74 | typedef LLPointer<LLMediaDataClientObject> ptr_t; | ||
75 | }; | ||
76 | |||
77 | // This object creates a priority queue for requests. | ||
78 | // Abstracts the Cap URL, the request, and the responder | ||
79 | class LLMediaDataClient : public LLRefCount | ||
80 | { | ||
81 | public: | ||
82 | LOG_CLASS(LLMediaDataClient); | ||
83 | |||
84 | const static F32 QUEUE_TIMER_DELAY;// = 1.0; // seconds(s) | ||
85 | const static F32 UNAVAILABLE_RETRY_TIMER_DELAY;// = 5.0; // secs | ||
86 | const static U32 MAX_RETRIES;// = 4; | ||
87 | const static U32 MAX_SORTED_QUEUE_SIZE;// = 10000; | ||
88 | const static U32 MAX_ROUND_ROBIN_QUEUE_SIZE;// = 10000; | ||
89 | |||
90 | // Constructor | ||
91 | LLMediaDataClient(F32 queue_timer_delay = QUEUE_TIMER_DELAY, | ||
92 | F32 retry_timer_delay = UNAVAILABLE_RETRY_TIMER_DELAY, | ||
93 | U32 max_retries = MAX_RETRIES, | ||
94 | U32 max_sorted_queue_size = MAX_SORTED_QUEUE_SIZE, | ||
95 | U32 max_round_robin_queue_size = MAX_ROUND_ROBIN_QUEUE_SIZE); | ||
96 | |||
97 | // Make the request | ||
98 | void request(const LLMediaDataClientObject::ptr_t &object, const LLSD &payload); | ||
99 | |||
100 | F32 getRetryTimerDelay() const { return mRetryTimerDelay; } | ||
101 | |||
102 | // Returns true iff the queue is empty | ||
103 | bool isEmpty() const; | ||
104 | |||
105 | // Returns true iff the given object is in the queue | ||
106 | bool isInQueue(const LLMediaDataClientObject::ptr_t &object); | ||
107 | |||
108 | // Remove the given object from the queue. Returns true iff the given object is removed. | ||
109 | bool removeFromQueue(const LLMediaDataClientObject::ptr_t &object); | ||
110 | |||
111 | // Called only by the Queue timer and tests (potentially) | ||
112 | bool processQueueTimer(); | ||
113 | |||
114 | protected: | ||
115 | // Destructor | ||
116 | virtual ~LLMediaDataClient(); // use unref | ||
117 | |||
118 | // Request | ||
119 | class Request : public LLRefCount | ||
120 | { | ||
121 | public: | ||
122 | enum Type { | ||
123 | GET, | ||
124 | UPDATE, | ||
125 | NAVIGATE, | ||
126 | ANY | ||
127 | }; | ||
128 | |||
129 | Request(const char *cap_name, const LLSD& sd_payload, LLMediaDataClientObject *obj, LLMediaDataClient *mdc); | ||
130 | const char *getCapName() const { return mCapName; } | ||
131 | const LLSD &getPayload() const { return mPayload; } | ||
132 | LLMediaDataClientObject *getObject() const { return mObject; } | ||
133 | |||
134 | U32 getNum() const { return mNum; } | ||
135 | |||
136 | U32 getRetryCount() const { return mRetryCount; } | ||
137 | void incRetryCount() { mRetryCount++; } | ||
138 | |||
139 | // Note: may return empty string! | ||
140 | std::string getCapability() const; | ||
141 | |||
142 | Type getType() const; | ||
143 | const char *getTypeAsString() const; | ||
144 | |||
145 | // Re-enqueue thyself | ||
146 | void reEnqueue() const; | ||
147 | |||
148 | F32 getRetryTimerDelay() const; | ||
149 | U32 getMaxNumRetries() const; | ||
150 | |||
151 | bool isNew() const { return mObject.notNull() ? mObject->isNew() : false; } | ||
152 | void markSent(bool flag); | ||
153 | bool isMarkedSent() const { return mMarkedSent; } | ||
154 | void updateScore(); | ||
155 | F64 getScore() const { return mScore; } | ||
156 | |||
157 | public: | ||
158 | friend std::ostream& operator<<(std::ostream &s, const Request &q); | ||
159 | |||
160 | protected: | ||
161 | virtual ~Request(); // use unref(); | ||
162 | |||
163 | private: | ||
164 | const char *mCapName; | ||
165 | LLSD mPayload; | ||
166 | LLMediaDataClientObject::ptr_t mObject; | ||
167 | // Simple tracking | ||
168 | U32 mNum; | ||
169 | static U32 sNum; | ||
170 | U32 mRetryCount; | ||
171 | F64 mScore; | ||
172 | bool mMarkedSent; | ||
173 | |||
174 | // Back pointer to the MDC...not a ref! | ||
175 | LLMediaDataClient *mMDC; | ||
176 | }; | ||
177 | typedef LLPointer<Request> request_ptr_t; | ||
178 | |||
179 | // Responder | ||
180 | class Responder : public LLHTTPClient::Responder | ||
181 | { | ||
182 | public: | ||
183 | Responder(const request_ptr_t &request); | ||
184 | //If we get back an error (not found, etc...), handle it here | ||
185 | virtual void error(U32 status, const std::string& reason); | ||
186 | //If we get back a normal response, handle it here. Default just logs it. | ||
187 | virtual void result(const LLSD& content); | ||
188 | |||
189 | const request_ptr_t &getRequest() const { return mRequest; } | ||
190 | |||
191 | protected: | ||
192 | virtual ~Responder(); | ||
193 | |||
194 | private: | ||
195 | |||
196 | class RetryTimer : public LLEventTimer | ||
197 | { | ||
198 | public: | ||
199 | RetryTimer(F32 time, Responder *); | ||
200 | virtual ~RetryTimer(); | ||
201 | virtual BOOL tick(); | ||
202 | private: | ||
203 | // back-pointer | ||
204 | boost::intrusive_ptr<Responder> mResponder; | ||
205 | }; | ||
206 | |||
207 | request_ptr_t mRequest; | ||
208 | }; | ||
209 | |||
210 | protected: | ||
211 | |||
212 | // Subclasses must override this factory method to return a new responder | ||
213 | virtual Responder *createResponder(const request_ptr_t &request) const = 0; | ||
214 | |||
215 | // Subclasses must override to return a cap name | ||
216 | virtual const char *getCapabilityName() const = 0; | ||
217 | |||
218 | virtual void sortQueue(); | ||
219 | virtual void serviceQueue(); | ||
220 | |||
221 | private: | ||
222 | typedef std::list<request_ptr_t> request_queue_t; | ||
223 | |||
224 | void enqueue(const Request*); | ||
225 | |||
226 | // Return whether the given object is/was in the queue | ||
227 | static LLMediaDataClient::request_ptr_t findOrRemove(request_queue_t &queue, const LLMediaDataClientObject::ptr_t &obj, bool remove, Request::Type type); | ||
228 | |||
229 | // Comparator for sorting | ||
230 | static bool compareRequests(const request_ptr_t &o1, const request_ptr_t &o2); | ||
231 | static F64 getObjectScore(const LLMediaDataClientObject::ptr_t &obj); | ||
232 | |||
233 | friend std::ostream& operator<<(std::ostream &s, const Request &q); | ||
234 | friend std::ostream& operator<<(std::ostream &s, const request_queue_t &q); | ||
235 | |||
236 | class QueueTimer : public LLEventTimer | ||
237 | { | ||
238 | public: | ||
239 | QueueTimer(F32 time, LLMediaDataClient *mdc); | ||
240 | virtual BOOL tick(); | ||
241 | protected: | ||
242 | virtual ~QueueTimer(); | ||
243 | private: | ||
244 | // back-pointer | ||
245 | LLPointer<LLMediaDataClient> mMDC; | ||
246 | }; | ||
247 | |||
248 | void startQueueTimer(); | ||
249 | void stopQueueTimer(); | ||
250 | void setIsRunning(bool val) { mQueueTimerIsRunning = val; } | ||
251 | |||
252 | void swapCurrentQueue(); | ||
253 | request_queue_t *getCurrentQueue(); | ||
254 | |||
255 | const F32 mQueueTimerDelay; | ||
256 | const F32 mRetryTimerDelay; | ||
257 | const U32 mMaxNumRetries; | ||
258 | const U32 mMaxSortedQueueSize; | ||
259 | const U32 mMaxRoundRobinQueueSize; | ||
260 | |||
261 | bool mQueueTimerIsRunning; | ||
262 | |||
263 | request_queue_t mSortedQueue; | ||
264 | request_queue_t mRoundRobinQueue; | ||
265 | bool mCurrentQueueIsTheSortedQueue; | ||
266 | }; | ||
267 | |||
268 | |||
269 | // MediaDataClient specific for the ObjectMedia cap | ||
270 | class LLObjectMediaDataClient : public LLMediaDataClient | ||
271 | { | ||
272 | public: | ||
273 | LLObjectMediaDataClient(F32 queue_timer_delay = QUEUE_TIMER_DELAY, | ||
274 | F32 retry_timer_delay = UNAVAILABLE_RETRY_TIMER_DELAY, | ||
275 | U32 max_retries = MAX_RETRIES, | ||
276 | U32 max_sorted_queue_size = MAX_SORTED_QUEUE_SIZE, | ||
277 | U32 max_round_robin_queue_size = MAX_ROUND_ROBIN_QUEUE_SIZE) | ||
278 | : LLMediaDataClient(queue_timer_delay, retry_timer_delay, max_retries) | ||
279 | {} | ||
280 | virtual ~LLObjectMediaDataClient() {} | ||
281 | |||
282 | void fetchMedia(LLMediaDataClientObject *object); | ||
283 | void updateMedia(LLMediaDataClientObject *object); | ||
284 | |||
285 | protected: | ||
286 | // Subclasses must override this factory method to return a new responder | ||
287 | virtual Responder *createResponder(const request_ptr_t &request) const; | ||
288 | |||
289 | // Subclasses must override to return a cap name | ||
290 | virtual const char *getCapabilityName() const; | ||
291 | |||
292 | class Responder : public LLMediaDataClient::Responder | ||
293 | { | ||
294 | public: | ||
295 | Responder(const request_ptr_t &request) | ||
296 | : LLMediaDataClient::Responder(request) {} | ||
297 | virtual void result(const LLSD &content); | ||
298 | }; | ||
299 | }; | ||
300 | |||
301 | |||
302 | // MediaDataClient specific for the ObjectMediaNavigate cap | ||
303 | class LLObjectMediaNavigateClient : public LLMediaDataClient | ||
304 | { | ||
305 | public: | ||
306 | // NOTE: from llmediaservice.h | ||
307 | static const int ERROR_PERMISSION_DENIED_CODE = 8002; | ||
308 | |||
309 | LLObjectMediaNavigateClient(F32 queue_timer_delay = QUEUE_TIMER_DELAY, | ||
310 | F32 retry_timer_delay = UNAVAILABLE_RETRY_TIMER_DELAY, | ||
311 | U32 max_retries = MAX_RETRIES, | ||
312 | U32 max_sorted_queue_size = MAX_SORTED_QUEUE_SIZE, | ||
313 | U32 max_round_robin_queue_size = MAX_ROUND_ROBIN_QUEUE_SIZE) | ||
314 | : LLMediaDataClient(queue_timer_delay, retry_timer_delay, max_retries) | ||
315 | {} | ||
316 | virtual ~LLObjectMediaNavigateClient() {} | ||
317 | |||
318 | void navigate(LLMediaDataClientObject *object, U8 texture_index, const std::string &url); | ||
319 | |||
320 | protected: | ||
321 | // Subclasses must override this factory method to return a new responder | ||
322 | virtual Responder *createResponder(const request_ptr_t &request) const; | ||
323 | |||
324 | // Subclasses must override to return a cap name | ||
325 | virtual const char *getCapabilityName() const; | ||
326 | |||
327 | class Responder : public LLMediaDataClient::Responder | ||
328 | { | ||
329 | public: | ||
330 | Responder(const request_ptr_t &request) | ||
331 | : LLMediaDataClient::Responder(request) {} | ||
332 | virtual void error(U32 status, const std::string& reason); | ||
333 | virtual void result(const LLSD &content); | ||
334 | private: | ||
335 | void mediaNavigateBounceBack(); | ||
336 | }; | ||
337 | |||
338 | }; | ||
339 | |||
340 | |||
341 | #endif // LL_LLMEDIADATACLIENT_H | ||