phoenix-firestorm/indra/newview/llmediadataclient.h

341 lines
11 KiB
C++
Executable File

/**
* @file llmediadataclient.h
* @brief class for queueing up requests to the media service
*
* $LicenseInfo:firstyear=2007&license=viewergpl$
*
* Copyright (c) 2007-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#ifndef LL_LLMEDIADATACLIENT_H
#define LL_LLMEDIADATACLIENT_H
#include "llhttpclient.h"
#include <queue>
#include "llrefcount.h"
#include "llpointer.h"
#include "lleventtimer.h"
// Link seam for LLVOVolume
class LLMediaDataClientObject : public LLRefCount
{
public:
// Get the number of media data items
virtual U8 getMediaDataCount() const = 0;
// Get the media data at index, as an LLSD
virtual LLSD getMediaDataLLSD(U8 index) const = 0;
// Get this object's UUID
virtual LLUUID getID() const = 0;
// Navigate back to previous URL
virtual void mediaNavigateBounceBack(U8 index) = 0;
// Does this object have media?
virtual bool hasMedia() const = 0;
// Update the object's media data to the given array
virtual void updateObjectMediaData(LLSD const &media_data_array, const std::string &version_string) = 0;
// Return the total "interest" of the media (on-screen area)
virtual F64 getMediaInterest() const = 0;
// Return the given cap url
virtual std::string getCapabilityUrl(const std::string &name) const = 0;
// Return whether the object has been marked dead
virtual bool isDead() const = 0;
// Returns a media version number for the object
virtual U32 getMediaVersion() const = 0;
// Returns whether the object is "interesting enough" to fetch
virtual bool isInterestingEnough() const = 0;
// Returns whether we've seen this object yet or not
virtual bool isNew() const = 0;
// smart pointer
typedef LLPointer<LLMediaDataClientObject> ptr_t;
};
// This object creates a priority queue for requests.
// Abstracts the Cap URL, the request, and the responder
class LLMediaDataClient : public LLRefCount
{
public:
LOG_CLASS(LLMediaDataClient);
const static F32 QUEUE_TIMER_DELAY;// = 1.0; // seconds(s)
const static F32 UNAVAILABLE_RETRY_TIMER_DELAY;// = 5.0; // secs
const static U32 MAX_RETRIES;// = 4;
const static U32 MAX_SORTED_QUEUE_SIZE;// = 10000;
const static U32 MAX_ROUND_ROBIN_QUEUE_SIZE;// = 10000;
// Constructor
LLMediaDataClient(F32 queue_timer_delay = QUEUE_TIMER_DELAY,
F32 retry_timer_delay = UNAVAILABLE_RETRY_TIMER_DELAY,
U32 max_retries = MAX_RETRIES,
U32 max_sorted_queue_size = MAX_SORTED_QUEUE_SIZE,
U32 max_round_robin_queue_size = MAX_ROUND_ROBIN_QUEUE_SIZE);
// Make the request
void request(const LLMediaDataClientObject::ptr_t &object, const LLSD &payload);
F32 getRetryTimerDelay() const { return mRetryTimerDelay; }
// Returns true iff the queue is empty
bool isEmpty() const;
// Returns true iff the given object is in the queue
bool isInQueue(const LLMediaDataClientObject::ptr_t &object);
// Remove the given object from the queue. Returns true iff the given object is removed.
bool removeFromQueue(const LLMediaDataClientObject::ptr_t &object);
// Called only by the Queue timer and tests (potentially)
bool processQueueTimer();
protected:
// Destructor
virtual ~LLMediaDataClient(); // use unref
// Request
class Request : public LLRefCount
{
public:
enum Type {
GET,
UPDATE,
NAVIGATE,
ANY
};
Request(const char *cap_name, const LLSD& sd_payload, LLMediaDataClientObject *obj, LLMediaDataClient *mdc);
const char *getCapName() const { return mCapName; }
const LLSD &getPayload() const { return mPayload; }
LLMediaDataClientObject *getObject() const { return mObject; }
U32 getNum() const { return mNum; }
U32 getRetryCount() const { return mRetryCount; }
void incRetryCount() { mRetryCount++; }
// Note: may return empty string!
std::string getCapability() const;
Type getType() const;
const char *getTypeAsString() const;
// Re-enqueue thyself
void reEnqueue() const;
F32 getRetryTimerDelay() const;
U32 getMaxNumRetries() const;
bool isNew() const { return mObject.notNull() ? mObject->isNew() : false; }
void markSent(bool flag);
bool isMarkedSent() const { return mMarkedSent; }
void updateScore();
F64 getScore() const { return mScore; }
public:
friend std::ostream& operator<<(std::ostream &s, const Request &q);
protected:
virtual ~Request(); // use unref();
private:
const char *mCapName;
LLSD mPayload;
LLMediaDataClientObject::ptr_t mObject;
// Simple tracking
U32 mNum;
static U32 sNum;
U32 mRetryCount;
F64 mScore;
bool mMarkedSent;
// Back pointer to the MDC...not a ref!
LLMediaDataClient *mMDC;
};
typedef LLPointer<Request> request_ptr_t;
// Responder
class Responder : public LLHTTPClient::Responder
{
public:
Responder(const request_ptr_t &request);
//If we get back an error (not found, etc...), handle it here
virtual void error(U32 status, const std::string& reason);
//If we get back a normal response, handle it here. Default just logs it.
virtual void result(const LLSD& content);
const request_ptr_t &getRequest() const { return mRequest; }
protected:
virtual ~Responder();
private:
class RetryTimer : public LLEventTimer
{
public:
RetryTimer(F32 time, Responder *);
virtual ~RetryTimer();
virtual BOOL tick();
private:
// back-pointer
boost::intrusive_ptr<Responder> mResponder;
};
request_ptr_t mRequest;
};
protected:
// Subclasses must override this factory method to return a new responder
virtual Responder *createResponder(const request_ptr_t &request) const = 0;
// Subclasses must override to return a cap name
virtual const char *getCapabilityName() const = 0;
virtual void sortQueue();
virtual void serviceQueue();
private:
typedef std::list<request_ptr_t> request_queue_t;
void enqueue(const Request*);
// Return whether the given object is/was in the queue
static LLMediaDataClient::request_ptr_t findOrRemove(request_queue_t &queue, const LLMediaDataClientObject::ptr_t &obj, bool remove, Request::Type type);
// Comparator for sorting
static bool compareRequests(const request_ptr_t &o1, const request_ptr_t &o2);
static F64 getObjectScore(const LLMediaDataClientObject::ptr_t &obj);
friend std::ostream& operator<<(std::ostream &s, const Request &q);
friend std::ostream& operator<<(std::ostream &s, const request_queue_t &q);
class QueueTimer : public LLEventTimer
{
public:
QueueTimer(F32 time, LLMediaDataClient *mdc);
virtual BOOL tick();
protected:
virtual ~QueueTimer();
private:
// back-pointer
LLPointer<LLMediaDataClient> mMDC;
};
void startQueueTimer();
void stopQueueTimer();
void setIsRunning(bool val) { mQueueTimerIsRunning = val; }
void swapCurrentQueue();
request_queue_t *getCurrentQueue();
const F32 mQueueTimerDelay;
const F32 mRetryTimerDelay;
const U32 mMaxNumRetries;
const U32 mMaxSortedQueueSize;
const U32 mMaxRoundRobinQueueSize;
bool mQueueTimerIsRunning;
request_queue_t mSortedQueue;
request_queue_t mRoundRobinQueue;
bool mCurrentQueueIsTheSortedQueue;
};
// MediaDataClient specific for the ObjectMedia cap
class LLObjectMediaDataClient : public LLMediaDataClient
{
public:
LLObjectMediaDataClient(F32 queue_timer_delay = QUEUE_TIMER_DELAY,
F32 retry_timer_delay = UNAVAILABLE_RETRY_TIMER_DELAY,
U32 max_retries = MAX_RETRIES,
U32 max_sorted_queue_size = MAX_SORTED_QUEUE_SIZE,
U32 max_round_robin_queue_size = MAX_ROUND_ROBIN_QUEUE_SIZE)
: LLMediaDataClient(queue_timer_delay, retry_timer_delay, max_retries)
{}
virtual ~LLObjectMediaDataClient() {}
void fetchMedia(LLMediaDataClientObject *object);
void updateMedia(LLMediaDataClientObject *object);
protected:
// Subclasses must override this factory method to return a new responder
virtual Responder *createResponder(const request_ptr_t &request) const;
// Subclasses must override to return a cap name
virtual const char *getCapabilityName() const;
class Responder : public LLMediaDataClient::Responder
{
public:
Responder(const request_ptr_t &request)
: LLMediaDataClient::Responder(request) {}
virtual void result(const LLSD &content);
};
};
// MediaDataClient specific for the ObjectMediaNavigate cap
class LLObjectMediaNavigateClient : public LLMediaDataClient
{
public:
// NOTE: from llmediaservice.h
static const int ERROR_PERMISSION_DENIED_CODE = 8002;
LLObjectMediaNavigateClient(F32 queue_timer_delay = QUEUE_TIMER_DELAY,
F32 retry_timer_delay = UNAVAILABLE_RETRY_TIMER_DELAY,
U32 max_retries = MAX_RETRIES,
U32 max_sorted_queue_size = MAX_SORTED_QUEUE_SIZE,
U32 max_round_robin_queue_size = MAX_ROUND_ROBIN_QUEUE_SIZE)
: LLMediaDataClient(queue_timer_delay, retry_timer_delay, max_retries)
{}
virtual ~LLObjectMediaNavigateClient() {}
void navigate(LLMediaDataClientObject *object, U8 texture_index, const std::string &url);
protected:
// Subclasses must override this factory method to return a new responder
virtual Responder *createResponder(const request_ptr_t &request) const;
// Subclasses must override to return a cap name
virtual const char *getCapabilityName() const;
class Responder : public LLMediaDataClient::Responder
{
public:
Responder(const request_ptr_t &request)
: LLMediaDataClient::Responder(request) {}
virtual void error(U32 status, const std::string& reason);
virtual void result(const LLSD &content);
private:
void mediaNavigateBounceBack();
};
};
#endif // LL_LLMEDIADATACLIENT_H