Merge branch 'master' of github.com:singularity-viewer/SingularityViewer
This commit is contained in:
82
doc/responders.txt
Normal file
82
doc/responders.txt
Normal file
@@ -0,0 +1,82 @@
|
||||
All Responders are derived from ResponderBase, however you normally do never derived from that directly yourself.
|
||||
Instead, Responder classes are derived from one of:
|
||||
|
||||
1. Responder base classes
|
||||
|
||||
ResponderHeadersOnly -- Derived classes are used with HTTPClient::head or HTTPClient::getHeaderOnly.
|
||||
ResponderWithCompleted -- Derived classes implement completed(U32, std::string const&, LLSD const&),
|
||||
or completedRaw(U32, std::string const&, LLChannelDescriptors const&, buffer_ptr_t const&)
|
||||
if the response is not (always) LLSD.
|
||||
ResponderWithResult -- Derived classes implement result(LLSD const&) and optionally
|
||||
errorWithContent(U32, std::string const&, LLSD const&) OR error(U32, std::string const&).
|
||||
|
||||
2. Special base classes
|
||||
|
||||
ResponderIgnoreBody -- Same as ResponderWithResult but already implements result() that ignored the body.
|
||||
LLAssetUploadResponder -- Derived from ResponderWithResult. Base class for responders that upload assets via capabilities.
|
||||
LegacyPolledResponder -- Used for old code that needs polling (do not use).
|
||||
|
||||
|
||||
There is one non-base class Responder with a more general purpose:
|
||||
|
||||
3. Special purpose responders:
|
||||
|
||||
ResponderIgnore -- Derived from ResponderIgnoreBody. Used for "fire and forget" requests as it ignores any response.
|
||||
|
||||
|
||||
4. Signatures.
|
||||
|
||||
Every final (derived) responder class must implement 'getName(void) const' and 'getHTTPTimeoutPolicy(void)',
|
||||
except the base classes (this is to alert the developer they have to implement getName as it is pure virtual).
|
||||
|
||||
For example:
|
||||
|
||||
extern AIHTTPTimeoutPolicy myResponder_timeout; // Add 'P(myResponder)' to indra/llmessage/aihttptimeoutpolicy.cpp.
|
||||
|
||||
class MyResponder : public LLHTTPClient::SomeResponderBaseClass {
|
||||
...
|
||||
/*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return myResponder_timeout; }
|
||||
/*virtual*/ char const* getName(void) const { return "MyResponder"; }
|
||||
};
|
||||
|
||||
Note the convention that the name of a AIHTTPTimeoutPolicy (what goes between the brackets of P()) is
|
||||
the class name minus any 'AI' or 'LL' prefix and starting with a lowercase character.
|
||||
|
||||
Then, depending on the three main base classes that was derived from, the signatures should be:
|
||||
|
||||
class MyResponder1 : public LLHTTPClient::ResponderHeadersOnly {
|
||||
/*virtual*/ void completedHeaders(U32 status, std::string const& reason, AIHTTPReceivedHeaders const& headers);
|
||||
// See for example PostImageResponder
|
||||
...
|
||||
};
|
||||
|
||||
class MyResponder2 : public LLHTTPClient::ResponderWithCompleted {
|
||||
/*virtual*/ void completedRaw(U32 status, std::string const& reason, LLChannelDescriptors const& channels, buffer_ptr_t const& buffer);
|
||||
// See for example PostImageRedirectResponder
|
||||
>>>OR<<<
|
||||
|
||||
/*virtual*/ void completed(U32 status, const std::string& reason, const LLSD& content); // See for example LLImportPostResponder
|
||||
|
||||
};
|
||||
|
||||
class MyResponder3 : public LLHTTPClient::ResponderWithResult {
|
||||
/*virtual*/ void result(const LLSD& content); // See for example LLInventoryModelFetchItemResponder
|
||||
/*virtual*/ void error(U32 status, const std::string& reason);
|
||||
>>>OR instead error()<<<
|
||||
/*virtual*/ void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
|
||||
// See for example LLSDMessage::EventResponder
|
||||
};
|
||||
|
||||
Finally, if a responder derived from ResponderWithCompleted or ResponderWithResult needs to process
|
||||
individual headers, you need to override 'needsHeaders':
|
||||
|
||||
/*virtual*/ bool needsHeaders(void) const { return true; } // See for example LLWebProfileResponders::PostImageResponder
|
||||
// which will cause this to be called:
|
||||
/*virtual*/ void completedHeaders(U32 status, std::string const& reason, AIHTTPReceivedHeaders const& headers);
|
||||
|
||||
And if it needs redirection to work (you'll get an assert if you forget this and it is being redirected):
|
||||
|
||||
/*virtual*/ bool followRedir(void) const { return true; } // See for example LLWebProfileResponders::ConfigResponder
|
||||
|
||||
This is not necessary for ResponderHeadersOnly because that already defines both.
|
||||
|
||||
@@ -562,8 +562,10 @@ namespace dc
|
||||
fake_channel const warning(1, "WARNING ");
|
||||
fake_channel const curl(1, "CURL ");
|
||||
fake_channel const curlio(1, "CURLIO ");
|
||||
fake_channel const curltr(1, "CURLTR ");
|
||||
fake_channel const statemachine(1, "STATEMACHINE");
|
||||
fake_channel const notice(1, "NOTICE ");
|
||||
fake_channel const snapshot(0, "SNAPSHOT ");
|
||||
|
||||
} // namespace dc
|
||||
} // namespace debug
|
||||
|
||||
@@ -82,8 +82,10 @@ struct fake_channel {
|
||||
extern LL_COMMON_API fake_channel const warning;
|
||||
extern LL_COMMON_API fake_channel const curl;
|
||||
extern LL_COMMON_API fake_channel const curlio;
|
||||
extern LL_COMMON_API fake_channel const curltr;
|
||||
extern LL_COMMON_API fake_channel const statemachine;
|
||||
extern LL_COMMON_API fake_channel const notice;
|
||||
extern LL_COMMON_API fake_channel const snapshot;
|
||||
|
||||
} // namespace dc
|
||||
} // namespace debug
|
||||
@@ -173,8 +175,8 @@ extern LL_COMMON_API fake_channel const notice;
|
||||
#include <boost/shared_array.hpp>
|
||||
#if CWDEBUG_LOCATION
|
||||
#include <execinfo.h> // Needed for 'backtrace'.
|
||||
#include "llpreprocessor.h"
|
||||
#endif
|
||||
#include "llpreprocessor.h" // LL_COMMON_API
|
||||
#include <set>
|
||||
|
||||
#define CWD_API __attribute__ ((visibility("default")))
|
||||
@@ -387,21 +389,21 @@ void InstanceTracker<T>::dump(void)
|
||||
// Print "Entering " << \a data to channel \a cntrl and increment
|
||||
// debugging output indentation until the end of the current scope.
|
||||
#define DoutEntering(cntrl, data) \
|
||||
int __slviewer_debug_indentation = 2; \
|
||||
int __slviewer_debug_indentation = 2; \
|
||||
{ \
|
||||
LIBCWD_TSD_DECLARATION; \
|
||||
if (LIBCWD_DO_TSD_MEMBER_OFF(::libcwd::libcw_do) < 0) \
|
||||
{ \
|
||||
::libcwd::channel_set_bootstrap_st __libcwd_channel_set(LIBCWD_DO_TSD(::libcwd::libcw_do) LIBCWD_COMMA_TSD); \
|
||||
bool on; \
|
||||
bool __slviewer_debug_on; \
|
||||
{ \
|
||||
using namespace LIBCWD_DEBUGCHANNELS; \
|
||||
on = (__libcwd_channel_set|cntrl).on; \
|
||||
__slviewer_debug_on = (__libcwd_channel_set|cntrl).on; \
|
||||
} \
|
||||
if (on) \
|
||||
if (__slviewer_debug_on) \
|
||||
Dout(cntrl, "Entering " << data); \
|
||||
else \
|
||||
__slviewer_debug_indentation = 0; \
|
||||
__slviewer_debug_indentation = 0; \
|
||||
} \
|
||||
} \
|
||||
debug::Indent __slviewer_debug_indent(__slviewer_debug_indentation);
|
||||
|
||||
@@ -76,6 +76,7 @@ protected:
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
LL_ALIGN_PREFIX(16)
|
||||
class LLDriverParam : public LLViewerVisualParam
|
||||
{
|
||||
friend class LLPhysicsMotion;
|
||||
@@ -133,13 +134,13 @@ protected:
|
||||
void setDrivenWeight(LLDrivenEntry *driven, F32 driven_weight, bool upload_bake);
|
||||
|
||||
|
||||
LLVector4a mDefaultVec; // temp holder
|
||||
LL_ALIGN_16(LLVector4a mDefaultVec); // temp holder
|
||||
typedef std::vector<LLDrivenEntry> entry_list_t;
|
||||
entry_list_t mDriven;
|
||||
LLViewerVisualParam* mCurrentDistortionParam;
|
||||
// Backlink only; don't make this an LLPointer.
|
||||
LLAvatarAppearance* mAvatarAppearance;
|
||||
LLWearable* mWearablep;
|
||||
};
|
||||
} LL_ALIGN_POSTFIX(16);
|
||||
|
||||
#endif // LL_LLDRIVERPARAM_H
|
||||
|
||||
@@ -41,6 +41,7 @@ class LLWearable;
|
||||
//-----------------------------------------------------------------------------
|
||||
// LLPolyMorphData()
|
||||
//-----------------------------------------------------------------------------
|
||||
LL_ALIGN_PREFIX(16)
|
||||
class LLPolyMorphData
|
||||
{
|
||||
public:
|
||||
@@ -79,12 +80,13 @@ public:
|
||||
|
||||
F32 mTotalDistortion; // vertex distortion summed over entire morph
|
||||
F32 mMaxDistortion; // maximum single vertex distortion in a given morph
|
||||
LLVector4a mAvgDistortion; // average vertex distortion, to infer directionality of the morph
|
||||
LL_ALIGN_16(LLVector4a mAvgDistortion); // average vertex distortion, to infer directionality of the morph
|
||||
LLPolyMeshSharedData* mMesh;
|
||||
|
||||
private:
|
||||
void freeData();
|
||||
};
|
||||
} LL_ALIGN_POSTFIX(16);
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// LLPolyVertexMask()
|
||||
|
||||
@@ -63,6 +63,7 @@ struct LLPolySkeletalBoneInfo
|
||||
BOOL mHasPositionDeformation;
|
||||
};
|
||||
|
||||
LL_ALIGN_PREFIX(16)
|
||||
class LLPolySkeletalDistortionInfo : public LLViewerVisualParamInfo
|
||||
{
|
||||
friend class LLPolySkeletalDistortion;
|
||||
@@ -118,13 +119,13 @@ public:
|
||||
/*virtual*/ const LLVector4a* getNextDistortion(U32 *index, LLPolyMesh **poly_mesh){index = 0; poly_mesh = NULL; return NULL;};
|
||||
|
||||
protected:
|
||||
LL_ALIGN_16(LLVector4a mDefaultVec);
|
||||
typedef std::map<LLJoint*, LLVector3> joint_vec_map_t;
|
||||
joint_vec_map_t mJointScales;
|
||||
joint_vec_map_t mJointOffsets;
|
||||
LLVector4a mDefaultVec;
|
||||
// Backlink only; don't make this an LLPointer.
|
||||
LLAvatarAppearance *mAvatar;
|
||||
};
|
||||
} LL_ALIGN_POSTFIX(16);
|
||||
|
||||
#endif // LL_LLPOLYSKELETALDISTORTION_H
|
||||
|
||||
|
||||
@@ -60,6 +60,7 @@ protected:
|
||||
// LLTexLayerParamAlpha
|
||||
//
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
LL_ALIGN_PREFIX(16)
|
||||
class LLTexLayerParamAlpha : public LLTexLayerParam
|
||||
{
|
||||
public:
|
||||
@@ -67,8 +68,6 @@ public:
|
||||
LLTexLayerParamAlpha( LLAvatarAppearance* appearance );
|
||||
/*virtual*/ ~LLTexLayerParamAlpha();
|
||||
|
||||
/*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable = NULL) const;
|
||||
|
||||
void* operator new(size_t size)
|
||||
{
|
||||
return ll_aligned_malloc_16(size);
|
||||
@@ -79,6 +78,8 @@ public:
|
||||
ll_aligned_free_16(ptr);
|
||||
}
|
||||
|
||||
/*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable = NULL) const;
|
||||
|
||||
// LLVisualParam Virtual functions
|
||||
///*virtual*/ BOOL parseData(LLXmlTreeNode* node);
|
||||
/*virtual*/ void apply( ESex avatar_sex ) {}
|
||||
@@ -106,7 +107,7 @@ private:
|
||||
LLPointer<LLImageRaw> mStaticImageRaw;
|
||||
BOOL mNeedsCreateTexture;
|
||||
BOOL mStaticImageInvalid;
|
||||
LLVector4a mAvgDistortionVec;
|
||||
LL_ALIGN_16(LLVector4a mAvgDistortionVec);
|
||||
F32 mCachedEffectiveWeight;
|
||||
|
||||
public:
|
||||
@@ -116,7 +117,7 @@ public:
|
||||
|
||||
typedef std::list< LLTexLayerParamAlpha* > param_alpha_ptr_list_t;
|
||||
static param_alpha_ptr_list_t sInstances;
|
||||
};
|
||||
} LL_ALIGN_POSTFIX(16);
|
||||
class LLTexLayerParamAlphaInfo : public LLViewerVisualParamInfo
|
||||
{
|
||||
friend class LLTexLayerParamAlpha;
|
||||
@@ -140,6 +141,8 @@ private:
|
||||
// LLTexLayerParamColor
|
||||
//
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
LL_ALIGN_PREFIX(16)
|
||||
class LLTexLayerParamColor : public LLTexLayerParam
|
||||
{
|
||||
public:
|
||||
@@ -153,7 +156,6 @@ public:
|
||||
|
||||
LLTexLayerParamColor( LLTexLayerInterface* layer );
|
||||
LLTexLayerParamColor( LLAvatarAppearance* appearance );
|
||||
/* virtual */ ~LLTexLayerParamColor();
|
||||
|
||||
void* operator new(size_t size)
|
||||
{
|
||||
@@ -165,6 +167,8 @@ public:
|
||||
ll_aligned_free_16(ptr);
|
||||
}
|
||||
|
||||
/* virtual */ ~LLTexLayerParamColor();
|
||||
|
||||
/*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable = NULL) const;
|
||||
|
||||
// LLVisualParam Virtual functions
|
||||
@@ -188,8 +192,8 @@ public:
|
||||
protected:
|
||||
virtual void onGlobalColorChanged(bool upload_bake) {}
|
||||
private:
|
||||
LLVector4a mAvgDistortionVec;
|
||||
};
|
||||
LL_ALIGN_16(LLVector4a mAvgDistortionVec);
|
||||
} LL_ALIGN_POSTFIX(16);
|
||||
|
||||
class LLTexLayerParamColorInfo : public LLViewerVisualParamInfo
|
||||
{
|
||||
|
||||
@@ -66,6 +66,7 @@ protected:
|
||||
// VIRTUAL CLASS
|
||||
// a viewer side interface class for a generalized parametric modification of the avatar mesh
|
||||
//-----------------------------------------------------------------------------
|
||||
LL_ALIGN_PREFIX(16)
|
||||
class LLViewerVisualParam : public LLVisualParam
|
||||
{
|
||||
public:
|
||||
@@ -106,6 +107,6 @@ public:
|
||||
|
||||
BOOL getCrossWearable() const { return getInfo()->mCrossWearable; }
|
||||
|
||||
};
|
||||
} LL_ALIGN_POSTFIX(16);
|
||||
|
||||
#endif // LL_LLViewerVisualParam_H
|
||||
|
||||
@@ -106,9 +106,9 @@
|
||||
// on a compiler that doesn't need this hack.
|
||||
#define AI_NEED_ACCESS_CC (defined(__GNUC__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ < 3)) || (__GNUC__ < 4)))
|
||||
|
||||
template<typename T> struct AIReadAccessConst;
|
||||
template<typename T> struct AIReadAccess;
|
||||
template<typename T> struct AIWriteAccess;
|
||||
template<typename T, typename RWLOCK> struct AIReadAccessConst;
|
||||
template<typename T, typename RWLOCK> struct AIReadAccess;
|
||||
template<typename T, typename RWLOCK> struct AIWriteAccess;
|
||||
template<typename T, typename MUTEX> struct AIAccessConst;
|
||||
template<typename T, typename MUTEX> struct AIAccess;
|
||||
template<typename T> struct AISTAccessConst;
|
||||
@@ -225,17 +225,17 @@ protected:
|
||||
* </code>
|
||||
*
|
||||
*/
|
||||
template<typename T>
|
||||
template<typename T, typename RWLOCK = AIRWLock>
|
||||
class AIThreadSafe : public AIThreadSafeBits<T>
|
||||
{
|
||||
protected:
|
||||
// Only these may access the object (through ptr()).
|
||||
friend struct AIReadAccessConst<T>;
|
||||
friend struct AIReadAccess<T>;
|
||||
friend struct AIWriteAccess<T>;
|
||||
friend struct AIReadAccessConst<T, RWLOCK>;
|
||||
friend struct AIReadAccess<T, RWLOCK>;
|
||||
friend struct AIWriteAccess<T, RWLOCK>;
|
||||
|
||||
// Locking control.
|
||||
AIRWLock mRWLock;
|
||||
RWLOCK mRWLock;
|
||||
|
||||
// For use by AIThreadSafeDC
|
||||
AIThreadSafe(void) { }
|
||||
@@ -310,20 +310,20 @@ public:
|
||||
*
|
||||
* which is not possible with AITHREADSAFE.
|
||||
*/
|
||||
template<typename T>
|
||||
class AIThreadSafeDC : public AIThreadSafe<T>
|
||||
template<typename T, typename RWLOCK = AIRWLock>
|
||||
class AIThreadSafeDC : public AIThreadSafe<T, RWLOCK>
|
||||
{
|
||||
public:
|
||||
// Construct a wrapper around a default constructed object.
|
||||
AIThreadSafeDC(void) { new (AIThreadSafe<T>::ptr()) T; }
|
||||
AIThreadSafeDC(void) { new (AIThreadSafe<T, RWLOCK>::ptr()) T; }
|
||||
// Allow an arbitrary parameter to be passed for construction.
|
||||
template<typename T2> AIThreadSafeDC(T2 const& val) { new (AIThreadSafe<T>::ptr()) T(val); }
|
||||
template<typename T2> AIThreadSafeDC(T2 const& val) { new (AIThreadSafe<T, RWLOCK>::ptr()) T(val); }
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Read lock object and provide read access.
|
||||
*/
|
||||
template<typename T>
|
||||
template<typename T, typename RWLOCK = AIRWLock>
|
||||
struct AIReadAccessConst
|
||||
{
|
||||
//! Internal enum for the lock-type of the AI*Access object.
|
||||
@@ -336,8 +336,8 @@ struct AIReadAccessConst
|
||||
};
|
||||
|
||||
//! Construct a AIReadAccessConst from a constant AIThreadSafe.
|
||||
AIReadAccessConst(AIThreadSafe<T> const& wrapper, bool high_priority = false)
|
||||
: mWrapper(const_cast<AIThreadSafe<T>&>(wrapper)),
|
||||
AIReadAccessConst(AIThreadSafe<T, RWLOCK> const& wrapper, bool high_priority = false)
|
||||
: mWrapper(const_cast<AIThreadSafe<T, RWLOCK>&>(wrapper)),
|
||||
mState(readlocked)
|
||||
#if AI_NEED_ACCESS_CC
|
||||
, mIsCopyConstructed(false)
|
||||
@@ -369,14 +369,14 @@ struct AIReadAccessConst
|
||||
|
||||
protected:
|
||||
//! Constructor used by AIReadAccess.
|
||||
AIReadAccessConst(AIThreadSafe<T>& wrapper, state_type state)
|
||||
AIReadAccessConst(AIThreadSafe<T, RWLOCK>& wrapper, state_type state)
|
||||
: mWrapper(wrapper), mState(state)
|
||||
#if AI_NEED_ACCESS_CC
|
||||
, mIsCopyConstructed(false)
|
||||
#endif
|
||||
{ }
|
||||
|
||||
AIThreadSafe<T>& mWrapper; //!< Reference to the object that we provide access to.
|
||||
AIThreadSafe<T, RWLOCK>& mWrapper; //!< Reference to the object that we provide access to.
|
||||
state_type const mState; //!< The lock state that mWrapper is in.
|
||||
|
||||
#if AI_NEED_ACCESS_CC
|
||||
@@ -393,39 +393,39 @@ private:
|
||||
/**
|
||||
* @brief Read lock object and provide read access, with possible promotion to write access.
|
||||
*/
|
||||
template<typename T>
|
||||
struct AIReadAccess : public AIReadAccessConst<T>
|
||||
template<typename T, typename RWLOCK = AIRWLock>
|
||||
struct AIReadAccess : public AIReadAccessConst<T, RWLOCK>
|
||||
{
|
||||
typedef typename AIReadAccessConst<T>::state_type state_type;
|
||||
using AIReadAccessConst<T>::readlocked;
|
||||
typedef typename AIReadAccessConst<T, RWLOCK>::state_type state_type;
|
||||
using AIReadAccessConst<T, RWLOCK>::readlocked;
|
||||
|
||||
//! Construct a AIReadAccess from a non-constant AIThreadSafe.
|
||||
AIReadAccess(AIThreadSafe<T>& wrapper, bool high_priority = false) : AIReadAccessConst<T>(wrapper, readlocked) { this->mWrapper.mRWLock.rdlock(high_priority); }
|
||||
AIReadAccess(AIThreadSafe<T, RWLOCK>& wrapper, bool high_priority = false) : AIReadAccessConst<T, RWLOCK>(wrapper, readlocked) { this->mWrapper.mRWLock.rdlock(high_priority); }
|
||||
|
||||
protected:
|
||||
//! Constructor used by AIWriteAccess.
|
||||
AIReadAccess(AIThreadSafe<T>& wrapper, state_type state) : AIReadAccessConst<T>(wrapper, state) { }
|
||||
AIReadAccess(AIThreadSafe<T, RWLOCK>& wrapper, state_type state) : AIReadAccessConst<T, RWLOCK>(wrapper, state) { }
|
||||
|
||||
friend struct AIWriteAccess<T>;
|
||||
friend struct AIWriteAccess<T, RWLOCK>;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Write lock object and provide read/write access.
|
||||
*/
|
||||
template<typename T>
|
||||
struct AIWriteAccess : public AIReadAccess<T>
|
||||
template<typename T, typename RWLOCK = AIRWLock>
|
||||
struct AIWriteAccess : public AIReadAccess<T, RWLOCK>
|
||||
{
|
||||
using AIReadAccessConst<T>::readlocked;
|
||||
using AIReadAccessConst<T>::read2writelocked;
|
||||
using AIReadAccessConst<T>::writelocked;
|
||||
using AIReadAccessConst<T>::write2writelocked;
|
||||
using AIReadAccessConst<T, RWLOCK>::readlocked;
|
||||
using AIReadAccessConst<T, RWLOCK>::read2writelocked;
|
||||
using AIReadAccessConst<T, RWLOCK>::writelocked;
|
||||
using AIReadAccessConst<T, RWLOCK>::write2writelocked;
|
||||
|
||||
//! Construct a AIWriteAccess from a non-constant AIThreadSafe.
|
||||
AIWriteAccess(AIThreadSafe<T>& wrapper) : AIReadAccess<T>(wrapper, writelocked) { this->mWrapper.mRWLock.wrlock();}
|
||||
AIWriteAccess(AIThreadSafe<T, RWLOCK>& wrapper) : AIReadAccess<T, RWLOCK>(wrapper, writelocked) { this->mWrapper.mRWLock.wrlock();}
|
||||
|
||||
//! Promote read access to write access.
|
||||
explicit AIWriteAccess(AIReadAccess<T>& access)
|
||||
: AIReadAccess<T>(access.mWrapper, (access.mState == readlocked) ? read2writelocked : write2writelocked)
|
||||
explicit AIWriteAccess(AIReadAccess<T, RWLOCK>& access)
|
||||
: AIReadAccess<T, RWLOCK>(access.mWrapper, (access.mState == readlocked) ? read2writelocked : write2writelocked)
|
||||
{
|
||||
if (this->mState == read2writelocked)
|
||||
{
|
||||
|
||||
@@ -35,28 +35,6 @@
|
||||
DECLARE_bool(heap_profile_use_stack_trace);
|
||||
//DECLARE_double(tcmalloc_release_rate);
|
||||
|
||||
// static
|
||||
void LLAllocator::pushMemType(S32 type)
|
||||
{
|
||||
if(isProfiling())
|
||||
{
|
||||
PushMemType(type);
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
S32 LLAllocator::popMemType()
|
||||
{
|
||||
if (isProfiling())
|
||||
{
|
||||
return PopMemType();
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
void LLAllocator::setProfilingEnabled(bool should_enable)
|
||||
{
|
||||
// NULL disables dumping to disk
|
||||
@@ -94,17 +72,6 @@ std::string LLAllocator::getRawProfile()
|
||||
// stub implementations for when tcmalloc is disabled
|
||||
//
|
||||
|
||||
// static
|
||||
void LLAllocator::pushMemType(S32 type)
|
||||
{
|
||||
}
|
||||
|
||||
// static
|
||||
S32 LLAllocator::popMemType()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
void LLAllocator::setProfilingEnabled(bool should_enable)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -29,16 +29,10 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "llmemtype.h"
|
||||
#include "llallocator_heap_profile.h"
|
||||
|
||||
class LL_COMMON_API LLAllocator {
|
||||
friend class LLMemoryView;
|
||||
friend class LLMemType;
|
||||
|
||||
private:
|
||||
static void pushMemType(S32 type);
|
||||
static S32 popMemType();
|
||||
|
||||
public:
|
||||
void setProfilingEnabled(bool should_enable);
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include <vector>
|
||||
#include <boost/function.hpp>
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
#include <boost/type_traits/is_enum.hpp>
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
@@ -224,32 +225,81 @@ namespace LLInitParam
|
||||
typedef std::map<const std::type_info*, parser_write_func_t> parser_write_func_map_t;
|
||||
typedef std::map<const std::type_info*, parser_inspect_func_t> parser_inspect_func_map_t;
|
||||
|
||||
private:
|
||||
template<typename T, bool is_enum = boost::is_enum<T>::value>
|
||||
struct ReaderWriter
|
||||
{
|
||||
static bool read(T& param, Parser* parser)
|
||||
{
|
||||
parser_read_func_map_t::iterator found_it = parser->mParserReadFuncs->find(&typeid(T));
|
||||
if (found_it != parser->mParserReadFuncs->end())
|
||||
{
|
||||
return found_it->second(*parser, (void*)¶m);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool write(const T& param, Parser* parser, name_stack_t& name_stack)
|
||||
{
|
||||
parser_write_func_map_t::iterator found_it = parser->mParserWriteFuncs->find(&typeid(T));
|
||||
if (found_it != parser->mParserWriteFuncs->end())
|
||||
{
|
||||
return found_it->second(*parser, (const void*)¶m, name_stack);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
// read enums as ints
|
||||
template<typename T>
|
||||
struct ReaderWriter<T, true>
|
||||
{
|
||||
static bool read(T& param, Parser* parser)
|
||||
{
|
||||
// read all enums as ints
|
||||
parser_read_func_map_t::iterator found_it = parser->mParserReadFuncs->find(&typeid(S32));
|
||||
if (found_it != parser->mParserReadFuncs->end())
|
||||
{
|
||||
S32 value;
|
||||
if (found_it->second(*parser, (void*)&value))
|
||||
{
|
||||
param = (T)value;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool write(const T& param, Parser* parser, name_stack_t& name_stack)
|
||||
{
|
||||
parser_write_func_map_t::iterator found_it = parser->mParserWriteFuncs->find(&typeid(S32));
|
||||
if (found_it != parser->mParserWriteFuncs->end())
|
||||
{
|
||||
return found_it->second(*parser, (const void*)¶m, name_stack);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
Parser(parser_read_func_map_t& read_map, parser_write_func_map_t& write_map, parser_inspect_func_map_t& inspect_map)
|
||||
: mParseSilently(false),
|
||||
mParserReadFuncs(&read_map),
|
||||
mParserWriteFuncs(&write_map),
|
||||
mParserInspectFuncs(&inspect_map)
|
||||
{}
|
||||
|
||||
virtual ~Parser();
|
||||
|
||||
template <typename T> bool readValue(T& param)
|
||||
{
|
||||
parser_read_func_map_t::iterator found_it = mParserReadFuncs->find(&typeid(T));
|
||||
if (found_it != mParserReadFuncs->end())
|
||||
{
|
||||
return found_it->second(*this, (void*)¶m);
|
||||
}
|
||||
return false;
|
||||
return ReaderWriter<T>::read(param, this);
|
||||
}
|
||||
|
||||
template <typename T> bool writeValue(const T& param, name_stack_t& name_stack)
|
||||
{
|
||||
parser_write_func_map_t::iterator found_it = mParserWriteFuncs->find(&typeid(T));
|
||||
if (found_it != mParserWriteFuncs->end())
|
||||
{
|
||||
return found_it->second(*this, (const void*)¶m, name_stack);
|
||||
}
|
||||
return false;
|
||||
return ReaderWriter<T>::write(param, this, name_stack);
|
||||
}
|
||||
|
||||
// dispatch inspection to registered inspection functions, for each parameter in a param block
|
||||
@@ -841,31 +891,25 @@ namespace LLInitParam
|
||||
self_t& typed_param = static_cast<self_t&>(param);
|
||||
// no further names in stack, attempt to parse value now
|
||||
if (name_stack_range.first == name_stack_range.second)
|
||||
{
|
||||
if (parser.readValue(typed_param.getValue()))
|
||||
{
|
||||
std::string name;
|
||||
|
||||
// try to parse a known named value
|
||||
if(name_value_lookup_t::valueNamesExist()
|
||||
&& parser.readValue(name)
|
||||
&& name_value_lookup_t::getValueFromName(name, typed_param.getValue()))
|
||||
{
|
||||
typed_param.setValueName(name);
|
||||
typed_param.setProvided();
|
||||
return true;
|
||||
}
|
||||
// try to read value directly
|
||||
else if (parser.readValue(typed_param.getValue()))
|
||||
{
|
||||
typed_param.clearValueName();
|
||||
typed_param.setProvided();
|
||||
return true;
|
||||
}
|
||||
|
||||
// try to parse a known named value
|
||||
if(name_value_lookup_t::valueNamesExist())
|
||||
{
|
||||
// try to parse a known named value
|
||||
std::string name;
|
||||
if (parser.readValue(name))
|
||||
{
|
||||
// try to parse a per type named value
|
||||
if (name_value_lookup_t::getValueFromName(name, typed_param.getValue()))
|
||||
{
|
||||
typed_param.setValueName(name);
|
||||
typed_param.setProvided();
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -987,30 +1031,29 @@ namespace LLInitParam
|
||||
static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack_range, bool new_name)
|
||||
{
|
||||
self_t& typed_param = static_cast<self_t&>(param);
|
||||
// attempt to parse block...
|
||||
|
||||
if (name_stack_range.first == name_stack_range.second)
|
||||
{ // try to parse a known named value
|
||||
std::string name;
|
||||
|
||||
if(name_value_lookup_t::valueNamesExist()
|
||||
&& parser.readValue(name)
|
||||
&& name_value_lookup_t::getValueFromName(name, typed_param.getValue()))
|
||||
{
|
||||
typed_param.setValueName(name);
|
||||
typed_param.setProvided();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if(typed_param.deserializeBlock(parser, name_stack_range, new_name))
|
||||
{
|
||||
{ // attempt to parse block...
|
||||
typed_param.clearValueName();
|
||||
typed_param.setProvided();
|
||||
return true;
|
||||
}
|
||||
|
||||
if(name_value_lookup_t::valueNamesExist())
|
||||
{
|
||||
// try to parse a known named value
|
||||
std::string name;
|
||||
if (parser.readValue(name))
|
||||
{
|
||||
// try to parse a per type named value
|
||||
if (name_value_lookup_t::getValueFromName(name, typed_param.getValue()))
|
||||
{
|
||||
typed_param.setValueName(name);
|
||||
typed_param.setProvided();
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1160,31 +1203,23 @@ namespace LLInitParam
|
||||
value_t value;
|
||||
// no further names in stack, attempt to parse value now
|
||||
if (name_stack_range.first == name_stack_range.second)
|
||||
{
|
||||
// attempt to read value directly
|
||||
if (parser.readValue(value))
|
||||
{
|
||||
std::string name;
|
||||
|
||||
// try to parse a known named value
|
||||
if(name_value_lookup_t::valueNamesExist()
|
||||
&& parser.readValue(name)
|
||||
&& name_value_lookup_t::getValueFromName(name, value))
|
||||
{
|
||||
typed_param.add(value);
|
||||
typed_param.mValues.back().setValueName(name);
|
||||
return true;
|
||||
}
|
||||
else if (parser.readValue(value)) // attempt to read value directly
|
||||
{
|
||||
typed_param.add(value);
|
||||
return true;
|
||||
}
|
||||
|
||||
// try to parse a known named value
|
||||
if(name_value_lookup_t::valueNamesExist())
|
||||
{
|
||||
// try to parse a known named value
|
||||
std::string name;
|
||||
if (parser.readValue(name))
|
||||
{
|
||||
// try to parse a per type named value
|
||||
if (name_value_lookup_t::getValueFromName(name, value))
|
||||
{
|
||||
typed_param.add(value);
|
||||
typed_param.mValues.back().setValueName(name);
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -1362,28 +1397,27 @@ namespace LLInitParam
|
||||
|
||||
param_value_t& value = typed_param.mValues.back();
|
||||
|
||||
if (name_stack_range.first == name_stack_range.second)
|
||||
{ // try to parse a known named value
|
||||
std::string name;
|
||||
|
||||
if(name_value_lookup_t::valueNamesExist()
|
||||
&& parser.readValue(name)
|
||||
&& name_value_lookup_t::getValueFromName(name, value.getValue()))
|
||||
{
|
||||
typed_param.mValues.back().setValueName(name);
|
||||
typed_param.setProvided();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// attempt to parse block...
|
||||
if(value.deserializeBlock(parser, name_stack_range, new_name))
|
||||
{
|
||||
typed_param.setProvided();
|
||||
return true;
|
||||
}
|
||||
else if(name_value_lookup_t::valueNamesExist())
|
||||
{
|
||||
// try to parse a known named value
|
||||
std::string name;
|
||||
if (parser.readValue(name))
|
||||
{
|
||||
// try to parse a per type named value
|
||||
if (name_value_lookup_t::getValueFromName(name, value.getValue()))
|
||||
{
|
||||
typed_param.mValues.back().setValueName(name);
|
||||
typed_param.setProvided();
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (new_value)
|
||||
{ // failed to parse new value, pop it off
|
||||
|
||||
@@ -27,7 +27,9 @@
|
||||
#include "llmemtype.h"
|
||||
#include "llallocator.h"
|
||||
|
||||
#if MEM_TRACK_TYPE
|
||||
std::vector<char const *> LLMemType::DeclareMemType::mNameList;
|
||||
#endif
|
||||
|
||||
LLMemType::DeclareMemType LLMemType::MTYPE_INIT("Init");
|
||||
LLMemType::DeclareMemType LLMemType::MTYPE_STARTUP("Startup");
|
||||
@@ -194,7 +196,7 @@ LLMemType::DeclareMemType LLMemType::MTYPE_TEMP9("Temp9");
|
||||
|
||||
LLMemType::DeclareMemType LLMemType::MTYPE_OTHER("Other");
|
||||
|
||||
|
||||
#if MEM_TRACK_TYPE
|
||||
LLMemType::DeclareMemType::DeclareMemType(char const * st)
|
||||
{
|
||||
mID = (S32)mNameList.size();
|
||||
@@ -229,3 +231,4 @@ char const * LLMemType::getNameFromID(S32 id)
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
#endif //MEM_TRACK_TYPE
|
||||
@@ -52,6 +52,10 @@ public:
|
||||
class LL_COMMON_API DeclareMemType
|
||||
{
|
||||
public:
|
||||
|
||||
#if !MEM_TRACK_TYPE
|
||||
DeclareMemType(char const * st) {}; //Do nothing
|
||||
#else
|
||||
DeclareMemType(char const * st);
|
||||
~DeclareMemType();
|
||||
|
||||
@@ -60,12 +64,17 @@ public:
|
||||
|
||||
// array so we can map an index ID to Name
|
||||
static std::vector<char const *> mNameList;
|
||||
#endif
|
||||
};
|
||||
|
||||
#if !MEM_TRACK_TYPE
|
||||
LLMemType(DeclareMemType& dt){} //Do nothing
|
||||
#else
|
||||
LLMemType(DeclareMemType& dt);
|
||||
~LLMemType();
|
||||
|
||||
static char const * getNameFromID(S32 id);
|
||||
#endif
|
||||
|
||||
static DeclareMemType MTYPE_INIT;
|
||||
static DeclareMemType MTYPE_STARTUP;
|
||||
@@ -232,7 +241,9 @@ public:
|
||||
|
||||
static DeclareMemType MTYPE_OTHER; // Special; used by display code
|
||||
|
||||
#if MEM_TRACK_TYPE
|
||||
S32 mTypeIndex;
|
||||
#endif
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
@@ -598,7 +598,7 @@ bool llsd_equals(const LLSD& lhs, const LLSD& rhs, unsigned bits)
|
||||
case LLSD::TypeReal:
|
||||
// This is where the 'bits' argument comes in handy. If passed
|
||||
// explicitly, it means to use is_approx_equal_fraction() to compare.
|
||||
if (bits >= 0)
|
||||
if (bits != -1)
|
||||
{
|
||||
return is_approx_equal_fraction(lhs.asReal(), rhs.asReal(), bits);
|
||||
}
|
||||
|
||||
@@ -226,7 +226,7 @@ void LLSingleton<DERIVED_TYPE>::createInstance(SingletonInstanceData& data)
|
||||
|
||||
if (data.mInitState == INITIALIZING)
|
||||
{
|
||||
llwarns << "Tried to access singleton " << typeid(DERIVED_TYPE).name() << " from initSingleton(), using half-initialized object" << llendl;
|
||||
lldebugs << "Tried to access singleton " << typeid(DERIVED_TYPE).name() << " from initSingleton(), using half-initialized object" << llendl;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -27,294 +27,52 @@
|
||||
#ifndef LL_LLSTAT_H
|
||||
#define LL_LLSTAT_H
|
||||
|
||||
#include <deque>
|
||||
#include <map>
|
||||
|
||||
#include "lltimer.h"
|
||||
#include "llframetimer.h"
|
||||
#include "llfile.h"
|
||||
|
||||
class LLSD;
|
||||
|
||||
// Set this if longer stats are needed
|
||||
#define ENABLE_LONG_TIME_STATS 0
|
||||
|
||||
//
|
||||
// Accumulates statistics for an arbitrary length of time.
|
||||
// Does this by maintaining a chain of accumulators, each one
|
||||
// accumulation the results of the parent. Can scale to arbitrary
|
||||
// amounts of time with very low memory cost.
|
||||
//
|
||||
|
||||
class LL_COMMON_API LLStatAccum
|
||||
{
|
||||
protected:
|
||||
LLStatAccum(bool use_frame_timer);
|
||||
virtual ~LLStatAccum();
|
||||
|
||||
public:
|
||||
enum TimeScale {
|
||||
SCALE_100MS,
|
||||
SCALE_SECOND,
|
||||
SCALE_MINUTE,
|
||||
#if ENABLE_LONG_TIME_STATS
|
||||
SCALE_HOUR,
|
||||
SCALE_DAY,
|
||||
SCALE_WEEK,
|
||||
#endif
|
||||
NUM_SCALES, // Use to size storage arrays
|
||||
SCALE_PER_FRAME // For latest frame information - should be after NUM_SCALES since this doesn't go into the time buckets
|
||||
};
|
||||
|
||||
static U64 sScaleTimes[NUM_SCALES];
|
||||
|
||||
virtual F32 meanValue(TimeScale scale) const;
|
||||
// see the subclasses for the specific meaning of value
|
||||
|
||||
F32 meanValueOverLast100ms() const { return meanValue(SCALE_100MS); }
|
||||
F32 meanValueOverLastSecond() const { return meanValue(SCALE_SECOND); }
|
||||
F32 meanValueOverLastMinute() const { return meanValue(SCALE_MINUTE); }
|
||||
|
||||
void reset(U64 when);
|
||||
|
||||
void sum(F64 value);
|
||||
void sum(F64 value, U64 when);
|
||||
|
||||
U64 getCurrentUsecs() const;
|
||||
// Get current microseconds based on timer type
|
||||
|
||||
BOOL mUseFrameTimer;
|
||||
BOOL mRunning;
|
||||
|
||||
U64 mLastTime;
|
||||
|
||||
struct Bucket
|
||||
{
|
||||
Bucket() :
|
||||
accum(0.0),
|
||||
endTime(0),
|
||||
lastValid(false),
|
||||
lastAccum(0.0)
|
||||
{}
|
||||
|
||||
F64 accum;
|
||||
U64 endTime;
|
||||
|
||||
bool lastValid;
|
||||
F64 lastAccum;
|
||||
};
|
||||
|
||||
Bucket mBuckets[NUM_SCALES];
|
||||
|
||||
BOOL mLastSampleValid;
|
||||
F64 mLastSampleValue;
|
||||
};
|
||||
|
||||
class LL_COMMON_API LLStatMeasure : public LLStatAccum
|
||||
// gathers statistics about things that are measured
|
||||
// ex.: tempature, time dilation
|
||||
{
|
||||
public:
|
||||
LLStatMeasure(bool use_frame_timer = true);
|
||||
|
||||
void sample(F64);
|
||||
void sample(S32 v) { sample((F64)v); }
|
||||
void sample(U32 v) { sample((F64)v); }
|
||||
void sample(S64 v) { sample((F64)v); }
|
||||
void sample(U64 v) { sample((F64)v); }
|
||||
};
|
||||
|
||||
|
||||
class LL_COMMON_API LLStatRate : public LLStatAccum
|
||||
// gathers statistics about things that can be counted over time
|
||||
// ex.: LSL instructions executed, messages sent, simulator frames completed
|
||||
// renders it in terms of rate of thing per second
|
||||
{
|
||||
public:
|
||||
LLStatRate(bool use_frame_timer = true);
|
||||
|
||||
void count(U32);
|
||||
// used to note that n items have occured
|
||||
|
||||
void mark();
|
||||
// used for counting the rate thorugh a point in the code
|
||||
};
|
||||
|
||||
|
||||
class LL_COMMON_API LLStatTime : public LLStatAccum
|
||||
// gathers statistics about time spent in a block of code
|
||||
// measure average duration per second in the block
|
||||
{
|
||||
public:
|
||||
LLStatTime( const std::string & key = "undefined" );
|
||||
|
||||
U32 mFrameNumber; // Current frame number
|
||||
U64 mTotalTimeInFrame; // Total time (microseconds) accumulated during the last frame
|
||||
|
||||
void setKey( const std::string & key ) { mKey = key; };
|
||||
|
||||
virtual F32 meanValue(TimeScale scale) const;
|
||||
|
||||
private:
|
||||
void start(); // Start and stop measuring time block
|
||||
void stop();
|
||||
|
||||
std::string mKey; // Tag representing this time block
|
||||
|
||||
#if LL_DEBUG
|
||||
BOOL mRunning; // TRUE if start() has been called
|
||||
#endif
|
||||
|
||||
friend class LLPerfBlock;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
|
||||
// Use this class on the stack to record statistics about an area of code
|
||||
class LL_COMMON_API LLPerfBlock
|
||||
{
|
||||
public:
|
||||
struct StatEntry
|
||||
{
|
||||
StatEntry(const std::string& key) : mStat(LLStatTime(key)), mCount(0) {}
|
||||
LLStatTime mStat;
|
||||
U32 mCount;
|
||||
};
|
||||
typedef std::map<std::string, StatEntry*> stat_map_t;
|
||||
|
||||
// Use this constructor for pre-defined LLStatTime objects
|
||||
LLPerfBlock(LLStatTime* stat);
|
||||
|
||||
// Use this constructor for normal, optional LLPerfBlock time slices
|
||||
LLPerfBlock( const char* key );
|
||||
|
||||
// Use this constructor for dynamically created LLPerfBlock time slices
|
||||
// that are only enabled by specific control flags
|
||||
LLPerfBlock( const char* key1, const char* key2, S32 flags = LLSTATS_BASIC_STATS );
|
||||
|
||||
~LLPerfBlock();
|
||||
|
||||
enum
|
||||
{ // Stats bitfield flags
|
||||
LLSTATS_NO_OPTIONAL_STATS = 0x00, // No optional stats gathering, just pre-defined LLStatTime objects
|
||||
LLSTATS_BASIC_STATS = 0x01, // Gather basic optional runtime stats
|
||||
LLSTATS_SCRIPT_FUNCTIONS = 0x02, // Include LSL function calls
|
||||
};
|
||||
static void setStatsFlags( S32 flags ) { sStatsFlags = flags; };
|
||||
static S32 getStatsFlags() { return sStatsFlags; };
|
||||
|
||||
static void clearDynamicStats(); // Reset maps to clear out dynamic objects
|
||||
static void addStatsToLLSDandReset( LLSD & stats, // Get current information and clear time bin
|
||||
LLStatAccum::TimeScale scale );
|
||||
|
||||
private:
|
||||
// Initialize dynamically created LLStatTime objects
|
||||
void initDynamicStat(const std::string& key);
|
||||
|
||||
std::string mLastPath; // Save sCurrentStatPath when this is called
|
||||
LLStatTime * mPredefinedStat; // LLStatTime object to get data
|
||||
StatEntry * mDynamicStat; // StatEntryobject to get data
|
||||
|
||||
static S32 sStatsFlags; // Control what is being recorded
|
||||
static stat_map_t sStatMap; // Map full path string to LLStatTime objects
|
||||
static std::string sCurrentStatPath; // Something like "frame/physics/physics step"
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
class LL_COMMON_API LLPerfStats
|
||||
{
|
||||
public:
|
||||
LLPerfStats(const std::string& process_name = "unknown", S32 process_pid = 0);
|
||||
virtual ~LLPerfStats();
|
||||
|
||||
virtual void init(); // Reset and start all stat timers
|
||||
virtual void updatePerFrameStats();
|
||||
// Override these function to add process-specific information to the performance log header and per-frame logging.
|
||||
virtual void addProcessHeaderInfo(LLSD& info) { /* not implemented */ }
|
||||
virtual void addProcessFrameInfo(LLSD& info, LLStatAccum::TimeScale scale) { /* not implemented */ }
|
||||
|
||||
// High-resolution frame stats
|
||||
BOOL frameStatsIsRunning() { return (mReportPerformanceStatEnd > 0.); };
|
||||
F32 getReportPerformanceInterval() const { return mReportPerformanceStatInterval; };
|
||||
void setReportPerformanceInterval( F32 interval ) { mReportPerformanceStatInterval = interval; };
|
||||
void setReportPerformanceDuration( F32 seconds, S32 flags = LLPerfBlock::LLSTATS_NO_OPTIONAL_STATS );
|
||||
void setProcessName(const std::string& process_name) { mProcessName = process_name; }
|
||||
void setProcessPID(S32 process_pid) { mProcessPID = process_pid; }
|
||||
|
||||
protected:
|
||||
void openPerfStatsFile(); // Open file for high resolution metrics logging
|
||||
void dumpIntervalPerformanceStats();
|
||||
|
||||
llofstream mFrameStatsFile; // File for per-frame stats
|
||||
BOOL mFrameStatsFileFailure; // Flag to prevent repeat opening attempts
|
||||
BOOL mSkipFirstFrameStats; // Flag to skip one (partial) frame report
|
||||
std::string mProcessName;
|
||||
S32 mProcessPID;
|
||||
|
||||
private:
|
||||
F32 mReportPerformanceStatInterval; // Seconds between performance stats
|
||||
F64 mReportPerformanceStatEnd; // End time (seconds) for performance stats
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
class LL_COMMON_API LLStat
|
||||
{
|
||||
private:
|
||||
typedef std::multimap<std::string, LLStat*> stat_map_t;
|
||||
|
||||
void init();
|
||||
static stat_map_t& getStatList();
|
||||
|
||||
public:
|
||||
LLStat(U32 num_bins = 32, BOOL use_frame_timer = FALSE);
|
||||
LLStat(std::string name, U32 num_bins = 32, BOOL use_frame_timer = FALSE);
|
||||
LLStat(std::string name = std::string(), S32 num_bins = 32, BOOL use_frame_timer = FALSE);
|
||||
~LLStat();
|
||||
|
||||
void reset();
|
||||
|
||||
void start(); // Start the timer for the current "frame", otherwise uses the time tracked from
|
||||
// the last addValue
|
||||
void reset();
|
||||
void addValue(const F32 value = 1.f); // Adds the current value being tracked, and tracks the DT.
|
||||
void addValue(const S32 value) { addValue((F32)value); }
|
||||
void addValue(const U32 value) { addValue((F32)value); }
|
||||
|
||||
void setBeginTime(const F64 time);
|
||||
void addValueTime(const F64 time, const F32 value = 1.f);
|
||||
|
||||
S32 getCurBin() const;
|
||||
S32 getNextBin() const;
|
||||
|
||||
F32 getCurrent() const;
|
||||
F32 getCurrentPerSec() const;
|
||||
F64 getCurrentBeginTime() const;
|
||||
F64 getCurrentTime() const;
|
||||
F32 getCurrentDuration() const;
|
||||
|
||||
F32 getPrev(S32 age) const; // Age is how many "addValues" previously - zero is current
|
||||
F32 getPrevPerSec(S32 age) const; // Age is how many "addValues" previously - zero is current
|
||||
F32 getCurrent() const;
|
||||
F32 getCurrentPerSec() const;
|
||||
F32 getCurrentDuration() const;
|
||||
|
||||
F64 getPrevBeginTime(S32 age) const;
|
||||
F64 getPrevTime(S32 age) const;
|
||||
|
||||
F32 getBin(S32 bin) const;
|
||||
F32 getBinPerSec(S32 bin) const;
|
||||
F64 getBinBeginTime(S32 bin) const;
|
||||
F64 getBinTime(S32 bin) const;
|
||||
|
||||
F32 getMax() const;
|
||||
F32 getMaxPerSec() const;
|
||||
|
||||
F32 getMean() const;
|
||||
F32 getMeanPerSec() const;
|
||||
F32 getMeanDuration() const;
|
||||
|
||||
F32 getMin() const;
|
||||
F32 getMinPerSec() const;
|
||||
F32 getMinDuration() const;
|
||||
|
||||
F32 getSum() const;
|
||||
F32 getSumDuration() const;
|
||||
F32 getMean() const;
|
||||
F32 getMeanPerSec() const;
|
||||
F32 getMeanDuration() const;
|
||||
F32 getMax() const;
|
||||
F32 getMaxPerSec() const;
|
||||
|
||||
U32 getNumValues() const;
|
||||
S32 getNumBins() const;
|
||||
@@ -326,10 +84,21 @@ private:
|
||||
U32 mNumBins;
|
||||
F32 mLastValue;
|
||||
F64 mLastTime;
|
||||
F32 *mBins;
|
||||
F64 *mBeginTime;
|
||||
F64 *mTime;
|
||||
F32 *mDT;
|
||||
|
||||
struct ValueEntry
|
||||
{
|
||||
ValueEntry()
|
||||
: mValue(0.f),
|
||||
mBeginTime(0.0),
|
||||
mTime(0.0),
|
||||
mDT(0.f)
|
||||
{}
|
||||
F32 mValue;
|
||||
F64 mBeginTime;
|
||||
F64 mTime;
|
||||
F32 mDT;
|
||||
};
|
||||
ValueEntry* mBins;
|
||||
S32 mCurBin;
|
||||
S32 mNextBin;
|
||||
|
||||
|
||||
@@ -63,6 +63,13 @@ enum
|
||||
LL_SIM_STAT_SIMSPARETIME = 32,
|
||||
LL_SIM_STAT_SIMSLEEPTIME = 33,
|
||||
LL_SIM_STAT_IOPUMPTIME = 34,
|
||||
LL_SIM_STAT_PCTSCRIPTSRUN = 35,
|
||||
LL_SIM_STAT_REGION_IDLE = 36, // dataserver only
|
||||
LL_SIM_STAT_REGION_IDLE_POSSIBLE = 37, // dataserver only
|
||||
LL_SIM_STAT_SIMAISTEPTIMEMS = 38,
|
||||
LL_SIM_STAT_SKIPPEDAISILSTEPS_PS = 39,
|
||||
LL_SIM_STAT_PCTSTEPPEDCHARACTERS = 40
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -24,6 +24,10 @@
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#if LL_WINDOWS
|
||||
#pragma warning (disable : 4355) // 'this' used in initializer list: yes, intentionally
|
||||
#endif
|
||||
|
||||
#include "linden_common.h"
|
||||
|
||||
#include "llsys.h"
|
||||
@@ -36,22 +40,45 @@
|
||||
#endif
|
||||
|
||||
#include "llprocessor.h"
|
||||
#include "llerrorcontrol.h"
|
||||
#include "llevents.h"
|
||||
#include "lltimer.h"
|
||||
#include "llsdserialize.h"
|
||||
#include "llsdutil.h"
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/circular_buffer.hpp>
|
||||
#include <boost/regex.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/range.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <boost/type_traits/is_integral.hpp>
|
||||
#include <boost/type_traits/is_float.hpp>
|
||||
|
||||
using namespace llsd;
|
||||
|
||||
#if LL_WINDOWS
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# include <winsock2.h>
|
||||
# include <windows.h>
|
||||
# include <psapi.h> // GetPerformanceInfo() et al.
|
||||
#elif LL_DARWIN
|
||||
# include <errno.h>
|
||||
# include <sys/sysctl.h>
|
||||
# include <sys/utsname.h>
|
||||
# include <stdint.h>
|
||||
# include <Carbon/Carbon.h>
|
||||
# include <stdexcept>
|
||||
# include <mach/host_info.h>
|
||||
# include <mach/mach_host.h>
|
||||
# include <mach/task.h>
|
||||
# include <mach/task_info.h>
|
||||
#elif LL_LINUX
|
||||
# include <errno.h>
|
||||
# include <sys/utsname.h>
|
||||
# include <unistd.h>
|
||||
# include <sys/sysinfo.h>
|
||||
# include <stdexcept>
|
||||
const char MEMINFO_FILE[] = "/proc/meminfo";
|
||||
#elif LL_SOLARIS
|
||||
# include <stdio.h>
|
||||
@@ -70,6 +97,15 @@ extern int errno;
|
||||
static const S32 CPUINFO_BUFFER_SIZE = 16383;
|
||||
LLCPUInfo gSysCPU;
|
||||
|
||||
// Don't log memory info any more often than this. It also serves as our
|
||||
// framerate sample size.
|
||||
static const F32 MEM_INFO_THROTTLE = 20;
|
||||
// Sliding window of samples. We intentionally limit the length of time we
|
||||
// remember "the slowest" framerate because framerate is very slow at login.
|
||||
// If we only triggered FrameWatcher logging when the session framerate
|
||||
// dropped below the login framerate, we'd have very little additional data.
|
||||
static const F32 MEM_INFO_WINDOW = 10*60;
|
||||
|
||||
#if LL_WINDOWS
|
||||
#ifndef DLLVERSIONINFO
|
||||
typedef struct _DllVersionInfo
|
||||
@@ -572,6 +608,7 @@ LLCPUInfo::LLCPUInfo()
|
||||
out << " (" << mCPUMHz << " MHz)";
|
||||
}
|
||||
mCPUString = out.str();
|
||||
LLStringUtil::trim(mCPUString);
|
||||
}
|
||||
|
||||
bool LLCPUInfo::hasAltivec() const
|
||||
@@ -613,8 +650,78 @@ void LLCPUInfo::stream(std::ostream& s) const
|
||||
s << "->mCPUString: " << mCPUString << std::endl;
|
||||
}
|
||||
|
||||
// Helper class for LLMemoryInfo: accumulate stats in the form we store for
|
||||
// LLMemoryInfo::getStatsMap().
|
||||
class Stats
|
||||
{
|
||||
public:
|
||||
Stats():
|
||||
mStats(LLSD::emptyMap())
|
||||
{}
|
||||
|
||||
// Store every integer type as LLSD::Integer.
|
||||
template <class T>
|
||||
void add(const LLSD::String& name, const T& value,
|
||||
typename boost::enable_if<boost::is_integral<T> >::type* = 0)
|
||||
{
|
||||
mStats[name] = LLSD::Integer(value);
|
||||
}
|
||||
|
||||
// Store every floating-point type as LLSD::Real.
|
||||
template <class T>
|
||||
void add(const LLSD::String& name, const T& value,
|
||||
typename boost::enable_if<boost::is_float<T> >::type* = 0)
|
||||
{
|
||||
mStats[name] = LLSD::Real(value);
|
||||
}
|
||||
|
||||
// Hope that LLSD::Date values are sufficiently unambiguous.
|
||||
void add(const LLSD::String& name, const LLSD::Date& value)
|
||||
{
|
||||
mStats[name] = value;
|
||||
}
|
||||
|
||||
LLSD get() const { return mStats; }
|
||||
|
||||
private:
|
||||
LLSD mStats;
|
||||
};
|
||||
|
||||
// Wrap boost::regex_match() with a function that doesn't throw.
|
||||
template <typename S, typename M, typename R>
|
||||
static bool regex_match_no_exc(const S& string, M& match, const R& regex)
|
||||
{
|
||||
try
|
||||
{
|
||||
return boost::regex_match(string, match, regex);
|
||||
}
|
||||
catch (const std::runtime_error& e)
|
||||
{
|
||||
LL_WARNS("LLMemoryInfo") << "error matching with '" << regex.str() << "': "
|
||||
<< e.what() << ":\n'" << string << "'" << LL_ENDL;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Wrap boost::regex_search() with a function that doesn't throw.
|
||||
template <typename S, typename M, typename R>
|
||||
static bool regex_search_no_exc(const S& string, M& match, const R& regex)
|
||||
{
|
||||
try
|
||||
{
|
||||
return boost::regex_search(string, match, regex);
|
||||
}
|
||||
catch (const std::runtime_error& e)
|
||||
{
|
||||
LL_WARNS("LLMemoryInfo") << "error searching with '" << regex.str() << "': "
|
||||
<< e.what() << ":\n'" << string << "'" << LL_ENDL;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
LLMemoryInfo::LLMemoryInfo()
|
||||
{
|
||||
refresh();
|
||||
}
|
||||
|
||||
#if LL_WINDOWS
|
||||
@@ -638,11 +745,7 @@ static U32 LLMemoryAdjustKBResult(U32 inKB)
|
||||
U32 LLMemoryInfo::getPhysicalMemoryKB() const
|
||||
{
|
||||
#if LL_WINDOWS
|
||||
MEMORYSTATUSEX state;
|
||||
state.dwLength = sizeof(state);
|
||||
GlobalMemoryStatusEx(&state);
|
||||
|
||||
return LLMemoryAdjustKBResult((U32)(state.ullTotalPhys >> 10));
|
||||
return LLMemoryAdjustKBResult(mStatsMap["Total Physical KB"].asInteger());
|
||||
|
||||
#elif LL_DARWIN
|
||||
// This might work on Linux as well. Someone check...
|
||||
@@ -690,12 +793,82 @@ U32 LLMemoryInfo::getPhysicalMemoryClamped() const
|
||||
void LLMemoryInfo::getAvailableMemoryKB(U32& avail_physical_mem_kb, U32& avail_virtual_mem_kb)
|
||||
{
|
||||
#if LL_WINDOWS
|
||||
MEMORYSTATUSEX state;
|
||||
state.dwLength = sizeof(state);
|
||||
GlobalMemoryStatusEx(&state);
|
||||
// Sigh, this shouldn't be a static method, then we wouldn't have to
|
||||
// reload this data separately from refresh()
|
||||
LLSD statsMap(loadStatsMap());
|
||||
|
||||
avail_physical_mem_kb = (U32)(state.ullAvailPhys/1024) ;
|
||||
avail_virtual_mem_kb = (U32)(state.ullAvailVirtual/1024) ;
|
||||
avail_physical_mem_kb = statsMap["Avail Physical KB"].asInteger();
|
||||
avail_virtual_mem_kb = statsMap["Avail Virtual KB"].asInteger();
|
||||
|
||||
#elif LL_DARWIN
|
||||
// mStatsMap is derived from vm_stat, look for (e.g.) "kb free":
|
||||
// $ vm_stat
|
||||
// Mach Virtual Memory Statistics: (page size of 4096 bytes)
|
||||
// Pages free: 462078.
|
||||
// Pages active: 142010.
|
||||
// Pages inactive: 220007.
|
||||
// Pages wired down: 159552.
|
||||
// "Translation faults": 220825184.
|
||||
// Pages copy-on-write: 2104153.
|
||||
// Pages zero filled: 167034876.
|
||||
// Pages reactivated: 65153.
|
||||
// Pageins: 2097212.
|
||||
// Pageouts: 41759.
|
||||
// Object cache: 841598 hits of 7629869 lookups (11% hit rate)
|
||||
avail_physical_mem_kb = -1 ;
|
||||
avail_virtual_mem_kb = -1 ;
|
||||
|
||||
#elif LL_LINUX
|
||||
// mStatsMap is derived from MEMINFO_FILE:
|
||||
// $ cat /proc/meminfo
|
||||
// MemTotal: 4108424 kB
|
||||
// MemFree: 1244064 kB
|
||||
// Buffers: 85164 kB
|
||||
// Cached: 1990264 kB
|
||||
// SwapCached: 0 kB
|
||||
// Active: 1176648 kB
|
||||
// Inactive: 1427532 kB
|
||||
// Active(anon): 529152 kB
|
||||
// Inactive(anon): 15924 kB
|
||||
// Active(file): 647496 kB
|
||||
// Inactive(file): 1411608 kB
|
||||
// Unevictable: 16 kB
|
||||
// Mlocked: 16 kB
|
||||
// HighTotal: 3266316 kB
|
||||
// HighFree: 721308 kB
|
||||
// LowTotal: 842108 kB
|
||||
// LowFree: 522756 kB
|
||||
// SwapTotal: 6384632 kB
|
||||
// SwapFree: 6384632 kB
|
||||
// Dirty: 28 kB
|
||||
// Writeback: 0 kB
|
||||
// AnonPages: 528820 kB
|
||||
// Mapped: 89472 kB
|
||||
// Shmem: 16324 kB
|
||||
// Slab: 159624 kB
|
||||
// SReclaimable: 145168 kB
|
||||
// SUnreclaim: 14456 kB
|
||||
// KernelStack: 2560 kB
|
||||
// PageTables: 5560 kB
|
||||
// NFS_Unstable: 0 kB
|
||||
// Bounce: 0 kB
|
||||
// WritebackTmp: 0 kB
|
||||
// CommitLimit: 8438844 kB
|
||||
// Committed_AS: 1271596 kB
|
||||
// VmallocTotal: 122880 kB
|
||||
// VmallocUsed: 65252 kB
|
||||
// VmallocChunk: 52356 kB
|
||||
// HardwareCorrupted: 0 kB
|
||||
// HugePages_Total: 0
|
||||
// HugePages_Free: 0
|
||||
// HugePages_Rsvd: 0
|
||||
// HugePages_Surp: 0
|
||||
// Hugepagesize: 2048 kB
|
||||
// DirectMap4k: 434168 kB
|
||||
// DirectMap2M: 477184 kB
|
||||
// (could also run 'free', but easier to read a file than run a program)
|
||||
avail_physical_mem_kb = -1 ;
|
||||
avail_virtual_mem_kb = -1 ;
|
||||
|
||||
#else
|
||||
//do not know how to collect available memory info for other systems.
|
||||
@@ -708,56 +881,285 @@ void LLMemoryInfo::getAvailableMemoryKB(U32& avail_physical_mem_kb, U32& avail_v
|
||||
|
||||
void LLMemoryInfo::stream(std::ostream& s) const
|
||||
{
|
||||
// We want these memory stats to be easy to grep from the log, along with
|
||||
// the timestamp. So preface each line with the timestamp and a
|
||||
// distinctive marker. Without that, we'd have to search the log for the
|
||||
// introducer line, then read subsequent lines, etc...
|
||||
std::string pfx(LLError::utcTime() + " <mem> ");
|
||||
|
||||
// Max key length
|
||||
size_t key_width(0);
|
||||
BOOST_FOREACH(const MapEntry& pair, inMap(mStatsMap))
|
||||
{
|
||||
size_t len(pair.first.length());
|
||||
if (len > key_width)
|
||||
{
|
||||
key_width = len;
|
||||
}
|
||||
}
|
||||
|
||||
// Now stream stats
|
||||
BOOST_FOREACH(const MapEntry& pair, inMap(mStatsMap))
|
||||
{
|
||||
s << pfx << std::setw(key_width+1) << (pair.first + ':') << ' ';
|
||||
LLSD value(pair.second);
|
||||
if (value.isInteger())
|
||||
s << std::setw(12) << value.asInteger();
|
||||
else if (value.isReal())
|
||||
s << std::fixed << std::setprecision(1) << value.asReal();
|
||||
else if (value.isDate())
|
||||
value.asDate().toStream(s);
|
||||
else
|
||||
s << value; // just use default LLSD formatting
|
||||
s << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
LLSD LLMemoryInfo::getStatsMap() const
|
||||
{
|
||||
return mStatsMap;
|
||||
}
|
||||
|
||||
LLMemoryInfo& LLMemoryInfo::refresh()
|
||||
{
|
||||
mStatsMap = loadStatsMap();
|
||||
|
||||
LL_DEBUGS("LLMemoryInfo") << "Populated mStatsMap:\n";
|
||||
LLSDSerialize::toPrettyXML(mStatsMap, LL_CONT);
|
||||
LL_ENDL;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
LLSD LLMemoryInfo::loadStatsMap()
|
||||
{
|
||||
// This implementation is derived from stream() code (as of 2011-06-29).
|
||||
Stats stats;
|
||||
|
||||
// associate timestamp for analysis over time
|
||||
stats.add("timestamp", LLDate::now());
|
||||
|
||||
#if LL_WINDOWS
|
||||
MEMORYSTATUSEX state;
|
||||
state.dwLength = sizeof(state);
|
||||
GlobalMemoryStatusEx(&state);
|
||||
|
||||
s << "Percent Memory use: " << (U32)state.dwMemoryLoad << '%' << std::endl;
|
||||
s << "Total Physical KB: " << (U32)(state.ullTotalPhys/1024) << std::endl;
|
||||
s << "Avail Physical KB: " << (U32)(state.ullAvailPhys/1024) << std::endl;
|
||||
s << "Total page KB: " << (U32)(state.ullTotalPageFile/1024) << std::endl;
|
||||
s << "Avail page KB: " << (U32)(state.ullAvailPageFile/1024) << std::endl;
|
||||
s << "Total Virtual KB: " << (U32)(state.ullTotalVirtual/1024) << std::endl;
|
||||
s << "Avail Virtual KB: " << (U32)(state.ullAvailVirtual/1024) << std::endl;
|
||||
DWORDLONG div = 1024;
|
||||
|
||||
stats.add("Percent Memory use", state.dwMemoryLoad/div);
|
||||
stats.add("Total Physical KB", state.ullTotalPhys/div);
|
||||
stats.add("Avail Physical KB", state.ullAvailPhys/div);
|
||||
stats.add("Total page KB", state.ullTotalPageFile/div);
|
||||
stats.add("Avail page KB", state.ullAvailPageFile/div);
|
||||
stats.add("Total Virtual KB", state.ullTotalVirtual/div);
|
||||
stats.add("Avail Virtual KB", state.ullAvailVirtual/div);
|
||||
|
||||
PERFORMANCE_INFORMATION perf;
|
||||
perf.cb = sizeof(perf);
|
||||
GetPerformanceInfo(&perf, sizeof(perf));
|
||||
|
||||
SIZE_T pagekb(perf.PageSize/1024);
|
||||
stats.add("CommitTotal KB", perf.CommitTotal * pagekb);
|
||||
stats.add("CommitLimit KB", perf.CommitLimit * pagekb);
|
||||
stats.add("CommitPeak KB", perf.CommitPeak * pagekb);
|
||||
stats.add("PhysicalTotal KB", perf.PhysicalTotal * pagekb);
|
||||
stats.add("PhysicalAvail KB", perf.PhysicalAvailable * pagekb);
|
||||
stats.add("SystemCache KB", perf.SystemCache * pagekb);
|
||||
stats.add("KernelTotal KB", perf.KernelTotal * pagekb);
|
||||
stats.add("KernelPaged KB", perf.KernelPaged * pagekb);
|
||||
stats.add("KernelNonpaged KB", perf.KernelNonpaged * pagekb);
|
||||
stats.add("PageSize KB", pagekb);
|
||||
stats.add("HandleCount", perf.HandleCount);
|
||||
stats.add("ProcessCount", perf.ProcessCount);
|
||||
stats.add("ThreadCount", perf.ThreadCount);
|
||||
|
||||
PROCESS_MEMORY_COUNTERS_EX pmem;
|
||||
pmem.cb = sizeof(pmem);
|
||||
// GetProcessMemoryInfo() is documented to accept either
|
||||
// PROCESS_MEMORY_COUNTERS* or PROCESS_MEMORY_COUNTERS_EX*, presumably
|
||||
// using the redundant size info to distinguish. But its prototype
|
||||
// specifically accepts PROCESS_MEMORY_COUNTERS*, and since this is a
|
||||
// classic-C API, PROCESS_MEMORY_COUNTERS_EX isn't a subclass. Cast the
|
||||
// pointer.
|
||||
GetProcessMemoryInfo(GetCurrentProcess(), PPROCESS_MEMORY_COUNTERS(&pmem), sizeof(pmem));
|
||||
|
||||
stats.add("Page Fault Count", pmem.PageFaultCount);
|
||||
stats.add("PeakWorkingSetSize KB", pmem.PeakWorkingSetSize/div);
|
||||
stats.add("WorkingSetSize KB", pmem.WorkingSetSize/div);
|
||||
stats.add("QutaPeakPagedPoolUsage KB", pmem.QuotaPeakPagedPoolUsage/div);
|
||||
stats.add("QuotaPagedPoolUsage KB", pmem.QuotaPagedPoolUsage/div);
|
||||
stats.add("QuotaPeakNonPagedPoolUsage KB", pmem.QuotaPeakNonPagedPoolUsage/div);
|
||||
stats.add("QuotaNonPagedPoolUsage KB", pmem.QuotaNonPagedPoolUsage/div);
|
||||
stats.add("PagefileUsage KB", pmem.PagefileUsage/div);
|
||||
stats.add("PeakPagefileUsage KB", pmem.PeakPagefileUsage/div);
|
||||
stats.add("PrivateUsage KB", pmem.PrivateUsage/div);
|
||||
|
||||
#elif LL_DARWIN
|
||||
uint64_t phys = 0;
|
||||
|
||||
size_t len = sizeof(phys);
|
||||
const vm_size_t pagekb(vm_page_size / 1024);
|
||||
|
||||
//
|
||||
// Collect the vm_stat's
|
||||
//
|
||||
|
||||
if(sysctlbyname("hw.memsize", &phys, &len, NULL, 0) == 0)
|
||||
{
|
||||
s << "Total Physical KB: " << phys/1024 << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
s << "Unable to collect memory information";
|
||||
}
|
||||
#elif LL_SOLARIS
|
||||
U64 phys = 0;
|
||||
vm_statistics_data_t vmstat;
|
||||
mach_msg_type_number_t vmstatCount = HOST_VM_INFO_COUNT;
|
||||
|
||||
phys = (U64)(sysconf(_SC_PHYS_PAGES)) * (U64)(sysconf(_SC_PAGESIZE)/1024);
|
||||
|
||||
s << "Total Physical KB: " << phys << std::endl;
|
||||
#else
|
||||
// *NOTE: This works on linux. What will it do on other systems?
|
||||
LLFILE* meminfo = LLFile::fopen(MEMINFO_FILE,"rb");
|
||||
if(meminfo)
|
||||
if (host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t) &vmstat, &vmstatCount) != KERN_SUCCESS)
|
||||
{
|
||||
char line[MAX_STRING]; /* Flawfinder: ignore */
|
||||
memset(line, 0, MAX_STRING);
|
||||
while(fgets(line, MAX_STRING, meminfo))
|
||||
{
|
||||
line[strlen(line)-1] = ' '; /*Flawfinder: ignore*/
|
||||
s << line;
|
||||
LL_WARNS("LLMemoryInfo") << "Unable to collect memory information" << LL_ENDL;
|
||||
}
|
||||
else
|
||||
{
|
||||
stats.add("Pages free KB", pagekb * vmstat.free_count);
|
||||
stats.add("Pages active KB", pagekb * vmstat.active_count);
|
||||
stats.add("Pages inactive KB", pagekb * vmstat.inactive_count);
|
||||
stats.add("Pages wired KB", pagekb * vmstat.wire_count);
|
||||
|
||||
stats.add("Pages zero fill", vmstat.zero_fill_count);
|
||||
stats.add("Page reactivations", vmstat.reactivations);
|
||||
stats.add("Page-ins", vmstat.pageins);
|
||||
stats.add("Page-outs", vmstat.pageouts);
|
||||
|
||||
stats.add("Faults", vmstat.faults);
|
||||
stats.add("Faults copy-on-write", vmstat.cow_faults);
|
||||
|
||||
stats.add("Cache lookups", vmstat.lookups);
|
||||
stats.add("Cache hits", vmstat.hits);
|
||||
|
||||
stats.add("Page purgeable count", vmstat.purgeable_count);
|
||||
stats.add("Page purges", vmstat.purges);
|
||||
|
||||
stats.add("Page speculative reads", vmstat.speculative_count);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Collect the misc task info
|
||||
//
|
||||
|
||||
{
|
||||
task_events_info_data_t taskinfo;
|
||||
unsigned taskinfoSize = sizeof(taskinfo);
|
||||
|
||||
if (task_info(mach_task_self(), TASK_EVENTS_INFO, (task_info_t) &taskinfo, &taskinfoSize) != KERN_SUCCESS)
|
||||
{
|
||||
LL_WARNS("LLMemoryInfo") << "Unable to collect task information" << LL_ENDL;
|
||||
}
|
||||
else
|
||||
{
|
||||
stats.add("Task page-ins", taskinfo.pageins);
|
||||
stats.add("Task copy-on-write faults", taskinfo.cow_faults);
|
||||
stats.add("Task messages sent", taskinfo.messages_sent);
|
||||
stats.add("Task messages received", taskinfo.messages_received);
|
||||
stats.add("Task mach system call count", taskinfo.syscalls_mach);
|
||||
stats.add("Task unix system call count", taskinfo.syscalls_unix);
|
||||
stats.add("Task context switch count", taskinfo.csw);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Collect the basic task info
|
||||
//
|
||||
|
||||
{
|
||||
task_basic_info_64_data_t taskinfo;
|
||||
unsigned taskinfoSize = sizeof(taskinfo);
|
||||
|
||||
if (task_info(mach_task_self(), TASK_BASIC_INFO_64, (task_info_t) &taskinfo, &taskinfoSize) != KERN_SUCCESS)
|
||||
{
|
||||
LL_WARNS("LLMemoryInfo") << "Unable to collect task information" << LL_ENDL;
|
||||
}
|
||||
else
|
||||
{
|
||||
stats.add("Basic suspend count", taskinfo.suspend_count);
|
||||
stats.add("Basic virtual memory KB", taskinfo.virtual_size / 1024);
|
||||
stats.add("Basic resident memory KB", taskinfo.resident_size / 1024);
|
||||
stats.add("Basic new thread policy", taskinfo.policy);
|
||||
}
|
||||
}
|
||||
|
||||
#elif LL_SOLARIS
|
||||
U64 phys = 0;
|
||||
|
||||
phys = (U64)(sysconf(_SC_PHYS_PAGES)) * (U64)(sysconf(_SC_PAGESIZE)/1024);
|
||||
|
||||
stats.add("Total Physical KB", phys);
|
||||
|
||||
#elif LL_LINUX
|
||||
std::ifstream meminfo(MEMINFO_FILE);
|
||||
if (meminfo.is_open())
|
||||
{
|
||||
// MemTotal: 4108424 kB
|
||||
// MemFree: 1244064 kB
|
||||
// Buffers: 85164 kB
|
||||
// Cached: 1990264 kB
|
||||
// SwapCached: 0 kB
|
||||
// Active: 1176648 kB
|
||||
// Inactive: 1427532 kB
|
||||
// ...
|
||||
// VmallocTotal: 122880 kB
|
||||
// VmallocUsed: 65252 kB
|
||||
// VmallocChunk: 52356 kB
|
||||
// HardwareCorrupted: 0 kB
|
||||
// HugePages_Total: 0
|
||||
// HugePages_Free: 0
|
||||
// HugePages_Rsvd: 0
|
||||
// HugePages_Surp: 0
|
||||
// Hugepagesize: 2048 kB
|
||||
// DirectMap4k: 434168 kB
|
||||
// DirectMap2M: 477184 kB
|
||||
|
||||
// Intentionally don't pass the boost::no_except flag. This
|
||||
// boost::regex object is constructed with a string literal, so it
|
||||
// should be valid every time. If it becomes invalid, we WANT an
|
||||
// exception, hopefully even before the dev checks in.
|
||||
boost::regex stat_rx("(.+): +([0-9]+)( kB)?");
|
||||
boost::smatch matched;
|
||||
|
||||
std::string line;
|
||||
while (std::getline(meminfo, line))
|
||||
{
|
||||
LL_DEBUGS("LLMemoryInfo") << line << LL_ENDL;
|
||||
if (regex_match_no_exc(line, matched, stat_rx))
|
||||
{
|
||||
// e.g. "MemTotal: 4108424 kB"
|
||||
LLSD::String key(matched[1].first, matched[1].second);
|
||||
LLSD::String value_str(matched[2].first, matched[2].second);
|
||||
LLSD::Integer value(0);
|
||||
try
|
||||
{
|
||||
value = boost::lexical_cast<LLSD::Integer>(value_str);
|
||||
}
|
||||
catch (const boost::bad_lexical_cast&)
|
||||
{
|
||||
LL_WARNS("LLMemoryInfo") << "couldn't parse '" << value_str
|
||||
<< "' in " << MEMINFO_FILE << " line: "
|
||||
<< line << LL_ENDL;
|
||||
continue;
|
||||
}
|
||||
// Store this statistic.
|
||||
stats.add(key, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS("LLMemoryInfo") << "unrecognized " << MEMINFO_FILE << " line: "
|
||||
<< line << LL_ENDL;
|
||||
}
|
||||
}
|
||||
fclose(meminfo);
|
||||
}
|
||||
else
|
||||
{
|
||||
s << "Unable to collect memory information";
|
||||
LL_WARNS("LLMemoryInfo") << "Unable to collect memory information" << LL_ENDL;
|
||||
}
|
||||
|
||||
#else
|
||||
LL_WARNS("LLMemoryInfo") << "Unknown system; unable to collect memory information" << LL_ENDL;
|
||||
|
||||
#endif
|
||||
|
||||
return stats.get();
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& s, const LLOSInfo& info)
|
||||
@@ -778,6 +1180,143 @@ std::ostream& operator<<(std::ostream& s, const LLMemoryInfo& info)
|
||||
return s;
|
||||
}
|
||||
|
||||
class FrameWatcher
|
||||
{
|
||||
public:
|
||||
FrameWatcher():
|
||||
// Hooking onto the "mainloop" event pump gets us one call per frame.
|
||||
mConnection(LLEventPumps::instance()
|
||||
.obtain("mainloop")
|
||||
.listen("FrameWatcher", boost::bind(&FrameWatcher::tick, this, _1))),
|
||||
// Initializing mSampleStart to an invalid timestamp alerts us to skip
|
||||
// trying to compute framerate on the first call.
|
||||
mSampleStart(-1),
|
||||
// Initializing mSampleEnd to 0 ensures that we treat the first call
|
||||
// as the completion of a sample window.
|
||||
mSampleEnd(0),
|
||||
mFrames(0),
|
||||
// Both MEM_INFO_WINDOW and MEM_INFO_THROTTLE are in seconds. We need
|
||||
// the number of integer MEM_INFO_THROTTLE sample slots that will fit
|
||||
// in MEM_INFO_WINDOW. Round up.
|
||||
mSamples(int((MEM_INFO_WINDOW / MEM_INFO_THROTTLE) + 0.7)),
|
||||
// Initializing to F32_MAX means that the first real frame will become
|
||||
// the slowest ever, which sounds like a good idea.
|
||||
mSlowest(F32_MAX)
|
||||
{}
|
||||
|
||||
bool tick(const LLSD&)
|
||||
{
|
||||
F32 timestamp(mTimer.getElapsedTimeF32());
|
||||
|
||||
// Count this frame in the interval just completed.
|
||||
++mFrames;
|
||||
|
||||
// Have we finished a sample window yet?
|
||||
if (timestamp < mSampleEnd)
|
||||
{
|
||||
// no, just keep waiting
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set up for next sample window. Capture values for previous frame in
|
||||
// local variables and reset data members.
|
||||
U32 frames(mFrames);
|
||||
F32 sampleStart(mSampleStart);
|
||||
// No frames yet in next window
|
||||
mFrames = 0;
|
||||
// which starts right now
|
||||
mSampleStart = timestamp;
|
||||
// and ends MEM_INFO_THROTTLE seconds in the future
|
||||
mSampleEnd = mSampleStart + MEM_INFO_THROTTLE;
|
||||
|
||||
// On the very first call, that's all we can do, no framerate
|
||||
// computation is possible.
|
||||
if (sampleStart < 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// How long did this actually take? As framerate slows, the duration
|
||||
// of the frame we just finished could push us WELL beyond our desired
|
||||
// sample window size.
|
||||
F32 elapsed(timestamp - sampleStart);
|
||||
F32 framerate(frames/elapsed);
|
||||
|
||||
// Remember previous slowest framerate because we're just about to
|
||||
// update it.
|
||||
F32 slowest(mSlowest);
|
||||
// Remember previous number of samples.
|
||||
boost::circular_buffer<F32>::size_type prevSize(mSamples.size());
|
||||
|
||||
// Capture new framerate in our samples buffer. Once the buffer is
|
||||
// full (after MEM_INFO_WINDOW seconds), this will displace the oldest
|
||||
// sample. ("So they all rolled over, and one fell out...")
|
||||
mSamples.push_back(framerate);
|
||||
|
||||
// Calculate the new minimum framerate. I know of no way to update a
|
||||
// rolling minimum without ever rescanning the buffer. But since there
|
||||
// are only a few tens of items in this buffer, rescanning it is
|
||||
// probably cheaper (and certainly easier to reason about) than
|
||||
// attempting to optimize away some of the scans.
|
||||
mSlowest = framerate; // pick an arbitrary entry to start
|
||||
for (boost::circular_buffer<F32>::const_iterator si(mSamples.begin()), send(mSamples.end());
|
||||
si != send; ++si)
|
||||
{
|
||||
if (*si < mSlowest)
|
||||
{
|
||||
mSlowest = *si;
|
||||
}
|
||||
}
|
||||
|
||||
// We're especially interested in memory as framerate drops. Only log
|
||||
// when framerate drops below the slowest framerate we remember.
|
||||
// (Should always be true for the end of the very first sample
|
||||
// window.)
|
||||
if (framerate >= slowest)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// Congratulations, we've hit a new low. :-P
|
||||
|
||||
LL_INFOS("FrameWatcher") << ' ';
|
||||
if (! prevSize)
|
||||
{
|
||||
LL_CONT << "initial framerate ";
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_CONT << "slowest framerate for last " << int(prevSize * MEM_INFO_THROTTLE)
|
||||
<< " seconds ";
|
||||
}
|
||||
LL_CONT << std::fixed << std::setprecision(1) << framerate << '\n'
|
||||
<< LLMemoryInfo() << LL_ENDL;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
// Storing the connection in an LLTempBoundListener ensures it will be
|
||||
// disconnected when we're destroyed.
|
||||
LLTempBoundListener mConnection;
|
||||
// Track elapsed time
|
||||
LLTimer mTimer;
|
||||
// Some of what you see here is in fact redundant with functionality you
|
||||
// can get from LLTimer. Unfortunately the LLTimer API is missing the
|
||||
// feature we need: has at least the stated interval elapsed, and if so,
|
||||
// exactly how long has passed? So we have to do it by hand, sigh.
|
||||
// Time at start, end of sample window
|
||||
F32 mSampleStart, mSampleEnd;
|
||||
// Frames this sample window
|
||||
U32 mFrames;
|
||||
// Sliding window of framerate samples
|
||||
boost::circular_buffer<F32> mSamples;
|
||||
// Slowest framerate in mSamples
|
||||
F32 mSlowest;
|
||||
};
|
||||
|
||||
// Need an instance of FrameWatcher before it does any good
|
||||
static FrameWatcher sFrameWatcher;
|
||||
|
||||
BOOL gunzip_file(const std::string& srcfile, const std::string& dstfile)
|
||||
{
|
||||
std::string tmpfile;
|
||||
|
||||
@@ -117,6 +117,27 @@ public:
|
||||
|
||||
//get the available memory infomation in KiloBytes.
|
||||
static void getAvailableMemoryKB(U32& avail_physical_mem_kb, U32& avail_virtual_mem_kb);
|
||||
|
||||
// Retrieve a map of memory statistics. The keys of the map are platform-
|
||||
// dependent. The values are in kilobytes to try to avoid integer overflow.
|
||||
LLSD getStatsMap() const;
|
||||
|
||||
// Re-fetch memory data (as reported by stream() and getStatsMap()) from the
|
||||
// system. Normally this is fetched at construction time. Return (*this)
|
||||
// to permit usage of the form:
|
||||
// @code
|
||||
// LLMemoryInfo info;
|
||||
// ...
|
||||
// info.refresh().getStatsMap();
|
||||
// @endcode
|
||||
LLMemoryInfo& refresh();
|
||||
|
||||
private:
|
||||
// set mStatsMap
|
||||
static LLSD loadStatsMap();
|
||||
|
||||
// Memory stats for getStatsMap().
|
||||
LLSD mStatsMap;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -397,6 +397,43 @@ public:
|
||||
#endif
|
||||
};
|
||||
|
||||
#if LL_DEBUG
|
||||
class LL_COMMON_API AINRLock
|
||||
{
|
||||
private:
|
||||
int read_locked;
|
||||
int write_locked;
|
||||
|
||||
mutable bool mAccessed;
|
||||
mutable AIThreadID mTheadID;
|
||||
|
||||
void accessed(void) const
|
||||
{
|
||||
if (!mAccessed)
|
||||
{
|
||||
mAccessed = true;
|
||||
mTheadID.reset();
|
||||
}
|
||||
else
|
||||
{
|
||||
llassert_always(mTheadID.equals_current_thread());
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
AINRLock(void) : read_locked(false), write_locked(false), mAccessed(false) { }
|
||||
|
||||
bool isLocked() const { return read_locked || write_locked; }
|
||||
|
||||
void rdlock(bool high_priority = false) { accessed(); ++read_locked; }
|
||||
void rdunlock() { --read_locked; }
|
||||
void wrlock() { llassert(!isLocked()); accessed(); ++write_locked; }
|
||||
void wrunlock() { --write_locked; }
|
||||
void wr2rdlock() { llassert(false); }
|
||||
void rd2wrlock() { llassert(false); }
|
||||
};
|
||||
#endif
|
||||
|
||||
//============================================================================
|
||||
|
||||
void LLThread::lockData()
|
||||
|
||||
@@ -41,10 +41,15 @@
|
||||
#include "llmd5.h"
|
||||
#include "llstring.h"
|
||||
#include "lltimer.h"
|
||||
#include "llthread.h"
|
||||
|
||||
const LLUUID LLUUID::null;
|
||||
const LLTransactionID LLTransactionID::tnull;
|
||||
|
||||
// static
|
||||
LLMutex * LLUUID::mMutex = NULL;
|
||||
|
||||
|
||||
/*
|
||||
|
||||
NOT DONE YET!!!
|
||||
@@ -731,6 +736,7 @@ void LLUUID::getCurrentTime(uuid_time_t *timestamp)
|
||||
getSystemTime(&time_last);
|
||||
uuids_this_tick = uuids_per_tick;
|
||||
init = TRUE;
|
||||
mMutex = new LLMutex;
|
||||
}
|
||||
|
||||
uuid_time_t time_now = {0,0};
|
||||
@@ -782,6 +788,7 @@ void LLUUID::generate()
|
||||
#endif
|
||||
if (!has_init)
|
||||
{
|
||||
has_init = 1;
|
||||
if (getNodeID(node_id) <= 0)
|
||||
{
|
||||
get_random_bytes(node_id, 6);
|
||||
@@ -803,18 +810,24 @@ void LLUUID::generate()
|
||||
#else
|
||||
clock_seq = (U16)ll_rand(65536);
|
||||
#endif
|
||||
has_init = 1;
|
||||
}
|
||||
|
||||
// get current time
|
||||
getCurrentTime(×tamp);
|
||||
U16 our_clock_seq = clock_seq;
|
||||
|
||||
// if clock went backward change clockseq
|
||||
if (cmpTime(×tamp, &time_last) == -1) {
|
||||
// if clock hasn't changed or went backward, change clockseq
|
||||
if (cmpTime(×tamp, &time_last) != 1)
|
||||
{
|
||||
LLMutexLock lock(mMutex);
|
||||
clock_seq = (clock_seq + 1) & 0x3FFF;
|
||||
if (clock_seq == 0) clock_seq++;
|
||||
if (clock_seq == 0)
|
||||
clock_seq++;
|
||||
our_clock_seq = clock_seq; // Ensure we're using a different clock_seq value from previous time
|
||||
}
|
||||
|
||||
time_last = timestamp;
|
||||
|
||||
memcpy(mData+10, node_id, 6); /* Flawfinder: ignore */
|
||||
U32 tmp;
|
||||
tmp = timestamp.low;
|
||||
@@ -836,7 +849,8 @@ void LLUUID::generate()
|
||||
tmp >>= 8;
|
||||
mData[6] = (unsigned char) tmp;
|
||||
|
||||
tmp = clock_seq;
|
||||
tmp = our_clock_seq;
|
||||
|
||||
mData[9] = (unsigned char) tmp;
|
||||
tmp >>= 8;
|
||||
mData[8] = (unsigned char) tmp;
|
||||
@@ -846,8 +860,6 @@ void LLUUID::generate()
|
||||
md5_uuid.update(mData,16);
|
||||
md5_uuid.finalize();
|
||||
md5_uuid.raw_digest(mData);
|
||||
|
||||
time_last = timestamp;
|
||||
}
|
||||
|
||||
void LLUUID::generate(const std::string& hash_string)
|
||||
@@ -861,8 +873,14 @@ U32 LLUUID::getRandomSeed()
|
||||
static unsigned char seed[16]; /* Flawfinder: ignore */
|
||||
|
||||
getNodeID(&seed[0]);
|
||||
seed[6]='\0';
|
||||
seed[7]='\0';
|
||||
|
||||
// Incorporate the pid into the seed to prevent
|
||||
// processes that start on the same host at the same
|
||||
// time from generating the same seed.
|
||||
pid_t pid = LLApp::getPid();
|
||||
|
||||
seed[6]=(unsigned char)(pid >> 8);
|
||||
seed[7]=(unsigned char)(pid);
|
||||
getSystemTime((uuid_time_t *)(&seed[8]));
|
||||
|
||||
LLMD5 md5_seed;
|
||||
|
||||
@@ -31,6 +31,8 @@
|
||||
#include "stdtypes.h"
|
||||
#include "llpreprocessor.h"
|
||||
|
||||
class LLMutex;
|
||||
|
||||
const S32 UUID_BYTES = 16;
|
||||
const S32 UUID_WORDS = 4;
|
||||
const S32 UUID_STR_LENGTH = 37; // actually wrong, should be 36 and use size below
|
||||
@@ -118,6 +120,7 @@ public:
|
||||
static BOOL validate(const std::string& in_string); // Validate that the UUID string is legal.
|
||||
|
||||
static const LLUUID null;
|
||||
static LLMutex * mMutex;
|
||||
|
||||
static U32 getRandomSeed();
|
||||
static S32 getNodeID(unsigned char * node_id);
|
||||
|
||||
@@ -59,6 +59,7 @@ const U32 PF_URL_WEB_PAGE = 1 << 19; // The "media URL" is an HTML page
|
||||
const U32 PF_URL_RAW_HTML = 1 << 20; // The "media URL" is a raw HTML string like <H1>Foo</H1>
|
||||
const U32 PF_RESTRICT_PUSHOBJECT = 1 << 21; // Restrict push object to either on agent or on scripts owned by parcel owner
|
||||
const U32 PF_DENY_ANONYMOUS = 1 << 22; // Deny all non identified/transacted accounts
|
||||
const U32 PF_GAMING = 1 << 23; // Denotes a gaming parcel on certain grids
|
||||
// const U32 PF_DENY_IDENTIFIED = 1 << 23; // Deny identified accounts
|
||||
// const U32 PF_DENY_TRANSACTED = 1 << 24; // Deny identified accounts
|
||||
const U32 PF_ALLOW_GROUP_SCRIPTS = 1 << 25; // Allow scripts owned by group
|
||||
|
||||
@@ -152,7 +152,7 @@ void HTTPTimeout::upload_finished(void)
|
||||
// ^ ^ ^ ^ ^ ^ ^ ^
|
||||
// | | | | | | | |
|
||||
bool HTTPTimeout::data_received(size_t n/*,*/
|
||||
#ifdef CWDEBUG
|
||||
#if defined(CWDEBUG) || defined(DEBUG_CURLIO)
|
||||
ASSERT_ONLY_COMMA(bool upload_error_status)
|
||||
#else
|
||||
ASSERT_ONLY_COMMA(bool)
|
||||
@@ -208,8 +208,9 @@ bool HTTPTimeout::lowspeed(size_t bytes)
|
||||
//
|
||||
// We do this as follows: we create low_speed_time (in seconds) buckets and fill them with the number
|
||||
// of bytes received during that second. We also keep track of the sum of all bytes received between 'now'
|
||||
// and 'now - llmax(starttime, low_speed_time)'. Then if that period reaches at least low_speed_time
|
||||
// seconds, and the transfer rate (sum / low_speed_time) is less than low_speed_limit, we abort.
|
||||
// and 'llmax(starttime, now - low_speed_time)'. Then if that period reaches at least low_speed_time
|
||||
// seconds (when now >= starttime + low_speed_time) and the transfer rate (sum / low_speed_time) is
|
||||
// less than low_speed_limit, we abort.
|
||||
|
||||
// When are we?
|
||||
S32 second = (sClockCount - mLowSpeedClock) * sClockWidth;
|
||||
@@ -244,6 +245,7 @@ bool HTTPTimeout::lowspeed(size_t bytes)
|
||||
if (s == -1)
|
||||
{
|
||||
mBucket = 0; // It doesn't really matter where we start.
|
||||
mOverwriteSecond = second + low_speed_time;
|
||||
mTotalBytes = bytes;
|
||||
mBuckets[mBucket] = bytes;
|
||||
return false;
|
||||
@@ -257,11 +259,17 @@ bool HTTPTimeout::lowspeed(size_t bytes)
|
||||
bucket = 0;
|
||||
if (++s == second)
|
||||
break;
|
||||
mTotalBytes -= mBuckets[bucket];
|
||||
if (s >= mOverwriteSecond)
|
||||
{
|
||||
mTotalBytes -= mBuckets[bucket];
|
||||
}
|
||||
mBuckets[bucket] = 0;
|
||||
}
|
||||
mBucket = bucket;
|
||||
mTotalBytes -= mBuckets[mBucket];
|
||||
if (s >= mOverwriteSecond)
|
||||
{
|
||||
mTotalBytes -= mBuckets[mBucket];
|
||||
}
|
||||
mTotalBytes += bytes;
|
||||
mBuckets[mBucket] = bytes;
|
||||
|
||||
@@ -286,29 +294,40 @@ bool HTTPTimeout::lowspeed(size_t bytes)
|
||||
}
|
||||
|
||||
// Calculate how long the data transfer may stall until we should timeout.
|
||||
//
|
||||
// Assume 6 buckets: 0 1 2 3 4 5 (low_speed_time == 6)
|
||||
// Seconds since start of transfer: 4 5 6 7 8 9 (mOverwriteSecond == 10)
|
||||
// Current second: ^
|
||||
// Data in buckets: A B w x y z (mTotalBytes = A + B; w, x, y and z are undefined)
|
||||
//
|
||||
// Obviously, we need to stall at LEAST till second low_speed_time before we can "timeout".
|
||||
// And possibly more if mTotalBytes is already >= mintotalbytes.
|
||||
//
|
||||
// The code below finds 'max_stall_time', so that when from now on the buckets
|
||||
// are filled with 0, then at 'second + max_stall_time' we should time out,
|
||||
// meaning that the resulting mTotalBytes after writing 0 at that second
|
||||
// will be less than mintotalbytes and 'second + max_stall_time' >= low_speed_time.
|
||||
//
|
||||
llassert_always(mintotalbytes > 0);
|
||||
S32 max_stall_time = 0;
|
||||
U32 dropped_bytes = 0;
|
||||
while(1)
|
||||
S32 max_stall_time = low_speed_time - second; // Minimum value.
|
||||
// Note that if max_stall_time <= 0 here, then second >= low_speed_time and
|
||||
// thus mTotalBytes >= mintotalbytes because we didn't timeout already above.
|
||||
if (mTotalBytes >= mintotalbytes)
|
||||
{
|
||||
if (++bucket == low_speed_time) // The next second the next bucket will be emptied.
|
||||
bucket = 0;
|
||||
++max_stall_time;
|
||||
dropped_bytes += mBuckets[bucket];
|
||||
// Note how, when max_stall_time == low_speed_time, dropped_bytes has
|
||||
// to be equal to mTotalBytes, the sum of all vector elements.
|
||||
llassert(max_stall_time < low_speed_time || dropped_bytes == mTotalBytes);
|
||||
// AIFIXME: This is a bug and should really be fixed instead of just be a warning.
|
||||
if (!(max_stall_time < low_speed_time || dropped_bytes == mTotalBytes))
|
||||
// In this case max_stall_time has a minimum value equal to when we will reach mOverwriteSecond,
|
||||
// because that is the first second at which mTotalBytes will decrease.
|
||||
max_stall_time = mOverwriteSecond - second - 1;
|
||||
U32 total_bytes = mTotalBytes;
|
||||
int bucket = -1; // Must be one less as the start bucket, which corresponds with mOverwriteSecond (and thus with the current max_stall_time).
|
||||
do
|
||||
{
|
||||
llwarns << "ASSERT max_stall_time < low_speed_time || dropped_bytes == mTotalBytes failed... aborting. "
|
||||
"max_stall_time = " << max_stall_time << "; low_speed_time = " << low_speed_time <<
|
||||
"; dropped_bytes = " << dropped_bytes << "; mTotalBytes = " << mTotalBytes << llendl;
|
||||
break;
|
||||
++max_stall_time; // Next second (mOverwriteSecond upon entry of the loop).
|
||||
++bucket; // The next bucket (0 upon entry of the loop).
|
||||
// Once we reach the end of the vector total_bytes MUST have reached 0 exactly and we should have left this loop.
|
||||
llassert_always(bucket < low_speed_time);
|
||||
total_bytes -= mBuckets[bucket]; // Empty this bucket.
|
||||
}
|
||||
// And thus the following will certainly abort.
|
||||
if (second + max_stall_time >= low_speed_time && mTotalBytes - dropped_bytes < mintotalbytes)
|
||||
break;
|
||||
while(total_bytes >= 1); // Use 1 here instead of mintotalbytes, to test that total_bytes indeed always reaches zero.
|
||||
}
|
||||
// If this function isn't called again within max_stall_time seconds, we stalled.
|
||||
mStalled = sClockCount + max_stall_time / sClockWidth;
|
||||
|
||||
@@ -81,6 +81,7 @@ class HTTPTimeout : public LLRefCount {
|
||||
bool mLowSpeedOn; // Set while uploading or downloading data.
|
||||
bool mUploadFinished; // Used to keep track of whether upload_finished was called yet.
|
||||
S32 mLastSecond; // The time at which lowspeed() was last called, in seconds since mLowSpeedClock.
|
||||
S32 mOverwriteSecond; // The second at which the first bucket of this transfer will be overwritten.
|
||||
U32 mTotalBytes; // The sum of all bytes in mBuckets.
|
||||
U64 mLowSpeedClock; // Clock count at which low speed detection (re)started.
|
||||
U64 mStalled; // The clock count at which this transaction is considered to be stalling if nothing is transfered anymore.
|
||||
|
||||
@@ -844,7 +844,12 @@ P(environmentRequestResponder);
|
||||
P(estateChangeInfoResponder);
|
||||
P(eventPollResponder);
|
||||
P(fetchInventoryResponder);
|
||||
P(fetchScriptLimitsAttachmentInfoResponder);
|
||||
P(fetchScriptLimitsRegionDetailsResponder);
|
||||
P(fetchScriptLimitsRegionInfoResponder);
|
||||
P(fetchScriptLimitsRegionSummaryResponder);
|
||||
P(fnPtrResponder);
|
||||
P2(gamingDataReceived, transfer_18s);
|
||||
P2(groupMemberDataResponder, transfer_300s);
|
||||
P2(groupProposalBallotResponder, transfer_300s);
|
||||
P(homeLocationResponder);
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <stdarg.h>
|
||||
#include <cstring>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include "llpreprocessor.h"
|
||||
#include <curl/curl.h>
|
||||
#define COMPILING_DEBUG_LIBCURL_CC
|
||||
|
||||
@@ -680,7 +680,6 @@ void LLCircuitData::checkPacketInID(TPACKETID id, BOOL receive_resent)
|
||||
setPacketInID((id + 1) % LL_MAX_OUT_PACKET_ID);
|
||||
|
||||
mLastPacketGap = 0;
|
||||
mOutOfOrderRate.count(0);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -776,7 +775,6 @@ void LLCircuitData::checkPacketInID(TPACKETID id, BOOL receive_resent)
|
||||
|
||||
}
|
||||
}
|
||||
mOutOfOrderRate.count(gap);
|
||||
mLastPacketGap = gap;
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,6 @@
|
||||
#include "llpacketack.h"
|
||||
#include "lluuid.h"
|
||||
#include "llthrottle.h"
|
||||
#include "llstat.h"
|
||||
|
||||
//
|
||||
// Constants
|
||||
@@ -126,8 +125,6 @@ public:
|
||||
S32 getUnackedPacketCount() const { return mUnackedPacketCount; }
|
||||
S32 getUnackedPacketBytes() const { return mUnackedPacketBytes; }
|
||||
F64 getNextPingSendTime() const { return mNextPingSendTime; }
|
||||
F32 getOutOfOrderRate(LLStatAccum::TimeScale scale = LLStatAccum::SCALE_MINUTE)
|
||||
{ return mOutOfOrderRate.meanValue(scale); }
|
||||
U32 getLastPacketGap() const { return mLastPacketGap; }
|
||||
LLHost getHost() const { return mHost; }
|
||||
F64 getLastPacketInTime() const { return mLastPacketInTime; }
|
||||
@@ -275,7 +272,6 @@ protected:
|
||||
LLTimer mExistenceTimer; // initialized when circuit created, used to track bandwidth numbers
|
||||
|
||||
S32 mCurrentResendCount; // Number of resent packets since last spam
|
||||
LLStatRate mOutOfOrderRate; // Rate of out of order packets coming in.
|
||||
U32 mLastPacketGap; // Gap in sequence number of last packet.
|
||||
|
||||
const F32 mHeartbeatInterval;
|
||||
|
||||
@@ -141,6 +141,11 @@ private:
|
||||
};
|
||||
|
||||
static LLFastTimer::DeclareTimer FTM_PROCESS_HTTP_PIPE("HTTP Pipe");
|
||||
static LLFastTimer::DeclareTimer FTM_PROCESS_HTTP_GET("HTTP Get");
|
||||
static LLFastTimer::DeclareTimer FTM_PROCESS_HTTP_PUT("HTTP Put");
|
||||
static LLFastTimer::DeclareTimer FTM_PROCESS_HTTP_POST("HTTP Post");
|
||||
static LLFastTimer::DeclareTimer FTM_PROCESS_HTTP_DELETE("HTTP Delete");
|
||||
|
||||
LLIOPipe::EStatus LLHTTPPipe::process_impl(
|
||||
const LLChannelDescriptors& channels,
|
||||
buffer_ptr_t& buffer,
|
||||
@@ -177,12 +182,12 @@ LLIOPipe::EStatus LLHTTPPipe::process_impl(
|
||||
std::string verb = context[CONTEXT_REQUEST][CONTEXT_VERB];
|
||||
if(verb == HTTP_VERB_GET)
|
||||
{
|
||||
LLPerfBlock getblock("http_get");
|
||||
LLFastTimer _(FTM_PROCESS_HTTP_GET);
|
||||
mNode.get(LLHTTPNode::ResponsePtr(mResponse), context);
|
||||
}
|
||||
else if(verb == HTTP_VERB_PUT)
|
||||
{
|
||||
LLPerfBlock putblock("http_put");
|
||||
LLFastTimer _(FTM_PROCESS_HTTP_PUT);
|
||||
LLSD input;
|
||||
if (mNode.getContentType() == LLHTTPNode::CONTENT_TYPE_LLSD)
|
||||
{
|
||||
@@ -198,7 +203,7 @@ LLIOPipe::EStatus LLHTTPPipe::process_impl(
|
||||
}
|
||||
else if(verb == HTTP_VERB_POST)
|
||||
{
|
||||
LLPerfBlock postblock("http_post");
|
||||
LLFastTimer _(FTM_PROCESS_HTTP_POST);
|
||||
LLSD input;
|
||||
if (mNode.getContentType() == LLHTTPNode::CONTENT_TYPE_LLSD)
|
||||
{
|
||||
@@ -214,7 +219,7 @@ LLIOPipe::EStatus LLHTTPPipe::process_impl(
|
||||
}
|
||||
else if(verb == HTTP_VERB_DELETE)
|
||||
{
|
||||
LLPerfBlock delblock("http_delete");
|
||||
LLFastTimer _(FTM_PROCESS_HTTP_DELETE);
|
||||
mNode.del(LLHTTPNode::ResponsePtr(mResponse), context);
|
||||
}
|
||||
else if(verb == HTTP_VERB_OPTIONS)
|
||||
|
||||
@@ -364,7 +364,6 @@ public:
|
||||
{
|
||||
if (mHandlerFunc)
|
||||
{
|
||||
LLPerfBlock msg_cb_time("msg_cb", mName);
|
||||
mHandlerFunc(msgsystem, mUserData);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -454,6 +454,7 @@ void LLPumpIO::pump()
|
||||
}
|
||||
|
||||
static LLFastTimer::DeclareTimer FTM_PUMP_IO("Pump IO");
|
||||
static LLFastTimer::DeclareTimer FTM_PUMP_POLL("Pump Poll");
|
||||
|
||||
LLPumpIO::current_chain_t LLPumpIO::removeRunningChain(LLPumpIO::current_chain_t& run_chain)
|
||||
{
|
||||
@@ -549,7 +550,7 @@ void LLPumpIO::pump(const S32& poll_timeout)
|
||||
S32 count = 0;
|
||||
S32 client_id = 0;
|
||||
{
|
||||
LLPerfBlock polltime("pump_poll");
|
||||
LLFastTimer _(FTM_PUMP_POLL);
|
||||
apr_pollset_poll(mPollset, poll_timeout, &count, &poll_fd);
|
||||
}
|
||||
PUMP_DEBUG;
|
||||
|
||||
@@ -66,6 +66,8 @@ const U32 DFQ_INC_NEW_VIEWER = (DFQ_INC_PG | DFQ_INC_MATURE | DFQ_INC_ADULT); //
|
||||
|
||||
const U32 DFQ_ADULT_SIMS_ONLY = 0x1 << 27;
|
||||
|
||||
const U32 DFQ_FILTER_GAMING = 0x1 << 28;
|
||||
|
||||
// Sell Type flags
|
||||
const U32 ST_AUCTION = 0x1 << 1;
|
||||
const U32 ST_NEWBIE = 0x1 << 2;
|
||||
|
||||
@@ -51,6 +51,8 @@ const U64 REGION_FLAGS_BLOCK_LAND_RESELL = (1 << 7);
|
||||
|
||||
// All content wiped once per night
|
||||
const U64 REGION_FLAGS_SANDBOX = (1 << 8);
|
||||
const U64 REGION_FLAGS_GAMING = (1 << 10); // Denotes a gaming region on certain grids
|
||||
const U64 REGION_FLAGS_HIDE_FROM_SEARCH = (1 << 11); // Hides region from search on certain grids
|
||||
const U64 REGION_FLAGS_SKIP_COLLISIONS = (1 << 12); // Pin all non agent rigid bodies
|
||||
const U64 REGION_FLAGS_SKIP_SCRIPTS = (1 << 13);
|
||||
const U64 REGION_FLAGS_SKIP_PHYSICS = (1 << 14); // Skip all physics
|
||||
@@ -96,6 +98,18 @@ const U64 REGION_FLAGS_ESTATE_MASK = REGION_FLAGS_EXTERNALLY_VISIBLE
|
||||
| REGION_FLAGS_DENY_ANONYMOUS
|
||||
| REGION_FLAGS_DENY_AGEUNVERIFIED;
|
||||
|
||||
// 'Gaming' flags
|
||||
const U32 REGION_GAMING_PRESENT = (1 << 0);
|
||||
const U32 REGION_GAMING_HIDE_PARCEL = (1 << 1);
|
||||
const U32 REGION_GAMING_HIDE_FIND_ALL = (1 << 2);
|
||||
const U32 REGION_GAMING_HIDE_FIND_CLASSIFIEDS = (1 << 3);
|
||||
const U32 REGION_GAMING_HIDE_FIND_EVENTS = (1 << 4);
|
||||
const U32 REGION_GAMING_HIDE_FIND_LAND = (1 << 5);
|
||||
const U32 REGION_GAMING_HIDE_FIND_SIMS = (1 << 6);
|
||||
const U32 REGION_GAMING_HIDE_FIND_GROUPS = (1 << 7);
|
||||
const U32 REGION_GAMING_HIDE_FIND_ALL_CLASSIC = (1 << 8);
|
||||
const U32 REGION_GAMING_HIDE_GOD_FLOATER = (1 << 9);
|
||||
|
||||
inline BOOL is_prelude( U64 flags )
|
||||
{
|
||||
// definition of prelude does not depend on fixed-sun
|
||||
|
||||
@@ -82,6 +82,7 @@ set(llui_SOURCE_FILES
|
||||
set(llui_HEADER_FILES
|
||||
CMakeLists.txt
|
||||
|
||||
ailist.h
|
||||
llalertdialog.h
|
||||
llbutton.h
|
||||
llcallbackmap.h
|
||||
|
||||
645
indra/llui/ailist.h
Normal file
645
indra/llui/ailist.h
Normal file
@@ -0,0 +1,645 @@
|
||||
/**
|
||||
* @file ailist.h
|
||||
* @brief A linked list with iterators that advance when their element is deleted.
|
||||
*
|
||||
* Copyright (c) 2013, Aleric Inglewood.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* CHANGELOG
|
||||
* and additional copyright holders.
|
||||
*
|
||||
* 05/02/2013
|
||||
* Initial version, written by Aleric Inglewood @ SL
|
||||
*/
|
||||
|
||||
#ifndef AILIST_H
|
||||
#define AILIST_H
|
||||
|
||||
#include <list>
|
||||
|
||||
template<typename T>
|
||||
class AIList;
|
||||
|
||||
template<typename T>
|
||||
class AIConstListIterator;
|
||||
|
||||
/*
|
||||
* AINode<T>
|
||||
*
|
||||
* The actual data stored in a std::list when using AIList<T>.
|
||||
* T is the template parameter used with AIList.
|
||||
* count are the number of iterators that currently point to this element.
|
||||
* dead is 0 or 1, where 1 means that the element was erased from the AIList
|
||||
* (but not yet from the internal std::list, so that any iterators to it
|
||||
* are NOT invalidated).
|
||||
*/
|
||||
template<typename T>
|
||||
struct AINode {
|
||||
T mElement; // The user visual data.
|
||||
mutable unsigned short count; // Number of iterators pointing to this element.
|
||||
mutable unsigned short dead; // Whether or not the element is "erased".
|
||||
|
||||
AINode(void) : count(0), dead(0) { }
|
||||
explicit AINode(T const& __val) : mElement(__val), count(0), dead(0) { }
|
||||
|
||||
// Equivalence operators.
|
||||
// __node may not be dead. Dead nodes in the list are "skipped" (obviously), meaning that they are never equal or always unequal.
|
||||
bool operator==(AINode const& __node) const { llassert(!__node.dead); return mElement == __node.mElement && !dead; }
|
||||
bool operator!=(AINode const& __node) const { llassert(!__node.dead); return mElement != __node.mElement || dead; }
|
||||
|
||||
// Default ordering for sort().
|
||||
bool operator<(AINode const& __node) const { return mElement < __node.mElement; }
|
||||
};
|
||||
|
||||
/*
|
||||
* AIListIterator<T>
|
||||
*
|
||||
* A non-const iterator to an element of AIList<T>.
|
||||
*/
|
||||
template<typename T>
|
||||
class AIListIterator {
|
||||
private:
|
||||
typedef AIListIterator<T> _Self;
|
||||
typedef std::list<AINode<T> > _Container;
|
||||
typedef typename _Container::iterator _Iterator;
|
||||
|
||||
_Container* mContainer; // A pointer to the associated container, or NULL when (still) singular.
|
||||
// Note that this code does not allow a container to be destructed while
|
||||
// any non-end iterators still exist (although that could be legal).
|
||||
// If an iterator points to end() and the container is destructed then
|
||||
// this pointer is NOT reset to NULL.
|
||||
_Iterator mIterator; // Internal iterator to element of mContainer (or singular when mContainer is NULL).
|
||||
|
||||
// Increment reference counter for mIterator (if not singular and not end()).
|
||||
void ref(void)
|
||||
{
|
||||
if (mContainer && mContainer->end() != mIterator)
|
||||
{
|
||||
// It would be bad a new iterator was created that pointed to a dead element.
|
||||
// Also, as a sanity check, make sure there aren't a ridiculous number of iterators
|
||||
// pointing to this element.
|
||||
llassert(!mIterator->dead && mIterator->count < 100);
|
||||
++(mIterator->count);
|
||||
}
|
||||
}
|
||||
|
||||
// Decrement reference counter for mIterator (if not singular and not end()).
|
||||
// If this was the last iterator pointing to a dead element, then really erase it.
|
||||
void unref(void)
|
||||
{
|
||||
if (mContainer && mContainer->end() != mIterator)
|
||||
{
|
||||
llassert(mIterator->count > 0);
|
||||
if (--(mIterator->count) == 0 && mIterator->dead)
|
||||
{
|
||||
mContainer->erase(mIterator);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
// Some standard typedefs that have to exist for iterators.
|
||||
typedef typename _Iterator::difference_type difference_type;
|
||||
typedef typename _Iterator::iterator_category iterator_category;
|
||||
typedef T value_type;
|
||||
typedef T* pointer;
|
||||
typedef T& reference;
|
||||
|
||||
// Construct a singular iterator.
|
||||
AIListIterator(void) : mContainer(NULL) { }
|
||||
|
||||
// Construct an iterator to a given element of std::list. Only for internal use by AIList<T>.
|
||||
AIListIterator(_Container* __c, _Iterator const& __i) : mContainer(__c), mIterator(__i)
|
||||
{
|
||||
llassert(mContainer);
|
||||
ref();
|
||||
}
|
||||
|
||||
// Copy constructor.
|
||||
AIListIterator(AIListIterator const& __i) : mContainer(__i.mContainer), mIterator(__i.mIterator)
|
||||
{
|
||||
ref();
|
||||
}
|
||||
|
||||
// Destructor.
|
||||
~AIListIterator()
|
||||
{
|
||||
unref();
|
||||
}
|
||||
|
||||
// Assignment operator.
|
||||
_Self& operator=(_Self const& __x)
|
||||
{
|
||||
unref(); // We no longer point to whatever we were pointing.
|
||||
mContainer = __x.mContainer;
|
||||
mIterator = __x.mIterator;
|
||||
llassert(mContainer);
|
||||
ref(); // We now point an(other) element.
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Dereference operator.
|
||||
reference operator*() const
|
||||
{
|
||||
// Iterator may not be singular or dead.
|
||||
llassert(mContainer && !mIterator->dead);
|
||||
return mIterator->mElement;
|
||||
}
|
||||
|
||||
// Dereference operator.
|
||||
pointer operator->() const
|
||||
{
|
||||
// Iterator may not be singular or dead.
|
||||
llassert(mContainer && !mIterator->dead);
|
||||
return &mIterator->mElement;
|
||||
}
|
||||
|
||||
// Pre-increment operator (not being singular is implied).
|
||||
_Self& operator++()
|
||||
{
|
||||
_Iterator cur = mIterator; // Make copy of mIterator.
|
||||
++cur; // Advance it.
|
||||
unref(); // We will no longer be pointing to this element. This might invalidate mIterator!
|
||||
while(cur != mContainer->end() && cur->dead) // Advance till the first non-dead element.
|
||||
{
|
||||
++cur;
|
||||
}
|
||||
mIterator = cur; // Put result back into mIterator.
|
||||
ref(); // We are now pointing to a valid element again.
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Post-increment operator (not being singular is implied).
|
||||
_Self operator++(int)
|
||||
{
|
||||
_Self tmp = *this;
|
||||
this->operator++();
|
||||
return tmp;
|
||||
}
|
||||
|
||||
// Pre-decrement operator (not being singular is implied).
|
||||
_Self& operator--()
|
||||
{
|
||||
_Iterator cur = mIterator; // See operator++().
|
||||
--cur;
|
||||
unref();
|
||||
while(cur->dead)
|
||||
{
|
||||
--cur;
|
||||
}
|
||||
mIterator = cur;
|
||||
ref();
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Post-decrement operator (not being singular is implied).
|
||||
_Self operator--(int)
|
||||
{
|
||||
_Self tmp = *this;
|
||||
this->operator--();
|
||||
return tmp;
|
||||
}
|
||||
|
||||
// Equivalence operators.
|
||||
// We allow comparing with dead iterators, because if one of them is not-dead
|
||||
// then the result is "unequal" anyway, which is probably what you want.
|
||||
bool operator==(_Self const& __x) const { return mIterator == __x.mIterator; }
|
||||
bool operator!=(_Self const& __x) const { return mIterator != __x.mIterator; }
|
||||
|
||||
friend class AIList<T>;
|
||||
friend class AIConstListIterator<T>;
|
||||
template<typename T2> friend bool operator==(AIListIterator<T2> const& __x, AIConstListIterator<T2> const& __y);
|
||||
template<typename T2> friend bool operator!=(AIListIterator<T2> const& __x, AIConstListIterator<T2> const& __y);
|
||||
|
||||
// Return the total number of iterators pointing the element that this iterator is pointing to.
|
||||
// Unless the iterator points to end, a positive number will be returned since this iterator is
|
||||
// pointing to the element. If it points to end (or is singular) then 0 is returned.
|
||||
int count(void) const
|
||||
{
|
||||
if (mContainer && mIterator != mContainer->end())
|
||||
{
|
||||
return mIterator->count;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* AIConstListIterator<T>
|
||||
*
|
||||
* A const iterator to an element of AIList<T>.
|
||||
*
|
||||
* Because this class is very simular to AIListIterator<T>, see above for detailed comments.
|
||||
*/
|
||||
template<typename T>
|
||||
class AIConstListIterator {
|
||||
private:
|
||||
typedef AIConstListIterator<T> _Self;
|
||||
typedef std::list<AINode<T> > _Container;
|
||||
typedef typename _Container::iterator _Iterator;
|
||||
typedef typename _Container::const_iterator _ConstIterator;
|
||||
typedef AIListIterator<T> iterator;
|
||||
|
||||
_Container const* mContainer;
|
||||
_Iterator mConstIterator; // This has to be an _Iterator instead of _ConstIterator, because the compiler doesn't accept a const_iterator for erase yet (C++11 does).
|
||||
|
||||
void ref(void)
|
||||
{
|
||||
if (mContainer && mContainer->end() != mConstIterator)
|
||||
{
|
||||
llassert(mConstIterator->count < 100);
|
||||
mConstIterator->count++;
|
||||
}
|
||||
}
|
||||
|
||||
void unref(void)
|
||||
{
|
||||
if (mContainer && mContainer->end() != mConstIterator)
|
||||
{
|
||||
llassert(mConstIterator->count > 0);
|
||||
mConstIterator->count--;
|
||||
if (mConstIterator->count == 0 && mConstIterator->dead)
|
||||
{
|
||||
const_cast<_Container*>(mContainer)->erase(mConstIterator);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
typedef typename _ConstIterator::difference_type difference_type;
|
||||
typedef typename _ConstIterator::iterator_category iterator_category;
|
||||
typedef T value_type;
|
||||
typedef T const* pointer;
|
||||
typedef T const& reference;
|
||||
|
||||
AIConstListIterator(void) : mContainer(NULL) { }
|
||||
AIConstListIterator(_Container const* __c, _Iterator const& __i) : mContainer(__c), mConstIterator(__i)
|
||||
{
|
||||
llassert(mContainer);
|
||||
ref();
|
||||
}
|
||||
// Allow to construct a const_iterator from an iterator.
|
||||
AIConstListIterator(iterator const& __x) : mContainer(__x.mContainer), mConstIterator(__x.mIterator)
|
||||
{
|
||||
ref();
|
||||
}
|
||||
AIConstListIterator(AIConstListIterator const& __i) : mContainer(__i.mContainer), mConstIterator(__i.mConstIterator)
|
||||
{
|
||||
ref();
|
||||
}
|
||||
~AIConstListIterator()
|
||||
{
|
||||
unref();
|
||||
}
|
||||
|
||||
_Self& operator=(_Self const& __x)
|
||||
{
|
||||
unref();
|
||||
mContainer = __x.mContainer;
|
||||
mConstIterator = __x.mConstIterator;
|
||||
llassert(mContainer);
|
||||
ref();
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Allow to assign from a non-const iterator.
|
||||
_Self& operator=(iterator const& __x)
|
||||
{
|
||||
unref();
|
||||
mContainer = __x.mContainer;
|
||||
mConstIterator = __x.mIterator;
|
||||
llassert(mContainer);
|
||||
ref();
|
||||
return *this;
|
||||
}
|
||||
|
||||
reference operator*() const
|
||||
{
|
||||
llassert(mContainer && !mConstIterator->dead);
|
||||
return mConstIterator->mElement;
|
||||
}
|
||||
|
||||
pointer operator->() const
|
||||
{
|
||||
llassert(mContainer && !mConstIterator->dead);
|
||||
return &mConstIterator->mElement;
|
||||
}
|
||||
|
||||
_Self& operator++()
|
||||
{
|
||||
_Iterator cur = mConstIterator;
|
||||
++cur;
|
||||
unref();
|
||||
while(cur != mContainer->end() && cur->dead)
|
||||
{
|
||||
++cur;
|
||||
}
|
||||
mConstIterator = cur;
|
||||
ref();
|
||||
return *this;
|
||||
}
|
||||
|
||||
_Self operator++(int)
|
||||
{
|
||||
_Self tmp = *this;
|
||||
this->operator++();
|
||||
return tmp;
|
||||
}
|
||||
|
||||
_Self& operator--()
|
||||
{
|
||||
_Iterator cur = mConstIterator;
|
||||
--cur;
|
||||
unref();
|
||||
while(cur->dead)
|
||||
{
|
||||
--cur;
|
||||
}
|
||||
mConstIterator = cur;
|
||||
ref();
|
||||
return *this;
|
||||
}
|
||||
|
||||
_Self operator--(int)
|
||||
{
|
||||
_Self tmp = *this;
|
||||
this->operator--();
|
||||
return tmp;
|
||||
}
|
||||
|
||||
bool operator==(_Self const& __x) const { return mConstIterator == __x.mConstIterator; }
|
||||
bool operator!=(_Self const& __x) const { return mConstIterator != __x.mConstIterator; }
|
||||
bool operator==(iterator const& __x) const { return mConstIterator == __x.mIterator; }
|
||||
bool operator!=(iterator const& __x) const { return mConstIterator != __x.mIterator; }
|
||||
|
||||
template<typename T2> friend bool operator==(AIListIterator<T2> const& __x, AIConstListIterator<T2> const& __y);
|
||||
template<typename T2> friend bool operator!=(AIListIterator<T2> const& __x, AIConstListIterator<T2> const& __y);
|
||||
|
||||
int count(void) const
|
||||
{
|
||||
if (mContainer && mConstIterator != mContainer->end())
|
||||
{
|
||||
return mConstIterator->count;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
inline bool operator==(AIListIterator<T> const& __x, AIConstListIterator<T> const& __y)
|
||||
{
|
||||
return __x.mIterator == __y.mConstIterator;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline bool operator!=(AIListIterator<T> const& __x, AIConstListIterator<T> const& __y)
|
||||
{
|
||||
return __x.mIterator != __y.mConstIterator;
|
||||
}
|
||||
|
||||
/*
|
||||
* AIList<T>
|
||||
*
|
||||
* A linked list that allows elements to be erased while one or more iterators
|
||||
* are still pointing to that element, after which pre-increment and pre-decrement
|
||||
* operators still work.
|
||||
*
|
||||
* For example:
|
||||
*
|
||||
* for (AIList<int>::iterator i = l.begin(); i != l.end(); ++i)
|
||||
* {
|
||||
* int x = *i;
|
||||
* f(i); // Might erase any element of list l.
|
||||
* // Should not dereference i anymore here (because it might be erased).
|
||||
* }
|
||||
*/
|
||||
template<typename T>
|
||||
class AIList {
|
||||
private:
|
||||
typedef std::list<AINode<T> > _Container;
|
||||
typedef typename _Container::iterator _Iterator;
|
||||
typedef typename _Container::const_iterator _ConstIterator;
|
||||
|
||||
_Container mContainer;
|
||||
size_t mSize;
|
||||
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef T* pointer;
|
||||
typedef T const* const_pointer;
|
||||
typedef T& reference;
|
||||
typedef T const& const_reference;
|
||||
typedef AIListIterator<T> iterator;
|
||||
typedef AIConstListIterator<T> const_iterator;
|
||||
typedef std::reverse_iterator<iterator> reverse_iterator;
|
||||
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
typedef size_t size_type;
|
||||
typedef ptrdiff_t difference_type;
|
||||
|
||||
// Default constructor. Create an empty list.
|
||||
AIList(void) : mSize(0) { }
|
||||
#ifdef LL_DEBUG
|
||||
// Destructor calls clear() to check if there are no iterators left pointing to this list. Destructing an empty list is trivial.
|
||||
~AIList() { clear(); }
|
||||
#endif
|
||||
|
||||
// Construct a list with __n elements of __val.
|
||||
explicit AIList(size_type __n, value_type const& __val = value_type()) : mContainer(__n, AINode<T>(__val)), mSize(__n) { }
|
||||
|
||||
// Copy constructor.
|
||||
AIList(AIList const& __list) : mSize(0)
|
||||
{
|
||||
for (_ConstIterator __i = __list.mContainer.begin(); __i != __list.mContainer.end(); ++__i)
|
||||
{
|
||||
if (!__i->dead)
|
||||
{
|
||||
mContainer.push_back(AINode<T>(__i->mElement));
|
||||
++mSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Construct a list from the range [__first, __last>.
|
||||
template<typename _InputIterator>
|
||||
AIList(_InputIterator __first, _InputIterator __last) : mSize(0)
|
||||
{
|
||||
for (_InputIterator __i = __first; __i != __last; ++__i)
|
||||
{
|
||||
mContainer.push_back(AINode<T>(*__i));
|
||||
++mSize;
|
||||
}
|
||||
}
|
||||
|
||||
// Assign from another list.
|
||||
AIList& operator=(AIList const& __list)
|
||||
{
|
||||
clear();
|
||||
for (_ConstIterator __i = __list.mContainer.begin(); __i != __list.mContainer.end(); ++__i)
|
||||
{
|
||||
if (!__i->dead)
|
||||
{
|
||||
mContainer.push_back(AINode<T>(__i->mElement));
|
||||
++mSize;
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
iterator begin()
|
||||
{
|
||||
_Iterator __i = mContainer.begin();
|
||||
while(__i != mContainer.end() && __i->dead)
|
||||
{
|
||||
++__i;
|
||||
}
|
||||
return iterator(&mContainer, __i);
|
||||
}
|
||||
|
||||
const_iterator begin() const
|
||||
{
|
||||
_Iterator __i = const_cast<_Container&>(mContainer).begin();
|
||||
while(__i != mContainer.end() && __i->dead)
|
||||
{
|
||||
++__i;
|
||||
}
|
||||
return const_iterator(&mContainer, __i);
|
||||
}
|
||||
|
||||
iterator end() { return iterator(&mContainer, mContainer.end()); }
|
||||
const_iterator end() const { return const_iterator(&mContainer, const_cast<_Container&>(mContainer).end()); }
|
||||
reverse_iterator rbegin() { return reverse_iterator(end()); }
|
||||
const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
|
||||
reverse_iterator rend() { return reverse_iterator(begin()); }
|
||||
const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
|
||||
|
||||
bool empty() const { return mSize == 0; }
|
||||
size_type size() const { return mSize; }
|
||||
size_type max_size() const { return mContainer.max_size(); }
|
||||
|
||||
reference front() { iterator __i = begin(); return *__i; }
|
||||
const_reference front() const { const_iterator __i = begin(); return *__i; }
|
||||
reference back() { iterator __i = end(); --__i; return *__i; }
|
||||
const_reference back() const { const_iterator __i = end(); --__i; return *__i; }
|
||||
|
||||
void push_front(value_type const& __x)
|
||||
{
|
||||
mContainer.push_front(AINode<T>(__x));
|
||||
++mSize;
|
||||
}
|
||||
void pop_front()
|
||||
{
|
||||
iterator __i = begin();
|
||||
erase(__i);
|
||||
}
|
||||
void push_back(value_type const& __x)
|
||||
{
|
||||
mContainer.push_back(AINode<T>(__x));
|
||||
++mSize;
|
||||
}
|
||||
void pop_back()
|
||||
{
|
||||
iterator __i = end();
|
||||
--__i;
|
||||
erase(__i);
|
||||
}
|
||||
|
||||
iterator insert(iterator __position, value_type const& __x)
|
||||
{
|
||||
++mSize;
|
||||
return iterator(&mContainer, mContainer.insert(__position.mIterator, AINode<T>(__x)));
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
#ifdef LL_DEBUG
|
||||
// There should be no iterators left pointing at any element here.
|
||||
for (_Iterator __i = mContainer.begin(); __i != mContainer.end(); ++__i)
|
||||
{
|
||||
llassert(__i->count == 0);
|
||||
}
|
||||
#endif
|
||||
mContainer.clear();
|
||||
mSize = 0;
|
||||
}
|
||||
|
||||
iterator erase(iterator __position)
|
||||
{
|
||||
// Mark the element __position points to as being erased.
|
||||
// Iterator may not be singular, point to end, or be dead already.
|
||||
// Obviously count must be larger than zero since __position is still pointing to it.
|
||||
llassert(__position.mContainer == &mContainer && __position.mIterator != mContainer.end() && __position.mIterator->count > 0 && !__position.mIterator->dead);
|
||||
__position.mIterator->dead = 1;
|
||||
--mSize;
|
||||
return ++__position;
|
||||
}
|
||||
|
||||
// Remove all elements, designated by the iterator where, for which *where == __val.
|
||||
void remove(value_type const& __val)
|
||||
{
|
||||
_Iterator const __e = mContainer.end();
|
||||
for (_Iterator __i = mContainer.begin(); __i != __e;)
|
||||
{
|
||||
if (!__i->dead && __i->mElement == __val)
|
||||
{
|
||||
--mSize;
|
||||
if (__i->count == 0)
|
||||
{
|
||||
mContainer.erase(__i++);
|
||||
continue;
|
||||
}
|
||||
// Mark the element as being erased.
|
||||
__i->dead = 1;
|
||||
}
|
||||
++__i;
|
||||
}
|
||||
}
|
||||
|
||||
void sort()
|
||||
{
|
||||
#ifdef LL_DEBUG
|
||||
// There should be no iterators left pointing at any element here.
|
||||
for (_Iterator __i = mContainer.begin(); __i != mContainer.end(); ++__i)
|
||||
{
|
||||
llassert(__i->count == 0);
|
||||
}
|
||||
#endif
|
||||
mContainer.sort();
|
||||
}
|
||||
template<typename _StrictWeakOrdering>
|
||||
struct PredWrapper
|
||||
{
|
||||
_StrictWeakOrdering mPred;
|
||||
PredWrapper(_StrictWeakOrdering const& pred) : mPred(pred) { }
|
||||
bool operator()(AINode<T> const& __x, AINode<T> const& __y) const { return mPred(__x.mElement, __y.mElement); }
|
||||
};
|
||||
template<typename _StrictWeakOrdering>
|
||||
void sort(_StrictWeakOrdering const& pred)
|
||||
{
|
||||
#ifdef LL_DEBUG
|
||||
// There should be no iterators left pointing at any element here.
|
||||
for (_Iterator __i = mContainer.begin(); __i != mContainer.end(); ++__i)
|
||||
{
|
||||
llassert(__i->count == 0);
|
||||
}
|
||||
#endif
|
||||
mContainer.sort(PredWrapper<_StrictWeakOrdering>(pred));
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -911,6 +911,8 @@ void LLFloater::setMinimized(BOOL minimize)
|
||||
|
||||
// Lose keyboard focus when minimized
|
||||
releaseFocus();
|
||||
// Also reset mLockedView and mLastKeyboardFocus, to avoid that we get focus back somehow.
|
||||
gFocusMgr.removeKeyboardFocusWithoutCallback(this);
|
||||
|
||||
for (S32 i = 0; i < 4; i++)
|
||||
{
|
||||
|
||||
@@ -55,6 +55,8 @@ BOOL LLFocusableElement::handleUnicodeChar(llwchar uni_char, BOOL called_from_pa
|
||||
// virtual
|
||||
LLFocusableElement::~LLFocusableElement()
|
||||
{
|
||||
// Make sure nothing is pointing to us anymore!
|
||||
gFocusMgr.removeKeyboardFocusWithoutCallback(this);
|
||||
delete mFocusLostCallback;
|
||||
delete mFocusReceivedCallback;
|
||||
delete mFocusChangedCallback;
|
||||
@@ -131,6 +133,7 @@ LLFocusMgr::LLFocusMgr()
|
||||
mKeyboardFocus( NULL ),
|
||||
mLastKeyboardFocus( NULL ),
|
||||
mDefaultKeyboardFocus( NULL ),
|
||||
mLastDefaultKeyboardFocus( NULL ),
|
||||
mKeystrokesOnly(FALSE),
|
||||
mTopCtrl( NULL ),
|
||||
mAppHasFocus(TRUE), // Macs don't seem to notify us that we've gotten focus, so default to true
|
||||
@@ -171,6 +174,23 @@ void LLFocusMgr::releaseFocusIfNeeded( const LLView* view )
|
||||
}
|
||||
}
|
||||
|
||||
void LLFocusMgr::restoreDefaultKeyboardFocus(LLFocusableElement* current_default_focus)
|
||||
{
|
||||
if (current_default_focus && mDefaultKeyboardFocus == current_default_focus)
|
||||
{
|
||||
setDefaultKeyboardFocus(mLastDefaultKeyboardFocus);
|
||||
mLastDefaultKeyboardFocus = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void LLFocusMgr::restoreKeyboardFocus(LLFocusableElement* current_focus)
|
||||
{
|
||||
if (current_focus && mKeyboardFocus == current_focus)
|
||||
{
|
||||
setKeyboardFocus(mLastKeyboardFocus);
|
||||
mLastKeyboardFocus = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void LLFocusMgr::setKeyboardFocus(LLFocusableElement* new_focus, BOOL lock, BOOL keystrokes_only)
|
||||
{
|
||||
@@ -328,11 +348,22 @@ void LLFocusMgr::removeKeyboardFocusWithoutCallback( const LLFocusableElement* f
|
||||
{
|
||||
mLockedView = NULL;
|
||||
}
|
||||
|
||||
if( mKeyboardFocus == focus )
|
||||
if (mKeyboardFocus == focus)
|
||||
{
|
||||
mKeyboardFocus = NULL;
|
||||
}
|
||||
if (mLastKeyboardFocus == focus)
|
||||
{
|
||||
mLastKeyboardFocus = NULL;
|
||||
}
|
||||
if (mDefaultKeyboardFocus == focus)
|
||||
{
|
||||
mDefaultKeyboardFocus = NULL;
|
||||
}
|
||||
if (mLastDefaultKeyboardFocus == focus)
|
||||
{
|
||||
mLastDefaultKeyboardFocus = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -84,6 +84,7 @@ public:
|
||||
|
||||
// Keyboard Focus
|
||||
void setKeyboardFocus(LLFocusableElement* new_focus, BOOL lock = FALSE, BOOL keystrokes_only = FALSE); // new_focus = NULL to release the focus.
|
||||
void restoreKeyboardFocus(LLFocusableElement* current_focus);
|
||||
LLFocusableElement* getKeyboardFocus() const { return mKeyboardFocus; }
|
||||
LLFocusableElement* getLastKeyboardFocus() const { return mLastKeyboardFocus; }
|
||||
BOOL childHasKeyboardFocus( const LLView* parent ) const;
|
||||
@@ -103,7 +104,8 @@ public:
|
||||
|
||||
// If setKeyboardFocus(NULL) is called, and there is a non-NULL default
|
||||
// keyboard focus view, focus goes there. JC
|
||||
void setDefaultKeyboardFocus(LLFocusableElement* default_focus) { mDefaultKeyboardFocus = default_focus; }
|
||||
void setDefaultKeyboardFocus(LLFocusableElement* default_focus) { mLastDefaultKeyboardFocus = mDefaultKeyboardFocus; mDefaultKeyboardFocus = default_focus; }
|
||||
void restoreDefaultKeyboardFocus(LLFocusableElement* current_default_focus);
|
||||
LLFocusableElement* getDefaultKeyboardFocus() const { return mDefaultKeyboardFocus; }
|
||||
|
||||
|
||||
@@ -132,6 +134,7 @@ private:
|
||||
LLFocusableElement* mKeyboardFocus; // Keyboard events are preemptively routed to this object
|
||||
LLFocusableElement* mLastKeyboardFocus; // who last had focus
|
||||
LLFocusableElement* mDefaultKeyboardFocus;
|
||||
LLFocusableElement* mLastDefaultKeyboardFocus;
|
||||
BOOL mKeystrokesOnly;
|
||||
|
||||
// Top View
|
||||
|
||||
@@ -1945,7 +1945,7 @@ void LLMenuGL::parseChildXML(LLXMLNodePtr child, LLView *parent, LLUICtrlFactory
|
||||
{
|
||||
// SUBMENU
|
||||
LLMenuGL *submenu = (LLMenuGL*)LLMenuGL::fromXML(child, parent, factory);
|
||||
appendMenu(submenu);
|
||||
appendMenu(submenu, 0);
|
||||
if (LLMenuGL::sMenuContainer != NULL)
|
||||
{
|
||||
submenu->updateParent(LLMenuGL::sMenuContainer);
|
||||
@@ -2214,18 +2214,27 @@ void LLMenuGL::parseChildXML(LLXMLNodePtr child, LLView *parent, LLUICtrlFactory
|
||||
}
|
||||
}
|
||||
|
||||
// This wrapper is needed because the virtual linkage causes errors if default parameters are used
|
||||
bool LLMenuGL::addChild(LLView* view, S32 tab_group)
|
||||
{
|
||||
return addChild(view, 0, tab_group);
|
||||
}
|
||||
|
||||
bool LLMenuGL::addChild(LLView* view, LLView* insert_before, S32 tab_group)
|
||||
{
|
||||
if (LLMenuGL* menup = dynamic_cast<LLMenuGL*>(view))
|
||||
{
|
||||
lldebugs << "Adding menu " << menup->getName() << " to " << getName() << llendl;
|
||||
appendMenu(menup);
|
||||
if (!insert_before)
|
||||
appendMenu(menup);
|
||||
else
|
||||
appendMenu(menup, insert_before);
|
||||
return true;
|
||||
}
|
||||
else if (LLMenuItemGL* itemp = dynamic_cast<LLMenuItemGL*>(view))
|
||||
{
|
||||
lldebugs << "Adding " << itemp->getName() << " to " << getName() << llendl;
|
||||
append(itemp);
|
||||
append(itemp, insert_before);
|
||||
return true;
|
||||
}
|
||||
lldebugs << "Error adding unknown child '"<<(view ? view->getName() : std::string("NULL")) << "' to " << getName() << llendl;
|
||||
@@ -2712,10 +2721,29 @@ BOOL LLMenuGL::handleJumpKey(KEY key)
|
||||
|
||||
|
||||
// Add the menu item to this menu.
|
||||
// This wrapper is needed because the virtual linkage causes errors if default parameters are used
|
||||
BOOL LLMenuGL::append( LLMenuItemGL* item )
|
||||
{
|
||||
return append(item, 0);
|
||||
}
|
||||
|
||||
BOOL LLMenuGL::append(LLMenuItemGL* item, LLView* insert_before)
|
||||
{
|
||||
if (!item) return FALSE;
|
||||
if (!insert_before)
|
||||
{
|
||||
mItems.push_back( item );
|
||||
}
|
||||
else
|
||||
{
|
||||
item_list_t::iterator i;
|
||||
|
||||
for (i = mItems.begin(); i != mItems.end(); ++i)
|
||||
if (*i == insert_before)
|
||||
break;
|
||||
mItems.insert(i, item);
|
||||
}
|
||||
|
||||
LLUICtrl::addChild(item);
|
||||
needsArrange();
|
||||
return TRUE;
|
||||
@@ -2729,7 +2757,13 @@ BOOL LLMenuGL::addSeparator()
|
||||
}
|
||||
|
||||
// add a menu - this will create a cascading menu
|
||||
// This wrapper is needed because the virtual linkage causes errors if default parameters are used
|
||||
BOOL LLMenuGL::appendMenu( LLMenuGL* menu )
|
||||
{
|
||||
return appendMenu(menu, 0);
|
||||
}
|
||||
|
||||
BOOL LLMenuGL::appendMenu(LLMenuGL* menu, LLView* insert_before)
|
||||
{
|
||||
if( menu == this )
|
||||
{
|
||||
@@ -2741,7 +2775,7 @@ BOOL LLMenuGL::appendMenu( LLMenuGL* menu )
|
||||
LLMenuItemBranchGL* branch = NULL;
|
||||
branch = new LLMenuItemBranchGL( menu->getName(), menu->getLabel(), menu->getHandle() );
|
||||
branch->setJumpKey(menu->getJumpKey());
|
||||
success &= append( branch );
|
||||
success &= append( branch, insert_before );
|
||||
|
||||
// Inherit colors
|
||||
menu->setBackgroundColor( mBackgroundColor );
|
||||
|
||||
@@ -476,6 +476,8 @@ public:
|
||||
/*virtual*/ void removeChild( LLView* ctrl);
|
||||
/*virtual*/ BOOL postBuild();
|
||||
|
||||
bool addChild(LLView* view, LLView* insert_before, S32 tab_group = 0);
|
||||
|
||||
virtual BOOL handleAcceleratorKey(KEY key, MASK mask);
|
||||
|
||||
LLMenuGL* getChildMenuByName(const std::string& name, BOOL recurse) const;
|
||||
@@ -572,11 +574,14 @@ public:
|
||||
protected:
|
||||
void createSpilloverBranch();
|
||||
void cleanupSpilloverBranch();
|
||||
|
||||
// Add the menu item to this menu.
|
||||
virtual BOOL append( LLMenuItemGL* item );
|
||||
BOOL append(LLMenuItemGL* item, LLView* insert_before);
|
||||
|
||||
// add a menu - this will create a cascading menu
|
||||
virtual BOOL appendMenu( LLMenuGL* menu );
|
||||
BOOL appendMenu(LLMenuGL* menu, LLView* insert_before);
|
||||
|
||||
// TODO: create accessor methods for these?
|
||||
typedef std::list< LLMenuItemGL* > item_list_t;
|
||||
|
||||
@@ -77,7 +77,8 @@ LLScrollableContainerView::LLScrollableContainerView( const std::string& name,
|
||||
mReserveScrollCorner( FALSE ),
|
||||
mMinAutoScrollRate( MIN_AUTO_SCROLL_RATE ),
|
||||
mMaxAutoScrollRate( MAX_AUTO_SCROLL_RATE ),
|
||||
mScrolledView( scrolled_view )
|
||||
mScrolledView( scrolled_view ),
|
||||
mPassBackToChildren(true)
|
||||
{
|
||||
if( mScrolledView )
|
||||
{
|
||||
@@ -218,7 +219,7 @@ BOOL LLScrollableContainerView::handleScrollWheel( S32 x, S32 y, S32 clicks )
|
||||
{
|
||||
// Give event to my child views - they may have scroll bars
|
||||
// (Bad UI design, but technically possible.)
|
||||
if (LLUICtrl::handleScrollWheel(x,y,clicks))
|
||||
if (mPassBackToChildren && LLUICtrl::handleScrollWheel(x,y,clicks))
|
||||
return TRUE;
|
||||
|
||||
// When the vertical scrollbar is visible, scroll wheel
|
||||
|
||||
@@ -70,6 +70,7 @@ public:
|
||||
virtual void setValue(const LLSD& value) { mInnerRect.setValue(value); }
|
||||
|
||||
void setBorderVisible( BOOL b );
|
||||
void setPassBackToChildren(bool b) { mPassBackToChildren = b; }
|
||||
|
||||
void scrollToShowRect( const LLRect& rect, const LLRect& constraint);
|
||||
void scrollToShowRect( const LLRect& rect) { scrollToShowRect(rect, LLRect(0, mInnerRect.getHeight(), mInnerRect.getWidth(), 0)); }
|
||||
@@ -128,6 +129,7 @@ private:
|
||||
F32 mMinAutoScrollRate;
|
||||
F32 mMaxAutoScrollRate;
|
||||
bool mHideScrollbar;
|
||||
bool mPassBackToChildren;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -302,8 +302,8 @@ BOOL LLUICtrl::focusFirstItem(BOOL prefer_text_fields, BOOL focus_flash)
|
||||
LLCtrlQuery query = getTabOrderQuery();
|
||||
// sort things such that the default tab group is at the front
|
||||
query.setSorter(DefaultTabGroupFirstSorter::getInstance());
|
||||
child_list_t result = query(this);
|
||||
if(result.size() > 0)
|
||||
viewList_t result = query(this);
|
||||
if(!result.empty())
|
||||
{
|
||||
LLUICtrl * ctrl = static_cast<LLUICtrl*>(result.front());
|
||||
if(!ctrl->hasFocus())
|
||||
@@ -322,7 +322,7 @@ BOOL LLUICtrl::focusFirstItem(BOOL prefer_text_fields, BOOL focus_flash)
|
||||
{
|
||||
LLCtrlQuery query = getTabOrderQuery();
|
||||
query.addPreFilter(LLUICtrl::LLTextInputFilter::getInstance());
|
||||
child_list_t result = query(this);
|
||||
viewList_t result = query(this);
|
||||
if(result.size() > 0)
|
||||
{
|
||||
LLUICtrl * ctrl = static_cast<LLUICtrl*>(result.front());
|
||||
@@ -358,7 +358,7 @@ BOOL LLUICtrl::focusLastItem(BOOL prefer_text_fields)
|
||||
{
|
||||
LLCtrlQuery query = getTabOrderQuery();
|
||||
query.addPreFilter(LLUICtrl::LLTextInputFilter::getInstance());
|
||||
child_list_t result = query(this);
|
||||
viewList_t result = query(this);
|
||||
if(result.size() > 0)
|
||||
{
|
||||
LLUICtrl * ctrl = static_cast<LLUICtrl*>(result.back());
|
||||
@@ -372,7 +372,7 @@ BOOL LLUICtrl::focusLastItem(BOOL prefer_text_fields)
|
||||
}
|
||||
}
|
||||
// no text field found, or we don't care about text fields
|
||||
child_list_t result = getTabOrderQuery().run(this);
|
||||
viewList_t result = getTabOrderQuery().run(this);
|
||||
if(result.size() > 0)
|
||||
{
|
||||
LLUICtrl * ctrl = static_cast<LLUICtrl*>(result.back());
|
||||
@@ -395,7 +395,7 @@ BOOL LLUICtrl::focusNextItem(BOOL text_fields_only)
|
||||
{
|
||||
query.addPreFilter(LLUICtrl::LLTextInputFilter::getInstance());
|
||||
}
|
||||
child_list_t result = query(this);
|
||||
viewList_t result = query(this);
|
||||
return focusNext(result);
|
||||
}
|
||||
|
||||
@@ -407,7 +407,7 @@ BOOL LLUICtrl::focusPrevItem(BOOL text_fields_only)
|
||||
{
|
||||
query.addPreFilter(LLUICtrl::LLTextInputFilter::getInstance());
|
||||
}
|
||||
child_list_t result = query(this);
|
||||
viewList_t result = query(this);
|
||||
return focusPrev(result);
|
||||
}
|
||||
|
||||
|
||||
@@ -518,21 +518,21 @@ LLRect LLView::getRequiredRect()
|
||||
|
||||
BOOL LLView::focusNextRoot()
|
||||
{
|
||||
LLView::child_list_t result = LLView::getFocusRootsQuery().run(this);
|
||||
viewList_t result = LLView::getFocusRootsQuery().run(this);
|
||||
return LLView::focusNext(result);
|
||||
}
|
||||
|
||||
BOOL LLView::focusPrevRoot()
|
||||
{
|
||||
LLView::child_list_t result = LLView::getFocusRootsQuery().run(this);
|
||||
viewList_t result = LLView::getFocusRootsQuery().run(this);
|
||||
return LLView::focusPrev(result);
|
||||
}
|
||||
|
||||
// static
|
||||
BOOL LLView::focusNext(LLView::child_list_t & result)
|
||||
BOOL LLView::focusNext(viewList_t& result)
|
||||
{
|
||||
LLView::child_list_iter_t focused = result.end();
|
||||
for(LLView::child_list_iter_t iter = result.begin();
|
||||
viewList_t::iterator focused = result.end();
|
||||
for(viewList_t::iterator iter = result.begin();
|
||||
iter != result.end();
|
||||
++iter)
|
||||
{
|
||||
@@ -542,7 +542,7 @@ BOOL LLView::focusNext(LLView::child_list_t & result)
|
||||
break;
|
||||
}
|
||||
}
|
||||
LLView::child_list_iter_t next = focused;
|
||||
viewList_t::iterator next = focused;
|
||||
next = (next == result.end()) ? result.begin() : ++next;
|
||||
while(next != focused)
|
||||
{
|
||||
@@ -565,10 +565,10 @@ BOOL LLView::focusNext(LLView::child_list_t & result)
|
||||
}
|
||||
|
||||
// static
|
||||
BOOL LLView::focusPrev(LLView::child_list_t & result)
|
||||
BOOL LLView::focusPrev(viewList_t& result)
|
||||
{
|
||||
LLView::child_list_reverse_iter_t focused = result.rend();
|
||||
for(LLView::child_list_reverse_iter_t iter = result.rbegin();
|
||||
viewList_t::reverse_iterator focused = result.rend();
|
||||
for(viewList_t::reverse_iterator iter = result.rbegin();
|
||||
iter != result.rend();
|
||||
++iter)
|
||||
{
|
||||
@@ -578,7 +578,7 @@ BOOL LLView::focusPrev(LLView::child_list_t & result)
|
||||
break;
|
||||
}
|
||||
}
|
||||
LLView::child_list_reverse_iter_t next = focused;
|
||||
viewList_t::reverse_iterator next = focused;
|
||||
next = (next == result.rend()) ? result.rbegin() : ++next;
|
||||
while(next != focused)
|
||||
{
|
||||
@@ -1170,16 +1170,13 @@ void LLView::drawChildren()
|
||||
LLView* rootp = getRootView();
|
||||
++sDepth;
|
||||
|
||||
for (child_list_reverse_iter_t child_iter = mChildList.rbegin(); child_iter != mChildList.rend();) // ++child_iter)
|
||||
for (child_list_const_reverse_iter_t child_iter = mChildList.rbegin(); child_iter != mChildList.rend(); ++child_iter)
|
||||
{
|
||||
child_list_reverse_iter_t child = child_iter++;
|
||||
LLView *viewp = *child;
|
||||
|
||||
if (viewp == NULL)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
LLView *viewp = *child_iter;
|
||||
if (viewp == NULL)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (viewp->getVisible() && /*viewp != focus_view && */viewp->getRect().isValid())
|
||||
{
|
||||
|
||||
@@ -57,6 +57,7 @@
|
||||
#include "llinitparam.h"
|
||||
#include "llfocusmgr.h"
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include "ailist.h"
|
||||
|
||||
const U32 FOLLOWS_NONE = 0x00;
|
||||
const U32 FOLLOWS_LEFT = 0x01;
|
||||
@@ -231,7 +232,7 @@ public:
|
||||
SNAP_BOTTOM
|
||||
};
|
||||
|
||||
typedef std::list<LLView*> child_list_t;
|
||||
typedef AIList<LLView*> child_list_t;
|
||||
typedef child_list_t::iterator child_list_iter_t;
|
||||
typedef child_list_t::const_iterator child_list_const_iter_t;
|
||||
typedef child_list_t::reverse_iterator child_list_reverse_iter_t;
|
||||
@@ -582,9 +583,9 @@ public:
|
||||
static std::string escapeXML(const std::string& xml, std::string& indent);
|
||||
|
||||
// focuses the item in the list after the currently-focused item, wrapping if necessary
|
||||
static BOOL focusNext(LLView::child_list_t & result);
|
||||
static BOOL focusNext(viewList_t& result);
|
||||
// focuses the item in the list before the currently-focused item, wrapping if necessary
|
||||
static BOOL focusPrev(LLView::child_list_t & result);
|
||||
static BOOL focusPrev(viewList_t& result);
|
||||
|
||||
// returns query for iterating over controls in tab order
|
||||
static const LLCtrlQuery & getTabOrderQuery();
|
||||
|
||||
@@ -74,9 +74,10 @@ filterResult_t LLCtrlFilter::operator() (const LLView* const view, const viewLis
|
||||
viewList_t LLViewQuery::run(LLView* view) const
|
||||
{
|
||||
viewList_t result;
|
||||
viewList_t const child_list(view->getChildList()->begin(), view->getChildList()->end());
|
||||
|
||||
// prefilter gets immediate children of view
|
||||
filterResult_t pre = runFilters(view, *view->getChildList(), mPreFilters);
|
||||
filterResult_t pre = runFilters(view, child_list, mPreFilters);
|
||||
if(!pre.first && !pre.second)
|
||||
{
|
||||
// not including ourselves or the children
|
||||
@@ -113,26 +114,26 @@ viewList_t LLViewQuery::run(LLView* view) const
|
||||
|
||||
void LLViewQuery::filterChildren(LLView * view, viewList_t & filtered_children) const
|
||||
{
|
||||
LLView::child_list_t views(*(view->getChildList()));
|
||||
viewList_t views(view->getChildList()->begin(), view->getChildList()->end());
|
||||
if (mSorterp)
|
||||
{
|
||||
(*mSorterp)(view, views); // sort the children per the sorter
|
||||
}
|
||||
for(LLView::child_list_iter_t iter = views.begin();
|
||||
for(viewList_t::iterator iter = views.begin();
|
||||
iter != views.end();
|
||||
iter++)
|
||||
++iter)
|
||||
{
|
||||
viewList_t indiv_children = this->run(*iter);
|
||||
filtered_children.splice(filtered_children.end(), indiv_children);
|
||||
}
|
||||
}
|
||||
|
||||
filterResult_t LLViewQuery::runFilters(LLView * view, const viewList_t children, const filterList_t filters) const
|
||||
filterResult_t LLViewQuery::runFilters(LLView* view, viewList_t const& children, filterList_t const& filters) const
|
||||
{
|
||||
filterResult_t result = filterResult_t(TRUE, TRUE);
|
||||
for(filterList_const_iter_t iter = filters.begin();
|
||||
iter != filters.end();
|
||||
iter++)
|
||||
++iter)
|
||||
{
|
||||
filterResult_t filtered = (**iter)(view, children);
|
||||
result.first = result.first && filtered.first;
|
||||
@@ -143,7 +144,7 @@ filterResult_t LLViewQuery::runFilters(LLView * view, const viewList_t children,
|
||||
|
||||
class SortByTabOrder : public LLQuerySorter, public LLSingleton<SortByTabOrder>
|
||||
{
|
||||
/*virtual*/ void operator() (LLView * parent, LLView::child_list_t &children) const
|
||||
/*virtual*/ void operator() (LLView* parent, viewList_t& children) const
|
||||
{
|
||||
children.sort(LLCompareByTabOrder(parent->getCtrlOrder()));
|
||||
}
|
||||
|
||||
@@ -126,7 +126,7 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
filterResult_t runFilters(LLView * view, const viewList_t children, const filterList_t filters) const;
|
||||
filterResult_t runFilters(LLView* view, viewList_t const& children, filterList_t const& filters) const;
|
||||
|
||||
filterList_t mPreFilters;
|
||||
filterList_t mPostFilters;
|
||||
|
||||
@@ -99,8 +99,10 @@ typedef enum e_control_type
|
||||
|
||||
class LLControlVariable : public LLRefCount
|
||||
{
|
||||
friend class LLControlGroup;
|
||||
LOG_CLASS(LLControlVariable);
|
||||
|
||||
friend class LLControlGroup;
|
||||
|
||||
public:
|
||||
typedef boost::signals2::signal<bool(LLControlVariable* control, const LLSD&), boost_boolean_combiner> validate_signal_t;
|
||||
typedef boost::signals2::signal<void(LLControlVariable* control, const LLSD&)> commit_signal_t;
|
||||
@@ -208,6 +210,7 @@ T convert_from_llsd(const LLSD& sd, eControlType type, const std::string& contro
|
||||
//const U32 STRING_CACHE_SIZE = 10000;
|
||||
class LLControlGroup : public LLInstanceTracker<LLControlGroup, std::string>
|
||||
{
|
||||
LOG_CLASS(LLControlGroup);
|
||||
protected:
|
||||
typedef std::map<std::string, LLControlVariablePtr > ctrl_name_table_t;
|
||||
ctrl_name_table_t mNameTable;
|
||||
@@ -283,6 +286,7 @@ public:
|
||||
else
|
||||
{
|
||||
llwarns << "Control " << name << " not found." << llendl;
|
||||
return T();
|
||||
}
|
||||
return convert_from_llsd<T>(value, type, name);
|
||||
}
|
||||
@@ -313,7 +317,7 @@ public:
|
||||
}
|
||||
else
|
||||
{
|
||||
llerrs << "Invalid control " << name << llendl;
|
||||
llwarns << "Invalid control " << name << llendl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -244,6 +244,7 @@ set(viewer_SOURCE_FILES
|
||||
llfloaterregioninfo.cpp
|
||||
llfloaterreporter.cpp
|
||||
llfloaterscriptdebug.cpp
|
||||
llfloaterscriptlimits.cpp
|
||||
llfloatersearchreplace.cpp
|
||||
llfloatersellland.cpp
|
||||
llfloatersettingsdebug.cpp
|
||||
@@ -745,6 +746,7 @@ set(viewer_HEADER_FILES
|
||||
llfloaterregioninfo.h
|
||||
llfloaterreporter.h
|
||||
llfloaterscriptdebug.h
|
||||
llfloaterscriptlimits.h
|
||||
llfloatersearchreplace.h
|
||||
llfloatersellland.h
|
||||
llfloatersettingsdebug.h
|
||||
|
||||
@@ -994,7 +994,7 @@ This should be as low as possible, but too low may break functionality</string>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>TurnAroundWhenWalkingBackwards</key>
|
||||
<map>
|
||||
@@ -5768,6 +5768,84 @@ This should be as low as possible, but too low may break functionality</string>
|
||||
<key>Value</key>
|
||||
<real>10.0</real>
|
||||
</map>
|
||||
<key>FilterGamingSearchAll</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Filter results flagged gaming in everything search</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>HideFromEditor</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>FilterGamingClassifieds</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Filter results flagged gaming in classifieds search</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>HideFromEditor</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>FilterGamingEvents</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Filter results flagged gaming in event search</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>HideFromEditor</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>FilterGamingGroups</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Filter results flagged gaming in groups search</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>HideFromEditor</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>FilterGamingLand</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Filter results flagged gaming in land search</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>HideFromEditor</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>FilterGamingSims</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Filter results flagged gaming in sim search</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>HideFromEditor</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>FilterItemsPerFrame</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
@@ -7072,6 +7150,22 @@ This should be as low as possible, but too low may break functionality</string>
|
||||
<integer>0</integer>
|
||||
</array>
|
||||
</map>
|
||||
<key>FloaterScriptLimitsRect</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Rectangle for Script Limits window</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Rect</string>
|
||||
<key>Value</key>
|
||||
<array>
|
||||
<integer>0</integer>
|
||||
<integer>500</integer>
|
||||
<integer>480</integer>
|
||||
<integer>0</integer>
|
||||
</array>
|
||||
</map>
|
||||
<key>FloaterSnapshotRect</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
@@ -8732,7 +8826,7 @@ This should be as low as possible, but too low may break functionality</string>
|
||||
<key>LastSnapshotType</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Select this as next type of snapshot to take (0 = postcard, 1 = texture, 2 = local image)</string>
|
||||
<string>Select this as next type of snapshot to take (0 = feed, 1 = postcard, 2 = texture, 3 = local image)</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
@@ -14185,6 +14279,50 @@ This should be as low as possible, but too low may break functionality</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>SnapshotFeedKeepAspect</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>When adjusting feed resolution keep its aspect ratio constant and equal to the target aspect.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>SnapshotPostcardKeepAspect</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>When adjusting postcard resolution keep its aspect ratio constant and equal to the target aspect.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>SnapshotTextureKeepAspect</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>When adjusting texture resolution keep its aspect ratio constant and equal to the target aspect.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>SnapshotLocalKeepAspect</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>When adjusting local resolution keep its aspect ratio constant and equal to the target aspect.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>SnapshotOpenFreezeTime</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
||||
@@ -268,7 +268,7 @@
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>AscentUseTag</key>
|
||||
<key>AscentBroadcastTag</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Broadcast client tag</string>
|
||||
|
||||
@@ -209,7 +209,7 @@
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>RLVaWearReplaceUnlocked</key>
|
||||
<map>
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
* @file previewF.glsl
|
||||
*
|
||||
* $LicenseInfo:firstyear=2011&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2011, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifdef DEFINE_GL_FRAGCOLOR
|
||||
out vec4 frag_color;
|
||||
#else
|
||||
#define frag_color gl_FragColor
|
||||
#endif
|
||||
|
||||
uniform sampler2D diffuseMap;
|
||||
|
||||
VARYING vec4 vertex_color;
|
||||
VARYING vec2 vary_texcoord0;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 color = texture2D(diffuseMap,vary_texcoord0.xy) * vertex_color;
|
||||
frag_color = color;
|
||||
}
|
||||
@@ -32,12 +32,51 @@ ATTRIBUTE vec3 position;
|
||||
ATTRIBUTE vec3 normal;
|
||||
ATTRIBUTE vec2 texcoord0;
|
||||
|
||||
uniform vec4 color;
|
||||
|
||||
VARYING vec4 vertex_color;
|
||||
VARYING vec2 vary_texcoord0;
|
||||
|
||||
uniform vec4 light_position[8];
|
||||
uniform vec3 light_direction[8];
|
||||
uniform vec3 light_attenuation[8];
|
||||
uniform vec3 light_diffuse[8];
|
||||
|
||||
//===================================================================================================
|
||||
//declare these here explicitly to separate them from atmospheric lighting elsewhere to work around
|
||||
//drivers that are picky about functions being declared but not defined even if they aren't called
|
||||
float calcDirectionalLight(vec3 n, vec3 l)
|
||||
{
|
||||
float a = max(dot(n,l),0.0);
|
||||
return a;
|
||||
}
|
||||
|
||||
|
||||
float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float is_pointlight)
|
||||
{
|
||||
//get light vector
|
||||
vec3 lv = lp.xyz-v;
|
||||
|
||||
//get distance
|
||||
float d = length(lv);
|
||||
|
||||
//normalize light vector
|
||||
lv *= 1.0/d;
|
||||
|
||||
//distance attenuation
|
||||
float da = clamp(1.0/(la * d), 0.0, 1.0);
|
||||
|
||||
// spotlight coefficient.
|
||||
float spot = max(dot(-ln, lv), is_pointlight);
|
||||
da *= spot*spot; // GL_SPOT_EXPONENT=2
|
||||
|
||||
//angular attenuation
|
||||
da *= calcDirectionalLight(n, lv);
|
||||
|
||||
return da;
|
||||
}
|
||||
//====================================================================================================
|
||||
|
||||
vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
|
||||
void calcAtmospherics(vec3 inPositionEye);
|
||||
|
||||
void main()
|
||||
{
|
||||
@@ -45,13 +84,15 @@ void main()
|
||||
vec4 pos = (modelview_matrix * vec4(position.xyz, 1.0));
|
||||
gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
|
||||
vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
|
||||
|
||||
|
||||
vec3 norm = normalize(normal_matrix * normal);
|
||||
|
||||
calcAtmospherics(pos.xyz);
|
||||
vec4 col = vec4(0,0,0,1);
|
||||
|
||||
vec4 color = calcLighting(pos.xyz, norm, vec4(1,1,1,1), vec4(0.));
|
||||
vertex_color = color;
|
||||
|
||||
|
||||
// Collect normal lights (need to be divided by two, as we later multiply by 2)
|
||||
col.rgb += light_diffuse[1].rgb * calcDirectionalLight(norm, light_position[1].xyz);
|
||||
col.rgb += light_diffuse[2].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[2], light_direction[2], light_attenuation[2].x, light_attenuation[2].z);
|
||||
col.rgb += light_diffuse[3].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[3], light_direction[3], light_attenuation[3].x, light_attenuation[3].z);
|
||||
|
||||
vertex_color = col*color;
|
||||
}
|
||||
|
||||
@@ -193,7 +193,7 @@ void LLPrefsAscentVan::refreshValues()
|
||||
mAnnounceStreamMetadata = gSavedSettings.getBOOL("AnnounceStreamMetadata");
|
||||
|
||||
//Tags\Colors ----------------------------------------------------------------------------
|
||||
mAscentUseTag = gSavedSettings.getBOOL("AscentUseTag");
|
||||
mAscentBroadcastTag = gSavedSettings.getBOOL("AscentBroadcastTag");
|
||||
mReportClientUUID = gSavedSettings.getString("AscentReportClientUUID");
|
||||
mSelectedClient = gSavedSettings.getU32("AscentReportClientIndex");
|
||||
mShowSelfClientTag = gSavedSettings.getBOOL("AscentShowSelfTag");
|
||||
@@ -276,7 +276,7 @@ void LLPrefsAscentVan::cancel()
|
||||
gSavedSettings.setBOOL("AnnounceStreamMetadata", mAnnounceStreamMetadata);
|
||||
|
||||
//Tags\Colors ----------------------------------------------------------------------------
|
||||
gSavedSettings.setBOOL("AscentUseTag", mAscentUseTag);
|
||||
gSavedSettings.setBOOL("AscentBroadcastTag", mAscentBroadcastTag);
|
||||
gSavedSettings.setString("AscentReportClientUUID", mReportClientUUID);
|
||||
gSavedSettings.setU32("AscentReportClientIndex", mSelectedClient);
|
||||
gSavedSettings.setBOOL("AscentShowSelfTag", mShowSelfClientTag);
|
||||
|
||||
@@ -63,7 +63,7 @@ protected:
|
||||
bool mAnnounceSnapshots;
|
||||
bool mAnnounceStreamMetadata;
|
||||
//Tags\Colors
|
||||
BOOL mAscentUseTag;
|
||||
BOOL mAscentBroadcastTag;
|
||||
std::string mReportClientUUID;
|
||||
U32 mSelectedClient;
|
||||
BOOL mShowSelfClientTag;
|
||||
|
||||
@@ -357,7 +357,7 @@ std::string HippoGridInfo::getSearchUrl(SearchType ty, bool is_web) const
|
||||
}
|
||||
else if (ty == SEARCH_ALL_TEMPLATE)
|
||||
{
|
||||
return "lang=[LANG]&mat=[MATURITY]&t=[TEEN]®ion=[REGION]&x=[X]&y=[Y]&z=[Z]&session=[SESSION]";
|
||||
return "lang=[LANG]&mat=[MATURITY]&t=[TEEN]®ion=[REGION]&x=[X]&y=[Y]&z=[Z]&session=[SESSION]&dice=[DICE]";
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -400,7 +400,7 @@ std::string HippoGridInfo::getSearchUrl(SearchType ty, bool is_web) const
|
||||
}
|
||||
else if (ty == SEARCH_ALL_TEMPLATE)
|
||||
{
|
||||
return "lang=[LANG]&m=[MATURITY]&t=[TEEN]®ion=[REGION]&x=[X]&y=[Y]&z=[Z]&session=[SESSION]";
|
||||
return "lang=[LANG]&m=[MATURITY]&t=[TEEN]®ion=[REGION]&x=[X]&y=[Y]&z=[Z]&session=[SESSION]&dice=[DICE]";
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -4459,9 +4459,9 @@ void LLAgent::sendAgentSetAppearance()
|
||||
|
||||
body_size.mV[VX] += x_off;
|
||||
body_size.mV[VY] += y_off;
|
||||
body_size.mV[VZ] += z_off; // Offset by RLVa, but not overridden.
|
||||
// [RLVa:KB] - Checked: 2010-10-11 (RLVa-1.2.0e) | Added: RLVa-1.2.0e
|
||||
body_size.mV[VZ] += RlvSettings::getAvatarOffsetZ();
|
||||
F32 rlvz_off = RlvSettings::getAvatarOffsetZ();
|
||||
body_size.mV[VZ] += fabs(rlvz_off) ? rlvz_off : z_off;
|
||||
// [/RLVa:KB]
|
||||
|
||||
msg->addVector3Fast(_PREHASH_Size, body_size);
|
||||
|
||||
@@ -243,7 +243,6 @@ const F32 DEFAULT_AFK_TIMEOUT = 5.f * 60.f; // time with no input before user fl
|
||||
F32 gSimLastTime; // Used in LLAppViewer::init and send_stats()
|
||||
F32 gSimFrames;
|
||||
|
||||
BOOL gAllowIdleAFK = FALSE;
|
||||
BOOL gAllowTapTapHoldRun = TRUE;
|
||||
BOOL gShowObjectUpdates = FALSE;
|
||||
BOOL gUseQuickTime = TRUE;
|
||||
@@ -397,15 +396,16 @@ LLAppViewer::LLUpdaterInfo *LLAppViewer::sUpdaterInfo = NULL ;
|
||||
|
||||
void idle_afk_check()
|
||||
{
|
||||
static const LLCachedControl<bool> allow_idk_afk("AllowIdleAFK");
|
||||
// check idle timers
|
||||
static const LLCachedControl<F32> afk_timeout("AFKTimeout",0.f);
|
||||
//if (gAllowIdleAFK && (gAwayTriggerTimer.getElapsedTimeF32() > gSavedSettings.getF32("AFKTimeout")))
|
||||
//if (allow_idk_afk && (gAwayTriggerTimer.getElapsedTimeF32() > gSavedSettings.getF32("AFKTimeout")))
|
||||
// [RLVa:KB] - Checked: 2009-10-19 (RLVa-1.1.0g) | Added: RLVa-1.1.0g
|
||||
#ifdef RLV_EXTENSION_CMD_ALLOWIDLE
|
||||
if ( (gAllowIdleAFK || gRlvHandler.hasBehaviour(RLV_BHVR_ALLOWIDLE)) &&
|
||||
if ( (allow_idk_afk || gRlvHandler.hasBehaviour(RLV_BHVR_ALLOWIDLE)) &&
|
||||
(gAwayTriggerTimer.getElapsedTimeF32() > afk_timeout) && (afk_timeout > 0))
|
||||
#else
|
||||
if (gAllowIdleAFK && (gAwayTriggerTimer.getElapsedTimeF32() > afk_timeout) && (afk_timeout > 0))
|
||||
if (allow_idk_afk && (gAwayTriggerTimer.getElapsedTimeF32() > afk_timeout) && (afk_timeout > 0))
|
||||
#endif // RLV_EXTENSION_CMD_ALLOWIDLE
|
||||
// [/RLVa:KB]
|
||||
{
|
||||
@@ -504,7 +504,6 @@ static void settings_to_globals()
|
||||
gAgent.setHideGroupTitle(gSavedSettings.getBOOL("RenderHideGroupTitle"));
|
||||
|
||||
gDebugWindowProc = gSavedSettings.getBOOL("DebugWindowProc");
|
||||
gAllowIdleAFK = gSavedSettings.getBOOL("AllowIdleAFK");
|
||||
gAllowTapTapHoldRun = gSavedSettings.getBOOL("AllowTapTapHoldRun");
|
||||
gShowObjectUpdates = gSavedSettings.getBOOL("ShowObjectUpdates");
|
||||
LLWorldMapView::sMapScale = llmax(.1f,gSavedSettings.getF32("MapScale"));
|
||||
@@ -690,9 +689,6 @@ bool LLAppViewer::init()
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// *FIX: The following code isn't grouped into functions yet.
|
||||
|
||||
// Statistics / debug timer initialization
|
||||
init_statistics();
|
||||
|
||||
//
|
||||
// Various introspection concerning the libs we're using - particularly
|
||||
// the libs involved in getting to a full login screen.
|
||||
@@ -2678,7 +2674,6 @@ void LLAppViewer::cleanupSavedSettings()
|
||||
|
||||
gSavedSettings.setBOOL("DebugWindowProc", gDebugWindowProc);
|
||||
|
||||
gSavedSettings.setBOOL("AllowIdleAFK", gAllowIdleAFK);
|
||||
gSavedSettings.setBOOL("AllowTapTapHoldRun", gAllowTapTapHoldRun);
|
||||
gSavedSettings.setBOOL("ShowObjectUpdates", gShowObjectUpdates);
|
||||
|
||||
@@ -3969,7 +3964,7 @@ void LLAppViewer::idle()
|
||||
idle_afk_check();
|
||||
|
||||
// Update statistics for this frame
|
||||
update_statistics(gFrameCount);
|
||||
update_statistics();
|
||||
}
|
||||
|
||||
////////////////////////////////////////
|
||||
|
||||
@@ -275,7 +275,6 @@ const S32 AGENT_UPDATES_PER_SECOND = 10;
|
||||
|
||||
extern LLSD gDebugInfo;
|
||||
|
||||
extern BOOL gAllowIdleAFK;
|
||||
extern BOOL gAllowTapTapHoldRun;
|
||||
extern BOOL gShowObjectUpdates;
|
||||
|
||||
|
||||
@@ -278,3 +278,10 @@ void LLContainerView::setDisplayChildren(const BOOL displayChildren)
|
||||
childp->setVisible(mDisplayChildren);
|
||||
}
|
||||
}
|
||||
|
||||
void LLContainerView::setScrollContainer(LLScrollableContainerView* scroll)
|
||||
{
|
||||
mScrollContainer = scroll;
|
||||
scroll->setPassBackToChildren(false);
|
||||
}
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ public:
|
||||
void showLabel(BOOL show) { mShowLabel = show; }
|
||||
void setDisplayChildren(const BOOL displayChildren);
|
||||
BOOL getDisplayChildren() { return mDisplayChildren; }
|
||||
void setScrollContainer(LLScrollableContainerView* scroll) {mScrollContainer = scroll;}
|
||||
void setScrollContainer(LLScrollableContainerView* scroll);
|
||||
|
||||
private:
|
||||
LLScrollableContainerView* mScrollContainer;
|
||||
|
||||
@@ -557,6 +557,12 @@ F32 LLDrawable::updateXform(BOOL undamped)
|
||||
mVObjp->dirtySpatialGroup();
|
||||
}
|
||||
}
|
||||
else if (!isRoot() && (
|
||||
dist_vec_squared(old_pos, target_pos) > 0.f
|
||||
|| old_rot != target_rot ))
|
||||
{ //fix for BUG-860, MAINT-2275, MAINT-1742, MAINT-2247
|
||||
gPipeline.markRebuild(this, LLDrawable::REBUILD_POSITION, TRUE);
|
||||
}
|
||||
else if (!getVOVolume() && !isAvatar())
|
||||
{
|
||||
movePartition();
|
||||
|
||||
@@ -500,18 +500,9 @@ void LLFloaterAvatarList::assessColumns()
|
||||
|
||||
if(!client_hidden)
|
||||
{
|
||||
name_col->setWidth(width_name);
|
||||
name_col->setWidth(llmax(width_name.get(),10));
|
||||
}
|
||||
}
|
||||
else if (!hide_client)
|
||||
{
|
||||
mAvatarList->getColumn(LIST_CLIENT)->setWidth(0);
|
||||
mAvatarList->getColumn(LIST_AVATAR_NAME)->setWidth(0);
|
||||
mAvatarList->getColumn(LIST_AVATAR_NAME)->mDynamicWidth = FALSE;
|
||||
mAvatarList->getColumn(LIST_AVATAR_NAME)->mRelWidth = 0;
|
||||
mAvatarList->getColumn(LIST_CLIENT)->mDynamicWidth = TRUE;
|
||||
mAvatarList->getColumn(LIST_CLIENT)->mRelWidth = -1;
|
||||
}
|
||||
|
||||
mAvatarList->updateLayout();
|
||||
}
|
||||
@@ -885,7 +876,7 @@ void LLFloaterAvatarList::refreshAvatarList()
|
||||
LLColor4 name_color = sDefaultListText;
|
||||
|
||||
//Lindens are always more Linden than your friend, make that take precedence
|
||||
if(LLMuteList::getInstance()->isLinden(av_name))
|
||||
if(LLMuteList::getInstance()->isLinden(av_id))
|
||||
{
|
||||
static const LLCachedControl<LLColor4> ascent_linden_color("AscentLindenColor",LLColor4(0.f,0.f,1.f,1.f));
|
||||
name_color = ascent_linden_color;
|
||||
|
||||
@@ -58,26 +58,36 @@
|
||||
|
||||
#include "hippogridmanager.h"
|
||||
|
||||
LLFloaterBuyContents* LLFloaterBuyContents::sInstance = NULL;
|
||||
|
||||
LLFloaterBuyContents::LLFloaterBuyContents()
|
||||
: LLFloater(std::string("floater_buy_contents"), std::string("FloaterBuyContentsRect"), LLStringUtil::null)
|
||||
{
|
||||
LLUICtrlFactory::getInstance()->buildFloater(this, "floater_buy_contents.xml");
|
||||
}
|
||||
|
||||
childSetAction("cancel_btn", onClickCancel, this);
|
||||
childSetAction("buy_btn", onClickBuy, this);
|
||||
BOOL LLFloaterBuyContents::postBuild()
|
||||
{
|
||||
|
||||
childDisable("item_list");
|
||||
childDisable("buy_btn");
|
||||
childDisable("wear_check");
|
||||
getChild<LLUICtrl>("cancel_btn")->setCommitCallback( boost::bind(&LLFloaterBuyContents::onClickCancel, this));
|
||||
getChild<LLUICtrl>("buy_btn")->setCommitCallback( boost::bind(&LLFloaterBuyContents::onClickBuy, this));
|
||||
|
||||
getChildView("item_list")->setEnabled(FALSE);
|
||||
getChildView("buy_btn")->setEnabled(FALSE);
|
||||
getChildView("wear_check")->setEnabled(FALSE);
|
||||
|
||||
setDefaultBtn("cancel_btn"); // to avoid accidental buy (SL-43130)
|
||||
|
||||
// Always center the dialog. User can change the size,
|
||||
// but purchases are important and should be center screen.
|
||||
// This also avoids problems where the user resizes the application window
|
||||
// mid-session and the saved rect is off-center.
|
||||
center();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
LLFloaterBuyContents::~LLFloaterBuyContents()
|
||||
{
|
||||
sInstance = NULL;
|
||||
removeVOInventoryListener();
|
||||
}
|
||||
|
||||
|
||||
@@ -92,26 +102,20 @@ void LLFloaterBuyContents::show(const LLSaleInfo& sale_info)
|
||||
return;
|
||||
}
|
||||
|
||||
// Create a new instance only if needed
|
||||
if (sInstance)
|
||||
{
|
||||
LLScrollListCtrl* list = sInstance->getChild<LLScrollListCtrl>("item_list");
|
||||
if (list) list->deleteAllItems();
|
||||
}
|
||||
else
|
||||
{
|
||||
sInstance = new LLFloaterBuyContents();
|
||||
}
|
||||
LLFloaterBuyContents* floater = getInstance();
|
||||
LLScrollListCtrl* list = floater->getChild<LLScrollListCtrl>("item_list");
|
||||
if (list)
|
||||
list->deleteAllItems();
|
||||
|
||||
sInstance->open(); /*Flawfinder: ignore*/
|
||||
sInstance->setFocus(TRUE);
|
||||
sInstance->mObjectSelection = LLSelectMgr::getInstance()->getEditSelection();
|
||||
floater->mObjectSelection = LLSelectMgr::getInstance()->getEditSelection();
|
||||
|
||||
floater->open(); /*Flawfinder: ignore*/
|
||||
floater->setFocus(TRUE);
|
||||
// Always center the dialog. User can change the size,
|
||||
// but purchases are important and should be center screen.
|
||||
// This also avoids problems where the user resizes the application window
|
||||
// mid-session and the saved rect is off-center.
|
||||
sInstance->center();
|
||||
floater->center();
|
||||
|
||||
LLUUID owner_id;
|
||||
std::string owner_name;
|
||||
@@ -122,7 +126,7 @@ void LLFloaterBuyContents::show(const LLSaleInfo& sale_info)
|
||||
return;
|
||||
}
|
||||
|
||||
sInstance->mSaleInfo = sale_info;
|
||||
floater->mSaleInfo = sale_info;
|
||||
|
||||
// Update the display
|
||||
LLSelectNode* node = selection->getFirstRootNode();
|
||||
@@ -132,17 +136,17 @@ void LLFloaterBuyContents::show(const LLSaleInfo& sale_info)
|
||||
gCacheName->getGroupName(owner_id, owner_name);
|
||||
}
|
||||
|
||||
sInstance->childSetTextArg("contains_text", "[NAME]", node->mName);
|
||||
sInstance->childSetTextArg("buy_text", "[CURRENCY]", gHippoGridManager->getConnectedGrid()->getCurrencySymbol());
|
||||
sInstance->childSetTextArg("buy_text", "[AMOUNT]", llformat("%d", sale_info.getSalePrice()));
|
||||
sInstance->childSetTextArg("buy_text", "[NAME]", owner_name);
|
||||
floater->getChild<LLUICtrl>("contains_text")->setTextArg("[NAME]", node->mName);
|
||||
floater->getChild<LLUICtrl>("buy_text")->setTextArg("[CURRENCY]", gHippoGridManager->getConnectedGrid()->getCurrencySymbol());
|
||||
floater->getChild<LLUICtrl>("buy_text")->setTextArg("[AMOUNT]", llformat("%d", sale_info.getSalePrice()));
|
||||
floater->getChild<LLUICtrl>("buy_text")->setTextArg("[NAME]", owner_name);
|
||||
|
||||
// Must do this after the floater is created, because
|
||||
// sometimes the inventory is already there and
|
||||
// the callback is called immediately.
|
||||
LLViewerObject* obj = selection->getFirstRootObject();
|
||||
sInstance->registerVOInventoryListener(obj,NULL);
|
||||
sInstance->requestVOInventory();
|
||||
floater->registerVOInventoryListener(obj,NULL);
|
||||
floater->requestVOInventory();
|
||||
}
|
||||
|
||||
|
||||
@@ -157,23 +161,26 @@ void LLFloaterBuyContents::inventoryChanged(LLViewerObject* obj,
|
||||
return;
|
||||
}
|
||||
|
||||
if (!inv)
|
||||
{
|
||||
llwarns << "No inventory in LLFloaterBuyContents::inventoryChanged"
|
||||
<< llendl;
|
||||
removeVOInventoryListener();
|
||||
return;
|
||||
}
|
||||
|
||||
LLCtrlListInterface *item_list = childGetListInterface("item_list");
|
||||
LLScrollListCtrl* item_list = getChild<LLScrollListCtrl>("item_list");
|
||||
if (!item_list)
|
||||
{
|
||||
removeVOInventoryListener();
|
||||
return;
|
||||
}
|
||||
|
||||
item_list->deleteAllItems();
|
||||
|
||||
if (!inv)
|
||||
{
|
||||
llwarns << "No inventory in LLFloaterBuyContents::inventoryChanged"
|
||||
<< llendl;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// default to turning off the buy button.
|
||||
childDisable("buy_btn");
|
||||
LLView* buy_btn = getChildView("buy_btn");
|
||||
buy_btn->setEnabled(FALSE);
|
||||
|
||||
LLUUID owner_id;
|
||||
BOOL is_group_owned;
|
||||
@@ -214,13 +221,15 @@ void LLFloaterBuyContents::inventoryChanged(LLViewerObject* obj,
|
||||
|
||||
// There will be at least one item shown in the display, so go
|
||||
// ahead and enable the buy button.
|
||||
childEnable("buy_btn");
|
||||
buy_btn->setEnabled(TRUE);
|
||||
|
||||
// Create the line in the list
|
||||
LLSD row;
|
||||
|
||||
BOOL item_is_multi = FALSE;
|
||||
if ( inv_item->getFlags() & LLInventoryItemFlags::II_FLAGS_LANDMARK_VISITED )
|
||||
if ((inv_item->getFlags() & LLInventoryItemFlags::II_FLAGS_LANDMARK_VISITED
|
||||
|| inv_item->getFlags() & LLInventoryItemFlags::II_FLAGS_OBJECT_HAS_MULTIPLE_ITEMS)
|
||||
&& !(inv_item->getFlags() & LLInventoryItemFlags::II_FLAGS_WEARABLES_MASK))
|
||||
{
|
||||
item_is_multi = TRUE;
|
||||
}
|
||||
@@ -260,28 +269,25 @@ void LLFloaterBuyContents::inventoryChanged(LLViewerObject* obj,
|
||||
|
||||
if (wearable_count > 0)
|
||||
{
|
||||
childEnable("wear_check");
|
||||
childSetValue("wear_check", LLSD(false) );
|
||||
getChildView("wear_check")->setEnabled(TRUE);
|
||||
getChild<LLUICtrl>("wear_check")->setValue(LLSD(false) );
|
||||
}
|
||||
|
||||
removeVOInventoryListener();
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
void LLFloaterBuyContents::onClickBuy(void*)
|
||||
void LLFloaterBuyContents::onClickBuy()
|
||||
{
|
||||
// Make sure this wasn't selected through other mechanisms
|
||||
// (ie, being the default button and pressing enter.
|
||||
if(!sInstance->childIsEnabled("buy_btn"))
|
||||
if(!getChildView("buy_btn")->getEnabled())
|
||||
{
|
||||
// We shouldn't be enabled. Just close.
|
||||
sInstance->close();
|
||||
close();
|
||||
return;
|
||||
}
|
||||
|
||||
// We may want to wear this item
|
||||
if (sInstance->childGetValue("wear_check"))
|
||||
if (getChild<LLUICtrl>("wear_check")->getValue())
|
||||
{
|
||||
LLInventoryState::sWearNewClothing = TRUE;
|
||||
}
|
||||
@@ -293,14 +299,14 @@ void LLFloaterBuyContents::onClickBuy(void*)
|
||||
// *NOTE: doesn't work for multiple object buy, which UI does not
|
||||
// currently support sale info is used for verification only, if
|
||||
// it doesn't match region info then sale is canceled.
|
||||
LLSelectMgr::getInstance()->sendBuy(gAgent.getID(), category_id, sInstance->mSaleInfo);
|
||||
LLSelectMgr::getInstance()->sendBuy(gAgent.getID(), category_id, mSaleInfo);
|
||||
|
||||
sInstance->close();
|
||||
close();
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
void LLFloaterBuyContents::onClickCancel(void*)
|
||||
void LLFloaterBuyContents::onClickCancel()
|
||||
{
|
||||
sInstance->close();
|
||||
close();
|
||||
}
|
||||
|
||||
@@ -47,27 +47,26 @@ class LLViewerObject;
|
||||
class LLObjectSelection;
|
||||
|
||||
class LLFloaterBuyContents
|
||||
: public LLFloater, public LLVOInventoryListener
|
||||
: public LLFloater, public LLVOInventoryListener, public LLSingleton<LLFloaterBuyContents>
|
||||
{
|
||||
public:
|
||||
static void show(const LLSaleInfo& sale_info);
|
||||
|
||||
protected:
|
||||
LLFloaterBuyContents();
|
||||
~LLFloaterBuyContents();
|
||||
|
||||
/*virtual*/ BOOL postBuild();
|
||||
|
||||
protected:
|
||||
void requestObjectInventories();
|
||||
/*virtual*/ void inventoryChanged(LLViewerObject* obj,
|
||||
LLInventoryObject::object_list_t* inv,
|
||||
S32 serial_num,
|
||||
void* data);
|
||||
|
||||
static void onClickBuy(void*);
|
||||
static void onClickCancel(void*);
|
||||
|
||||
void onClickBuy();
|
||||
void onClickCancel();
|
||||
|
||||
protected:
|
||||
static LLFloaterBuyContents* sInstance;
|
||||
|
||||
LLSafeHandle<LLObjectSelection> mObjectSelection;
|
||||
LLSaleInfo mSaleInfo;
|
||||
};
|
||||
|
||||
@@ -56,9 +56,9 @@ void LLFloaterEditUI::navigateHierarchyButtonPressed(void* data)
|
||||
const LLView::child_list_t* viewChildren = view->getChildList();
|
||||
const LLView::child_list_t* parentChildren = parent->getChildList();
|
||||
//LLView::child_list_t::iterator
|
||||
std::list<LLView*>::const_iterator itor;
|
||||
std::list<LLView*>::size_type idx;
|
||||
std::list<LLView*>::size_type sidx;
|
||||
LLView::child_list_t::const_iterator itor;
|
||||
LLView::child_list_t::size_type idx;
|
||||
LLView::child_list_t::size_type sidx;
|
||||
for(idx = 0,itor = parentChildren->begin();itor!=parentChildren->end();itor++,idx++){
|
||||
if((*itor)==view)break;
|
||||
}
|
||||
|
||||
@@ -461,6 +461,10 @@ BOOL LLPanelRegionTools::postBuild()
|
||||
getChild<LLUICtrl>("block terraform")->setCommitCallback(boost::bind(&LLPanelRegionTools::onChangeAnything, this));
|
||||
getChild<LLUICtrl>("allow transfer")->setCommitCallback(boost::bind(&LLPanelRegionTools::onChangeAnything, this));
|
||||
getChild<LLUICtrl>("is sandbox")->setCommitCallback( boost::bind(&LLPanelRegionTools::onChangeAnything, this));
|
||||
getChild<LLUICtrl>("is gaming")->setVisible((gAgent.getRegion()->getGamingFlags() & REGION_GAMING_PRESENT) && !(gAgent.getRegion()->getGamingFlags() & REGION_GAMING_HIDE_GOD_FLOATER));
|
||||
getChild<LLUICtrl>("is gaming")->setCommitCallback(boost::bind(&LLPanelRegionTools::onChangeAnything, this));
|
||||
getChild<LLUICtrl>("hide from search")->setVisible(!gHippoGridManager->getConnectedGrid()->isSecondLife());
|
||||
getChild<LLUICtrl>("hide from search")->setCommitCallback(boost::bind(&LLPanelRegionTools::onChangeAnything, this));
|
||||
|
||||
childSetAction("Bake Terrain", boost::bind(&LLPanelRegionTools::onBakeTerrain, this));
|
||||
childSetAction("Revert Terrain", boost::bind(&LLPanelRegionTools::onRevertTerrain, this));
|
||||
@@ -670,6 +674,14 @@ U64 LLPanelRegionTools::getRegionFlags() const
|
||||
{
|
||||
flags |= REGION_FLAGS_SANDBOX;
|
||||
}
|
||||
if (getChild<LLUICtrl>("is gaming")->getValue().asBoolean())
|
||||
{
|
||||
flags |= REGION_FLAGS_GAMING;
|
||||
}
|
||||
if (getChild<LLUICtrl>("hide from search")->getValue().asBoolean())
|
||||
{
|
||||
flags |= REGION_FLAGS_HIDE_FROM_SEARCH;
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
|
||||
@@ -708,6 +720,14 @@ U64 LLPanelRegionTools::getRegionFlagsMask() const
|
||||
{
|
||||
flags &= ~REGION_FLAGS_SANDBOX;
|
||||
}
|
||||
if (!getChild<LLUICtrl>("is gaming")->getValue().asBoolean())
|
||||
{
|
||||
flags &= ~REGION_FLAGS_GAMING;
|
||||
}
|
||||
if (!getChild<LLUICtrl>("hide from search")->getValue().asBoolean())
|
||||
{
|
||||
flags &= ~REGION_FLAGS_HIDE_FROM_SEARCH;
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
|
||||
@@ -766,6 +786,8 @@ void LLPanelRegionTools::setCheckFlags(U64 flags)
|
||||
getChild<LLUICtrl>("block terraform")->setValue(flags & REGION_FLAGS_BLOCK_TERRAFORM ? TRUE : FALSE);
|
||||
getChild<LLUICtrl>("block dwell")->setValue(flags & REGION_FLAGS_BLOCK_DWELL ? TRUE : FALSE);
|
||||
getChild<LLUICtrl>("is sandbox")->setValue(flags & REGION_FLAGS_SANDBOX ? TRUE : FALSE );
|
||||
getChild<LLUICtrl>("is gaming")->setValue(flags & REGION_FLAGS_GAMING ? true : false);
|
||||
getChild<LLUICtrl>("hide from search")->setValue(flags & REGION_FLAGS_HIDE_FROM_SEARCH ? true : false);
|
||||
}
|
||||
|
||||
void LLPanelRegionTools::setBillableFactor(F32 billable_factor)
|
||||
|
||||
@@ -973,11 +973,13 @@ BOOL LLImagePreviewSculpted::render()
|
||||
{
|
||||
gObjectPreviewProgram.bind();
|
||||
}
|
||||
gPipeline.enableLightsPreview();
|
||||
|
||||
gGL.pushMatrix();
|
||||
const F32 SCALE = 1.25f;
|
||||
gGL.scalef(SCALE, SCALE, SCALE);
|
||||
const F32 BRIGHTNESS = 0.9f;
|
||||
gGL.color3f(BRIGHTNESS, BRIGHTNESS, BRIGHTNESS);
|
||||
gGL.diffuseColor3f(BRIGHTNESS, BRIGHTNESS, BRIGHTNESS);
|
||||
|
||||
mVertexBuffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0);
|
||||
mVertexBuffer->draw(LLRender::TRIANGLES, num_indices, 0);
|
||||
|
||||
@@ -106,7 +106,8 @@ BOOL LLFloaterJoystick::postBuild()
|
||||
for (U32 i = 0; i < 6; i++)
|
||||
{
|
||||
axis.setArg("[NUM]", llformat("%d", i));
|
||||
mAxisStats[i] = new LLStat(4);
|
||||
std::string stat_name(llformat("Joystick axis %d", i));
|
||||
mAxisStats[i] = new LLStat(stat_name,4);
|
||||
mAxisStatsBar[i] = mAxisStatsView->addStat(axis, mAxisStats[i]);
|
||||
mAxisStatsBar[i]->mMinBar = -range;
|
||||
mAxisStatsBar[i]->mMaxBar = range;
|
||||
|
||||
@@ -48,15 +48,16 @@
|
||||
#include "llagent.h"
|
||||
#include "llagentaccess.h"
|
||||
#include "llavatarconstants.h" //For new Online check - HgB
|
||||
#include "llfloateravatarpicker.h"
|
||||
#include "llbutton.h"
|
||||
#include "llcheckboxctrl.h"
|
||||
#include "llradiogroup.h"
|
||||
#include "llcombobox.h"
|
||||
#include "llfloaterauction.h"
|
||||
#include "llfloateravatarinfo.h"
|
||||
#include "llfloateravatarpicker.h"
|
||||
#include "llfloatergroups.h"
|
||||
#include "llfloatergroupinfo.h"
|
||||
#include "llfloaterscriptlimits.h"
|
||||
#include "lllineeditor.h"
|
||||
#include "llnamelistctrl.h"
|
||||
#include "llnotify.h"
|
||||
@@ -221,8 +222,6 @@ LLFloaterLand::LLFloaterLand(const LLSD& seed)
|
||||
{
|
||||
LLCallbackMap::map_t factory_map;
|
||||
factory_map["land_general_panel"] = LLCallbackMap(createPanelLandGeneral, this);
|
||||
|
||||
|
||||
factory_map["land_covenant_panel"] = LLCallbackMap(createPanelLandCovenant, this);
|
||||
factory_map["land_objects_panel"] = LLCallbackMap(createPanelLandObjects, this);
|
||||
factory_map["land_options_panel"] = LLCallbackMap(createPanelLandOptions, this);
|
||||
@@ -344,16 +343,15 @@ LLPanelLandGeneral::LLPanelLandGeneral(LLParcelSelectionHandle& parcel)
|
||||
BOOL LLPanelLandGeneral::postBuild()
|
||||
{
|
||||
mEditName = getChild<LLLineEditor>("Name");
|
||||
mEditName->setCommitCallback(onCommitAny);
|
||||
childSetPrevalidate("Name", LLLineEditor::prevalidatePrintableNotPipe);
|
||||
childSetUserData("Name", this);
|
||||
mEditName->setCommitCallback(onCommitAny, this);
|
||||
getChild<LLLineEditor>("Name")->setPrevalidate(LLLineEditor::prevalidatePrintableNotPipe);
|
||||
|
||||
mEditDesc = getChild<LLTextEditor>("Description");
|
||||
mEditDesc->setCommitOnFocusLost(TRUE);
|
||||
mEditDesc->setCommitCallback(onCommitAny);
|
||||
//childSetPrevalidate("Description", LLLineEditor::prevalidatePrintableNotPipe); Making Dummy View -HgB
|
||||
childSetUserData("Description", this);
|
||||
|
||||
mEditDesc->setCommitCallback(onCommitAny, this);
|
||||
// No prevalidate function - historically the prevalidate function was broken,
|
||||
// allowing residents to put in characters like U+2661 WHITE HEART SUIT, so
|
||||
// preserve that ability.
|
||||
|
||||
mTextSalePending = getChild<LLTextBox>("SalePending");
|
||||
mTextOwnerLabel = getChild<LLTextBox>("Owner:");
|
||||
@@ -363,7 +361,7 @@ BOOL LLPanelLandGeneral::postBuild()
|
||||
mLandType = getChild<LLTextBox>("LandTypeText");
|
||||
|
||||
mBtnProfile = getChild<LLButton>("Profile...");
|
||||
mBtnProfile->setClickedCallback(onClickProfile, this);
|
||||
mBtnProfile->setClickedCallback(boost::bind(&LLPanelLandGeneral::onClickProfile, this));
|
||||
|
||||
|
||||
mTextGroupLabel = getChild<LLTextBox>("Group:");
|
||||
@@ -371,7 +369,7 @@ BOOL LLPanelLandGeneral::postBuild()
|
||||
|
||||
|
||||
mBtnSetGroup = getChild<LLButton>("Set...");
|
||||
mBtnSetGroup->setClickedCallback(onClickSetGroup, this);
|
||||
mBtnSetGroup->setCommitCallback(boost::bind(&LLPanelLandGeneral::onClickSetGroup, this));
|
||||
|
||||
getChild<LLButton>("group_profile")->setClickedCallback(onClickInfoGroup, this);
|
||||
|
||||
@@ -416,10 +414,30 @@ BOOL LLPanelLandGeneral::postBuild()
|
||||
|
||||
|
||||
mTextDwell = getChild<LLTextBox>("DwellText");
|
||||
|
||||
|
||||
mBtnBuyLand = getChild<LLButton>("Buy Land...");
|
||||
mBtnBuyLand->setClickedCallback(onClickBuyLand, (void*)&BUY_PERSONAL_LAND);
|
||||
|
||||
// note: on region change this will not be re checked, should not matter on Agni as
|
||||
// 99% of the time all regions will return the same caps. In case of an erroneous setting
|
||||
// to enabled the floater will just throw an error when trying to get it's cap
|
||||
std::string url = gAgent.getRegion()->getCapability("LandResources");
|
||||
if (!url.empty())
|
||||
{
|
||||
mBtnScriptLimits = getChild<LLButton>("Scripts...");
|
||||
if(mBtnScriptLimits)
|
||||
{
|
||||
mBtnScriptLimits->setClickedCallback(onClickScriptLimits, this);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mBtnScriptLimits = getChild<LLButton>("Scripts...");
|
||||
if(mBtnScriptLimits)
|
||||
{
|
||||
mBtnScriptLimits->setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
mBtnBuyGroupLand = getChild<LLButton>("Buy For Group...");
|
||||
mBtnBuyGroupLand->setClickedCallback(onClickBuyLand, (void*)&BUY_GROUP_LAND);
|
||||
@@ -508,6 +526,7 @@ void LLPanelLandGeneral::refresh()
|
||||
mTextDwell->setText(LLStringUtil::null);
|
||||
|
||||
mBtnBuyLand->setEnabled(FALSE);
|
||||
mBtnScriptLimits->setEnabled(FALSE);
|
||||
mBtnBuyGroupLand->setEnabled(FALSE);
|
||||
mBtnReleaseLand->setEnabled(FALSE);
|
||||
mBtnReclaimLand->setEnabled(FALSE);
|
||||
@@ -723,6 +742,7 @@ void LLPanelLandGeneral::refresh()
|
||||
|
||||
mBtnBuyLand->setEnabled(
|
||||
LLViewerParcelMgr::getInstance()->canAgentBuyParcel(parcel, false));
|
||||
mBtnScriptLimits->setEnabled(true);
|
||||
mBtnBuyGroupLand->setEnabled(
|
||||
LLViewerParcelMgr::getInstance()->canAgentBuyParcel(parcel, true));
|
||||
|
||||
@@ -741,7 +761,7 @@ void LLPanelLandGeneral::refresh()
|
||||
mBtnReleaseLand->setEnabled( can_release );
|
||||
}
|
||||
|
||||
BOOL use_pass = parcel->getParcelFlag(PF_USE_PASS_LIST) && !LLViewerParcelMgr::getInstance()->isCollisionBanned();;
|
||||
BOOL use_pass = parcel->getOwnerID()!= gAgent.getID() && parcel->getParcelFlag(PF_USE_PASS_LIST) && !LLViewerParcelMgr::getInstance()->isCollisionBanned();;
|
||||
mBtnBuyPass->setEnabled(use_pass);
|
||||
}
|
||||
}
|
||||
@@ -805,22 +825,20 @@ void LLPanelLandGeneral::draw()
|
||||
LLPanel::draw();
|
||||
}
|
||||
|
||||
// static
|
||||
void LLPanelLandGeneral::onClickSetGroup(void* userdata)
|
||||
void LLPanelLandGeneral::onClickSetGroup()
|
||||
{
|
||||
LLPanelLandGeneral* panelp = (LLPanelLandGeneral*)userdata;
|
||||
LLFloaterGroupPicker* fg;
|
||||
LLFloater* parent_floater = gFloaterView->getParentFloater(this);
|
||||
|
||||
LLFloater* parent_floater = gFloaterView->getParentFloater(panelp);
|
||||
|
||||
fg = LLFloaterGroupPicker::showInstance(LLSD(gAgent.getID()));
|
||||
fg->setSelectCallback( cbGroupID, userdata );
|
||||
|
||||
if (parent_floater)
|
||||
LLFloaterGroupPicker* fg = LLFloaterGroupPicker::showInstance(LLSD(gAgent.getID()));
|
||||
if (fg)
|
||||
{
|
||||
LLRect new_rect = gFloaterView->findNeighboringPosition(parent_floater, fg);
|
||||
fg->setOrigin(new_rect.mLeft, new_rect.mBottom);
|
||||
parent_floater->addDependentFloater(fg);
|
||||
fg->setSelectCallback( cbGroupID, this);
|
||||
if (parent_floater)
|
||||
{
|
||||
LLRect new_rect = gFloaterView->findNeighboringPosition(parent_floater, fg);
|
||||
fg->setOrigin(new_rect.mLeft, new_rect.mBottom);
|
||||
parent_floater->addDependentFloater(fg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -834,11 +852,9 @@ void LLPanelLandGeneral::onClickInfoGroup(void* userdata)
|
||||
if(id.notNull())LLFloaterGroupInfo::showFromUUID(parcel->getGroupID());
|
||||
}
|
||||
|
||||
// static
|
||||
void LLPanelLandGeneral::onClickProfile(void* data)
|
||||
void LLPanelLandGeneral::onClickProfile()
|
||||
{
|
||||
LLPanelLandGeneral* panelp = (LLPanelLandGeneral*)data;
|
||||
LLParcel* parcel = panelp->mParcel->getParcel();
|
||||
LLParcel* parcel = mParcel->getParcel();
|
||||
if (!parcel) return;
|
||||
|
||||
if (parcel->getIsGroupOwned())
|
||||
@@ -891,17 +907,15 @@ void LLPanelLandGeneral::onClickBuyLand(void* data)
|
||||
LLViewerParcelMgr::getInstance()->startBuyLand(*for_group);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
BOOL LLPanelLandGeneral::enableDeedToGroup(void* data)
|
||||
// static
|
||||
void LLPanelLandGeneral::onClickScriptLimits(void* data)
|
||||
{
|
||||
LLPanelLandGeneral* panelp = (LLPanelLandGeneral*)data;
|
||||
LLParcel* parcel = panelp->mParcel->getParcel();
|
||||
return (parcel != NULL) && (parcel->getParcelFlag(PF_ALLOW_DEED_TO_GROUP));
|
||||
if(parcel != NULL)
|
||||
{
|
||||
LLFloaterScriptLimits::showInstance();
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
@@ -954,6 +968,7 @@ void LLPanelLandGeneral::onClickBuyPass(void* data)
|
||||
|
||||
LLSD args;
|
||||
args["COST"] = cost;
|
||||
args["CURRENCY"] = gHippoGridManager->getConnectedGrid()->getCurrencySymbol();
|
||||
args["PARCEL_NAME"] = parcel_name;
|
||||
args["TIME"] = time;
|
||||
|
||||
@@ -1844,6 +1859,7 @@ LLPanelLandOptions::LLPanelLandOptions(LLParcelSelectionHandle& parcel)
|
||||
mSetBtn(NULL),
|
||||
mClearBtn(NULL),
|
||||
mMatureCtrl(NULL),
|
||||
mGamingCtrl(NULL),
|
||||
mPushRestrictionCtrl(NULL),
|
||||
mSeeAvatarsCtrl(NULL),
|
||||
mParcel(parcel),
|
||||
@@ -1869,9 +1885,9 @@ BOOL LLPanelLandOptions::postBuild()
|
||||
mCheckEditLand = getChild<LLCheckBoxCtrl>( "edit land check");
|
||||
childSetCommitCallback("edit land check", onCommitAny, this);
|
||||
|
||||
|
||||
mCheckLandmark = getChild<LLCheckBoxCtrl>( "check landmark");
|
||||
childSetCommitCallback("check landmark", onCommitAny, this);
|
||||
mCheckLandmark->setVisible(!gHippoGridManager->getConnectedGrid()->isSecondLife());
|
||||
|
||||
|
||||
mCheckGroupScripts = getChild<LLCheckBoxCtrl>( "check group scripts");
|
||||
@@ -1921,6 +1937,11 @@ BOOL LLPanelLandOptions::postBuild()
|
||||
|
||||
mMatureCtrl = getChild<LLCheckBoxCtrl>( "MatureCheck");
|
||||
childSetCommitCallback("MatureCheck", onCommitAny, this);
|
||||
|
||||
mGamingCtrl = getChild<LLCheckBoxCtrl>( "GamingCheck");
|
||||
childSetCommitCallback("GamingCheck", onCommitAny, this);
|
||||
mGamingCtrl->setVisible((gAgent.getRegion()->getGamingFlags() & REGION_GAMING_PRESENT) && !(gAgent.getRegion()->getGamingFlags() & REGION_GAMING_HIDE_PARCEL));
|
||||
mGamingCtrl->setEnabled(false);
|
||||
|
||||
mPublishHelpButton = getChild<LLButton>("?");
|
||||
mPublishHelpButton->setClickedCallback(onClickPublishHelp, this);
|
||||
@@ -1938,8 +1959,7 @@ BOOL LLPanelLandOptions::postBuild()
|
||||
mSnapshotCtrl = getChild<LLTextureCtrl>("snapshot_ctrl");
|
||||
if (mSnapshotCtrl)
|
||||
{
|
||||
mSnapshotCtrl->setCommitCallback( onCommitAny );
|
||||
mSnapshotCtrl->setCallbackUserData( this );
|
||||
mSnapshotCtrl->setCommitCallback( onCommitAny, this );
|
||||
mSnapshotCtrl->setAllowNoTexture ( TRUE );
|
||||
mSnapshotCtrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);
|
||||
mSnapshotCtrl->setNonImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);
|
||||
@@ -2029,6 +2049,7 @@ void LLPanelLandOptions::refresh()
|
||||
mClearBtn->setEnabled(FALSE);
|
||||
|
||||
mMatureCtrl->setEnabled(FALSE);
|
||||
mGamingCtrl->setEnabled(false);
|
||||
mPublishHelpButton->setEnabled(FALSE);
|
||||
}
|
||||
else
|
||||
@@ -2152,6 +2173,8 @@ void LLPanelLandOptions::refresh()
|
||||
}
|
||||
}
|
||||
}
|
||||
mGamingCtrl->set(parcel->getParcelFlag(PF_GAMING));
|
||||
mGamingCtrl->setEnabled(can_change_options);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2288,6 +2311,7 @@ void LLPanelLandOptions::onCommitAny(LLUICtrl *ctrl, void *userdata)
|
||||
BOOL mature_publish = self->mMatureCtrl->get();
|
||||
BOOL push_restriction = self->mPushRestrictionCtrl->get();
|
||||
BOOL see_avs = self->mSeeAvatarsCtrl->get();
|
||||
bool gaming = self->mGamingCtrl->get();
|
||||
BOOL show_directory = self->mCheckShowDirectory->get();
|
||||
// we have to get the index from a lookup, not from the position in the dropdown!
|
||||
S32 category_index = LLParcel::getCategoryFromString(self->mCategoryCombo->getSelectedValue());
|
||||
@@ -2296,11 +2320,16 @@ void LLPanelLandOptions::onCommitAny(LLUICtrl *ctrl, void *userdata)
|
||||
LLViewerRegion* region;
|
||||
region = LLViewerParcelMgr::getInstance()->getSelectionRegion();
|
||||
|
||||
if (!allow_other_scripts && region && region->getAllowDamage())
|
||||
{
|
||||
|
||||
LLNotificationsUtil::add("UnableToDisableOutsideScripts");
|
||||
return;
|
||||
if (region && region->getAllowDamage())
|
||||
{ // Damage is allowed on the region - server will always allow scripts
|
||||
if ( (!allow_other_scripts && parcel->getParcelFlag(PF_ALLOW_OTHER_SCRIPTS)) ||
|
||||
(!allow_group_scripts && parcel->getParcelFlag(PF_ALLOW_GROUP_SCRIPTS)) )
|
||||
{ // Don't allow turning off "Run Scripts" if damage is allowed in the region
|
||||
self->mCheckOtherScripts->set(parcel->getParcelFlag(PF_ALLOW_OTHER_SCRIPTS)); // Restore UI to actual settings
|
||||
self->mCheckGroupScripts->set(parcel->getParcelFlag(PF_ALLOW_GROUP_SCRIPTS));
|
||||
LLNotificationsUtil::add("UnableToDisableOutsideScripts");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Push data into current parcel
|
||||
@@ -2317,6 +2346,7 @@ void LLPanelLandOptions::onCommitAny(LLUICtrl *ctrl, void *userdata)
|
||||
parcel->setParcelFlag(PF_SHOW_DIRECTORY, show_directory);
|
||||
parcel->setParcelFlag(PF_ALLOW_PUBLISH, allow_publish);
|
||||
parcel->setParcelFlag(PF_MATURE_PUBLISH, mature_publish);
|
||||
parcel->setParcelFlag(PF_GAMING, gaming);
|
||||
parcel->setParcelFlag(PF_RESTRICT_PUSHOBJECT, push_restriction);
|
||||
parcel->setCategory((LLParcel::ECategory)category_index);
|
||||
parcel->setLandingType((LLParcel::ELandingType)landing_type_index);
|
||||
@@ -2419,9 +2449,9 @@ BOOL LLPanelLandAccess::postBuild()
|
||||
childSetCommitCallback("PriceSpin", onCommitAny, this);
|
||||
childSetCommitCallback("HoursSpin", onCommitAny, this);
|
||||
|
||||
childSetAction("add_allowed", onClickAddAccess, this);
|
||||
childSetAction("add_allowed", boost::bind(&LLPanelLandAccess::onClickAddAccess, this));
|
||||
childSetAction("remove_allowed", onClickRemoveAccess, this);
|
||||
childSetAction("add_banned", onClickAddBanned, this);
|
||||
childSetAction("add_banned", boost::bind(&LLPanelLandAccess::onClickAddBanned, this));
|
||||
childSetAction("remove_banned", onClickRemoveBanned, this);
|
||||
|
||||
mListAccess = getChild<LLNameListCtrl>("AccessList");
|
||||
@@ -2456,12 +2486,12 @@ void LLPanelLandAccess::refresh()
|
||||
BOOL use_group = parcel->getParcelFlag(PF_USE_ACCESS_GROUP);
|
||||
BOOL public_access = !use_access_list && !use_group;
|
||||
|
||||
childSetValue("public_access", public_access );
|
||||
childSetValue("GroupCheck", use_group );
|
||||
getChild<LLUICtrl>("public_access")->setValue(public_access );
|
||||
getChild<LLUICtrl>("GroupCheck")->setValue(use_group );
|
||||
|
||||
std::string group_name;
|
||||
gCacheName->getGroupName(parcel->getGroupID(), group_name);
|
||||
childSetLabelArg("GroupCheck", "[GROUP]", group_name );
|
||||
getChild<LLUICtrl>("GroupCheck")->setLabelArg("[GROUP]", group_name );
|
||||
|
||||
// Allow list
|
||||
if (mListAccess)
|
||||
@@ -2470,8 +2500,8 @@ void LLPanelLandAccess::refresh()
|
||||
mListAccess->clearSortOrder();
|
||||
mListAccess->deleteAllItems();
|
||||
S32 count = parcel->mAccessList.size();
|
||||
childSetToolTipArg("AccessList", "[LISTED]", llformat("%d",count));
|
||||
childSetToolTipArg("AccessList", "[MAX]", llformat("%d",PARCEL_MAX_ACCESS_LIST));
|
||||
getChild<LLUICtrl>("AccessList")->setToolTipArg(LLStringExplicit("[LISTED]"), llformat("%d",count));
|
||||
getChild<LLUICtrl>("AccessList")->setToolTipArg(LLStringExplicit("[MAX]"), llformat("%d",PARCEL_MAX_ACCESS_LIST));
|
||||
|
||||
for (access_map_const_iterator cit = parcel->mAccessList.begin();
|
||||
cit != parcel->mAccessList.end(); ++cit)
|
||||
@@ -2517,8 +2547,8 @@ void LLPanelLandAccess::refresh()
|
||||
mListBanned->deleteAllItems();
|
||||
S32 count = parcel->mBanList.size();
|
||||
|
||||
childSetToolTipArg("BannedList", "[LISTED]", llformat("%d",count));
|
||||
childSetToolTipArg("BannedList", "[MAX]", llformat("%d",PARCEL_MAX_ACCESS_LIST));
|
||||
getChild<LLUICtrl>("BannedList")->setToolTipArg(LLStringExplicit("[LISTED]"), llformat("%d",count));
|
||||
getChild<LLUICtrl>("BannedList")->setToolTipArg(LLStringExplicit("[MAX]"), llformat("%d",PARCEL_MAX_ACCESS_LIST));
|
||||
|
||||
for (access_map_const_iterator cit = parcel->mBanList.begin();
|
||||
cit != parcel->mBanList.end(); ++cit)
|
||||
@@ -2558,23 +2588,23 @@ void LLPanelLandAccess::refresh()
|
||||
|
||||
if(parcel->getRegionDenyAnonymousOverride())
|
||||
{
|
||||
childSetValue("limit_payment", TRUE);
|
||||
getChild<LLUICtrl>("limit_payment")->setValue(TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
childSetValue("limit_payment", (parcel->getParcelFlag(PF_DENY_ANONYMOUS)));
|
||||
getChild<LLUICtrl>("limit_payment")->setValue((parcel->getParcelFlag(PF_DENY_ANONYMOUS)));
|
||||
}
|
||||
if(parcel->getRegionDenyAgeUnverifiedOverride())
|
||||
{
|
||||
childSetValue("limit_age_verified", TRUE);
|
||||
getChild<LLUICtrl>("limit_age_verified")->setValue(TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
childSetValue("limit_age_verified", (parcel->getParcelFlag(PF_DENY_AGEUNVERIFIED)));
|
||||
getChild<LLUICtrl>("limit_age_verified")->setValue((parcel->getParcelFlag(PF_DENY_AGEUNVERIFIED)));
|
||||
}
|
||||
|
||||
BOOL use_pass = parcel->getParcelFlag(PF_USE_PASS_LIST);
|
||||
childSetValue("PassCheck", use_pass );
|
||||
getChild<LLUICtrl>("PassCheck")->setValue(use_pass );
|
||||
LLCtrlSelectionInterface* passcombo = childGetSelectionInterface("pass_combo");
|
||||
if (passcombo)
|
||||
{
|
||||
@@ -2585,41 +2615,41 @@ void LLPanelLandAccess::refresh()
|
||||
}
|
||||
|
||||
S32 pass_price = parcel->getPassPrice();
|
||||
childSetValue( "PriceSpin", (F32)pass_price );
|
||||
childSetLabelArg("PriceSpin", "[CURRENCY]", gHippoGridManager->getConnectedGrid()->getCurrencySymbol());
|
||||
getChild<LLUICtrl>("PriceSpin")->setValue((F32)pass_price );
|
||||
getChild<LLUICtrl>("PriceSpin")->setLabelArg("[CURRENCY]", gHippoGridManager->getConnectedGrid()->getCurrencySymbol());
|
||||
|
||||
F32 pass_hours = parcel->getPassHours();
|
||||
childSetValue( "HoursSpin", pass_hours );
|
||||
getChild<LLUICtrl>("HoursSpin")->setValue(pass_hours );
|
||||
}
|
||||
else
|
||||
{
|
||||
childSetValue("public_access", FALSE);
|
||||
childSetValue("limit_payment", FALSE);
|
||||
childSetValue("limit_age_verified", FALSE);
|
||||
childSetValue("GroupCheck", FALSE);
|
||||
childSetLabelArg("GroupCheck", "[GROUP]", LLStringUtil::null );
|
||||
childSetValue("PassCheck", FALSE);
|
||||
childSetValue("PriceSpin", (F32)PARCEL_PASS_PRICE_DEFAULT);
|
||||
childSetValue( "HoursSpin", PARCEL_PASS_HOURS_DEFAULT );
|
||||
childSetToolTipArg("AccessList", "[LISTED]", llformat("%d",0));
|
||||
childSetToolTipArg("AccessList", "[MAX]", llformat("%d",0));
|
||||
childSetToolTipArg("BannedList", "[LISTED]", llformat("%d",0));
|
||||
childSetToolTipArg("BannedList", "[MAX]", llformat("%d",0));
|
||||
getChild<LLUICtrl>("public_access")->setValue(FALSE);
|
||||
getChild<LLUICtrl>("limit_payment")->setValue(FALSE);
|
||||
getChild<LLUICtrl>("limit_age_verified")->setValue(FALSE);
|
||||
getChild<LLUICtrl>("GroupCheck")->setValue(FALSE);
|
||||
getChild<LLUICtrl>("GroupCheck")->setLabelArg("[GROUP]", LLStringUtil::null );
|
||||
getChild<LLUICtrl>("PassCheck")->setValue(FALSE);
|
||||
getChild<LLUICtrl>("PriceSpin")->setValue((F32)PARCEL_PASS_PRICE_DEFAULT);
|
||||
getChild<LLUICtrl>("HoursSpin")->setValue(PARCEL_PASS_HOURS_DEFAULT );
|
||||
getChild<LLUICtrl>("AccessList")->setToolTipArg(LLStringExplicit("[LISTED]"), llformat("%d",0));
|
||||
getChild<LLUICtrl>("AccessList")->setToolTipArg(LLStringExplicit("[MAX]"), llformat("%d",0));
|
||||
getChild<LLUICtrl>("BannedList")->setToolTipArg(LLStringExplicit("[LISTED]"), llformat("%d",0));
|
||||
getChild<LLUICtrl>("BannedList")->setToolTipArg(LLStringExplicit("[MAX]"), llformat("%d",0));
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelLandAccess::refresh_ui()
|
||||
{
|
||||
childSetEnabled("public_access", FALSE);
|
||||
childSetEnabled("limit_payment", FALSE);
|
||||
childSetEnabled("limit_age_verified", FALSE);
|
||||
childSetEnabled("GroupCheck", FALSE);
|
||||
childSetEnabled("PassCheck", FALSE);
|
||||
childSetEnabled("pass_combo", FALSE);
|
||||
childSetEnabled("PriceSpin", FALSE);
|
||||
childSetEnabled("HoursSpin", FALSE);
|
||||
childSetEnabled("AccessList", FALSE);
|
||||
childSetEnabled("BannedList", FALSE);
|
||||
getChildView("public_access")->setEnabled(FALSE);
|
||||
getChildView("limit_payment")->setEnabled(FALSE);
|
||||
getChildView("limit_age_verified")->setEnabled(FALSE);
|
||||
getChildView("GroupCheck")->setEnabled(FALSE);
|
||||
getChildView("PassCheck")->setEnabled(FALSE);
|
||||
getChildView("pass_combo")->setEnabled(FALSE);
|
||||
getChildView("PriceSpin")->setEnabled(FALSE);
|
||||
getChildView("HoursSpin")->setEnabled(FALSE);
|
||||
getChildView("AccessList")->setEnabled(FALSE);
|
||||
getChildView("BannedList")->setEnabled(FALSE);
|
||||
|
||||
LLParcel *parcel = mParcel->getParcel();
|
||||
if (parcel)
|
||||
@@ -2627,73 +2657,73 @@ void LLPanelLandAccess::refresh_ui()
|
||||
BOOL can_manage_allowed = LLViewerParcelMgr::isParcelModifiableByAgent(parcel, GP_LAND_MANAGE_ALLOWED);
|
||||
BOOL can_manage_banned = LLViewerParcelMgr::isParcelModifiableByAgent(parcel, GP_LAND_MANAGE_BANNED);
|
||||
|
||||
childSetEnabled("public_access", can_manage_allowed);
|
||||
BOOL public_access = childGetValue("public_access").asBoolean();
|
||||
getChildView("public_access")->setEnabled(can_manage_allowed);
|
||||
BOOL public_access = getChild<LLUICtrl>("public_access")->getValue().asBoolean();
|
||||
if (public_access)
|
||||
{
|
||||
bool override = false;
|
||||
if(parcel->getRegionDenyAnonymousOverride())
|
||||
{
|
||||
override = true;
|
||||
childSetEnabled("limit_payment", FALSE);
|
||||
getChildView("limit_payment")->setEnabled(FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
childSetEnabled("limit_payment", can_manage_allowed);
|
||||
getChildView("limit_payment")->setEnabled(can_manage_allowed);
|
||||
}
|
||||
if(parcel->getRegionDenyAgeUnverifiedOverride())
|
||||
{
|
||||
override = true;
|
||||
childSetEnabled("limit_age_verified", FALSE);
|
||||
getChildView("limit_age_verified")->setEnabled(FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
childSetEnabled("limit_age_verified", can_manage_allowed);
|
||||
getChildView("limit_age_verified")->setEnabled(can_manage_allowed);
|
||||
}
|
||||
if (override)
|
||||
{
|
||||
childSetToolTip("Only Allow", getString("estate_override"));
|
||||
getChildView("Only Allow")->setToolTip(getString("estate_override"));
|
||||
}
|
||||
else
|
||||
{
|
||||
childSetToolTip("Only Allow", std::string());
|
||||
getChildView("Only Allow")->setToolTip(std::string());
|
||||
}
|
||||
childSetEnabled("GroupCheck", FALSE);
|
||||
childSetEnabled("PassCheck", FALSE);
|
||||
childSetEnabled("pass_combo", FALSE);
|
||||
childSetEnabled("AccessList", FALSE);
|
||||
getChildView("GroupCheck")->setEnabled(FALSE);
|
||||
getChildView("PassCheck")->setEnabled(FALSE);
|
||||
getChildView("pass_combo")->setEnabled(FALSE);
|
||||
getChildView("AccessList")->setEnabled(FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
childSetEnabled("limit_payment", FALSE);
|
||||
childSetEnabled("limit_age_verified", FALSE);
|
||||
getChildView("limit_payment")->setEnabled(FALSE);
|
||||
getChildView("limit_age_verified")->setEnabled(FALSE);
|
||||
|
||||
std::string group_name;
|
||||
if (gCacheName->getGroupName(parcel->getGroupID(), group_name))
|
||||
{
|
||||
childSetEnabled("GroupCheck", can_manage_allowed);
|
||||
getChildView("GroupCheck")->setEnabled(can_manage_allowed);
|
||||
}
|
||||
BOOL group_access = childGetValue("GroupCheck").asBoolean();
|
||||
BOOL sell_passes = childGetValue("PassCheck").asBoolean();
|
||||
childSetEnabled("PassCheck", can_manage_allowed);
|
||||
BOOL group_access = getChild<LLUICtrl>("GroupCheck")->getValue().asBoolean();
|
||||
BOOL sell_passes = getChild<LLUICtrl>("PassCheck")->getValue().asBoolean();
|
||||
getChildView("PassCheck")->setEnabled(can_manage_allowed);
|
||||
if (sell_passes)
|
||||
{
|
||||
childSetEnabled("pass_combo", group_access && can_manage_allowed);
|
||||
childSetEnabled("PriceSpin", can_manage_allowed);
|
||||
childSetEnabled("HoursSpin", can_manage_allowed);
|
||||
getChildView("pass_combo")->setEnabled(group_access && can_manage_allowed);
|
||||
getChildView("PriceSpin")->setEnabled(can_manage_allowed);
|
||||
getChildView("HoursSpin")->setEnabled(can_manage_allowed);
|
||||
}
|
||||
}
|
||||
childSetEnabled("AccessList", can_manage_allowed);
|
||||
getChildView("AccessList")->setEnabled(can_manage_allowed);
|
||||
S32 allowed_list_count = parcel->mAccessList.size();
|
||||
childSetEnabled("add_allowed", can_manage_allowed && allowed_list_count < PARCEL_MAX_ACCESS_LIST);
|
||||
BOOL has_selected = mListAccess->getSelectionInterface()->getFirstSelectedIndex() >= 0;
|
||||
childSetEnabled("remove_allowed", can_manage_allowed && has_selected);
|
||||
getChildView("add_allowed")->setEnabled(can_manage_allowed && allowed_list_count < PARCEL_MAX_ACCESS_LIST);
|
||||
BOOL has_selected = (mListAccess && mListAccess->getSelectionInterface()->getFirstSelectedIndex() >= 0);
|
||||
getChildView("remove_allowed")->setEnabled(can_manage_allowed && has_selected);
|
||||
|
||||
childSetEnabled("BannedList", can_manage_banned);
|
||||
getChildView("BannedList")->setEnabled(can_manage_banned);
|
||||
S32 banned_list_count = parcel->mBanList.size();
|
||||
childSetEnabled("add_banned", can_manage_banned && banned_list_count < PARCEL_MAX_ACCESS_LIST);
|
||||
has_selected = mListBanned->getSelectionInterface()->getFirstSelectedIndex() >= 0;
|
||||
childSetEnabled("remove_banned", can_manage_banned && has_selected);
|
||||
getChildView("add_banned")->setEnabled(can_manage_banned && banned_list_count < PARCEL_MAX_ACCESS_LIST);
|
||||
has_selected = (mListBanned && mListBanned->getSelectionInterface()->getFirstSelectedIndex() >= 0);
|
||||
getChildView("remove_banned")->setEnabled(can_manage_banned && has_selected);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2707,7 +2737,7 @@ void LLPanelLandAccess::refreshNames()
|
||||
{
|
||||
gCacheName->getGroupName(parcel->getGroupID(), group_name);
|
||||
}
|
||||
childSetLabelArg("GroupCheck", "[GROUP]", group_name);
|
||||
getChild<LLUICtrl>("GroupCheck")->setLabelArg("[GROUP]", group_name);
|
||||
}
|
||||
|
||||
|
||||
@@ -2730,13 +2760,13 @@ void LLPanelLandAccess::onCommitPublicAccess(LLUICtrl *ctrl, void *userdata)
|
||||
}
|
||||
|
||||
// If we disabled public access, enable group access by default (if applicable)
|
||||
BOOL public_access = self->childGetValue("public_access").asBoolean();
|
||||
BOOL public_access = self->getChild<LLUICtrl>("public_access")->getValue().asBoolean();
|
||||
if (public_access == FALSE)
|
||||
{
|
||||
std::string group_name;
|
||||
if (gCacheName->getGroupName(parcel->getGroupID(), group_name))
|
||||
{
|
||||
self->childSetValue("GroupCheck", public_access ? FALSE : TRUE);
|
||||
self->getChild<LLUICtrl>("GroupCheck")->setValue(public_access ? FALSE : TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2755,8 +2785,8 @@ void LLPanelLandAccess::onCommitAny(LLUICtrl *ctrl, void *userdata)
|
||||
}
|
||||
|
||||
// Extract data from UI
|
||||
BOOL public_access = self->childGetValue("public_access").asBoolean();
|
||||
BOOL use_access_group = self->childGetValue("GroupCheck").asBoolean();
|
||||
BOOL public_access = self->getChild<LLUICtrl>("public_access")->getValue().asBoolean();
|
||||
BOOL use_access_group = self->getChild<LLUICtrl>("GroupCheck")->getValue().asBoolean();
|
||||
if (use_access_group)
|
||||
{
|
||||
std::string group_name;
|
||||
@@ -2774,13 +2804,13 @@ void LLPanelLandAccess::onCommitAny(LLUICtrl *ctrl, void *userdata)
|
||||
{
|
||||
use_access_list = FALSE;
|
||||
use_access_group = FALSE;
|
||||
limit_payment = self->childGetValue("limit_payment").asBoolean();
|
||||
limit_age_verified = self->childGetValue("limit_age_verified").asBoolean();
|
||||
limit_payment = self->getChild<LLUICtrl>("limit_payment")->getValue().asBoolean();
|
||||
limit_age_verified = self->getChild<LLUICtrl>("limit_age_verified")->getValue().asBoolean();
|
||||
}
|
||||
else
|
||||
{
|
||||
use_access_list = TRUE;
|
||||
use_pass_list = self->childGetValue("PassCheck").asBoolean();
|
||||
use_pass_list = self->getChild<LLUICtrl>("PassCheck")->getValue().asBoolean();
|
||||
if (use_access_group && use_pass_list)
|
||||
{
|
||||
LLCtrlSelectionInterface* passcombo = self->childGetSelectionInterface("pass_combo");
|
||||
@@ -2794,8 +2824,8 @@ void LLPanelLandAccess::onCommitAny(LLUICtrl *ctrl, void *userdata)
|
||||
}
|
||||
}
|
||||
|
||||
S32 pass_price = llfloor((F32)self->childGetValue("PriceSpin").asReal());
|
||||
F32 pass_hours = (F32)self->childGetValue("HoursSpin").asReal();
|
||||
S32 pass_price = llfloor((F32)self->getChild<LLUICtrl>("PriceSpin")->getValue().asReal());
|
||||
F32 pass_hours = (F32)self->getChild<LLUICtrl>("HoursSpin")->getValue().asReal();
|
||||
|
||||
// Push data into current parcel
|
||||
parcel->setParcelFlag(PF_USE_ACCESS_GROUP, use_access_group);
|
||||
@@ -2815,13 +2845,13 @@ void LLPanelLandAccess::onCommitAny(LLUICtrl *ctrl, void *userdata)
|
||||
self->refresh();
|
||||
}
|
||||
|
||||
// static
|
||||
void LLPanelLandAccess::onClickAddAccess(void* data)
|
||||
void LLPanelLandAccess::onClickAddAccess()
|
||||
{
|
||||
LLPanelLandAccess* panelp = (LLPanelLandAccess*)data;
|
||||
if (panelp)
|
||||
LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(
|
||||
boost::bind(&LLPanelLandAccess::callbackAvatarCBAccess, this, _1));
|
||||
if (picker)
|
||||
{
|
||||
gFloaterView->getParentFloater(panelp)->addDependentFloater(LLFloaterAvatarPicker::show(boost::bind(&LLPanelLandAccess::callbackAvatarCBAccess, panelp, _1)));
|
||||
gFloaterView->getParentFloater(this)->addDependentFloater(picker);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2863,11 +2893,14 @@ void LLPanelLandAccess::onClickRemoveAccess(void* data)
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void LLPanelLandAccess::onClickAddBanned(void* data)
|
||||
void LLPanelLandAccess::onClickAddBanned()
|
||||
{
|
||||
LLPanelLandAccess* panelp = (LLPanelLandAccess*)data;
|
||||
gFloaterView->getParentFloater(panelp)->addDependentFloater(LLFloaterAvatarPicker::show(boost::bind(&LLPanelLandAccess::callbackAvatarCBBanned, panelp, _1)));
|
||||
LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(
|
||||
boost::bind(&LLPanelLandAccess::callbackAvatarCBBanned, this, _1));
|
||||
if (picker)
|
||||
{
|
||||
gFloaterView->getParentFloater(this)->addDependentFloater(picker);
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelLandAccess::callbackAvatarCBBanned(const uuid_vec_t& ids)
|
||||
|
||||
@@ -49,11 +49,11 @@ class LLButton;
|
||||
class LLCheckBoxCtrl;
|
||||
class LLRadioGroup;
|
||||
class LLComboBox;
|
||||
class LLNameListCtrl;
|
||||
class LLSpinCtrl;
|
||||
class LLLineEditor;
|
||||
class LLNameListCtrl;
|
||||
class LLRadioGroup;
|
||||
class LLParcelSelectionObserver;
|
||||
class LLSpinCtrl;
|
||||
class LLTabContainer;
|
||||
class LLTextBox;
|
||||
class LLTextEditor;
|
||||
@@ -149,13 +149,13 @@ public:
|
||||
virtual void draw();
|
||||
|
||||
void setGroup(const LLUUID& group_id);
|
||||
static void onClickProfile(void*);
|
||||
static void onClickSetGroup(void*);
|
||||
void onClickProfile();
|
||||
void onClickSetGroup();
|
||||
static void onClickInfoGroup(void*);
|
||||
static void cbGroupID(LLUUID group_id, void* userdata);
|
||||
static BOOL enableDeedToGroup(void*);
|
||||
static void onClickDeed(void*);
|
||||
static void onClickBuyLand(void* data);
|
||||
static void onClickScriptLimits(void* data);
|
||||
static void onClickRelease(void*);
|
||||
static void onClickReclaim(void*);
|
||||
static void onClickBuyPass(void* deselect_when_done);
|
||||
@@ -225,6 +225,7 @@ protected:
|
||||
LLTextBox* mTextDwell;
|
||||
|
||||
LLButton* mBtnBuyLand;
|
||||
LLButton* mBtnScriptLimits;
|
||||
LLButton* mBtnBuyGroupLand;
|
||||
|
||||
// these buttons share the same location, but
|
||||
@@ -361,6 +362,7 @@ private:
|
||||
LLButton* mClearBtn;
|
||||
|
||||
LLCheckBoxCtrl *mMatureCtrl;
|
||||
LLCheckBoxCtrl *mGamingCtrl;
|
||||
LLCheckBoxCtrl *mPushRestrictionCtrl;
|
||||
LLCheckBoxCtrl *mSeeAvatarsCtrl;
|
||||
LLButton *mPublishHelpButton;
|
||||
@@ -382,15 +384,16 @@ public:
|
||||
|
||||
static void onCommitPublicAccess(LLUICtrl* ctrl, void *userdata);
|
||||
static void onCommitAny(LLUICtrl* ctrl, void *userdata);
|
||||
static void onClickAddAccess(void*);
|
||||
void callbackAvatarCBAccess(const uuid_vec_t& ids);
|
||||
static void onClickRemoveAccess(void*);
|
||||
static void onClickAddBanned(void*);
|
||||
void callbackAvatarCBBanned(const uuid_vec_t& ids);
|
||||
static void onClickRemoveBanned(void*);
|
||||
|
||||
virtual BOOL postBuild();
|
||||
|
||||
void onClickAddAccess();
|
||||
void onClickAddBanned();
|
||||
void callbackAvatarCBBanned(const uuid_vec_t& ids);
|
||||
void callbackAvatarCBAccess(const uuid_vec_t& ids);
|
||||
|
||||
protected:
|
||||
LLNameListCtrl* mListAccess;
|
||||
LLNameListCtrl* mListBanned;
|
||||
|
||||
@@ -1641,7 +1641,6 @@ bool LLModelLoader::doLoadModel()
|
||||
|
||||
//If no skeleton, do a breadth-first search to get at specific joints
|
||||
bool rootNode = false;
|
||||
bool skeletonWithNoRootNode = false;
|
||||
|
||||
//Need to test for a skeleton that does not have a root node
|
||||
//This occurs when your instance controller does not have an associated scene
|
||||
@@ -1652,10 +1651,6 @@ bool LLModelLoader::doLoadModel()
|
||||
{
|
||||
rootNode = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
skeletonWithNoRootNode = true;
|
||||
}
|
||||
|
||||
}
|
||||
if (!pSkeleton || !rootNode)
|
||||
@@ -5034,6 +5029,11 @@ BOOL LLModelPreview::render()
|
||||
refresh();
|
||||
}
|
||||
|
||||
if (use_shaders)
|
||||
{
|
||||
gObjectPreviewProgram.bind();
|
||||
}
|
||||
|
||||
gGL.loadIdentity();
|
||||
gPipeline.enableLightsPreview();
|
||||
|
||||
@@ -5043,8 +5043,9 @@ BOOL LLModelPreview::render()
|
||||
LLQuaternion av_rot = camera_rot;
|
||||
LLViewerCamera::getInstance()->setOriginAndLookAt(
|
||||
target_pos + ((LLVector3(mCameraDistance, 0.f, 0.f) + offset) * av_rot), // camera
|
||||
LLVector3::z_axis, // up
|
||||
target_pos); // point of interest
|
||||
LLVector3::z_axis, // up
|
||||
target_pos); // point of interest
|
||||
|
||||
|
||||
z_near = llclamp(z_far * 0.001f, 0.001f, 0.1f);
|
||||
|
||||
@@ -5058,11 +5059,6 @@ BOOL LLModelPreview::render()
|
||||
|
||||
const U32 type_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0;
|
||||
|
||||
if (use_shaders)
|
||||
{
|
||||
gObjectPreviewProgram.bind();
|
||||
}
|
||||
|
||||
LLGLEnable normalize(GL_NORMALIZE);
|
||||
|
||||
if (!mBaseModel.empty() && mVertexBuffer[5].empty())
|
||||
@@ -5248,10 +5244,10 @@ BOOL LLModelPreview::render()
|
||||
|
||||
if (i + 1 >= hull_colors.size())
|
||||
{
|
||||
hull_colors.push_back(LLColor4U(rand()%128 + 127, rand()%128 + 127, rand()%128 + 127, 128));
|
||||
hull_colors.push_back(LLColor4U(rand()%128+127, rand()%128+127, rand()%128+127, 128));
|
||||
}
|
||||
|
||||
glColor4ubv(hull_colors[i].mV);
|
||||
gGL.diffuseColor4ubv(hull_colors[i].mV);
|
||||
LLVertexBuffer::drawArrays(LLRender::TRIANGLES, physics.mMesh[i].mPositions, physics.mMesh[i].mNormals);
|
||||
|
||||
if (explode > 0.f)
|
||||
|
||||
1352
indra/newview/llfloaterscriptlimits.cpp
Normal file
1352
indra/newview/llfloaterscriptlimits.cpp
Normal file
File diff suppressed because it is too large
Load Diff
271
indra/newview/llfloaterscriptlimits.h
Normal file
271
indra/newview/llfloaterscriptlimits.h
Normal file
@@ -0,0 +1,271 @@
|
||||
/**
|
||||
* @file llfloaterscriptlimits.h
|
||||
* @author Gabriel Lee
|
||||
* @brief Declaration of the region info and controls floater and panels.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2004&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLFLOATERSCRIPTLIMITS_H
|
||||
#define LL_LLFLOATERSCRIPTLIMITS_H
|
||||
|
||||
#include <vector>
|
||||
#include "llfloater.h"
|
||||
#include "llhost.h"
|
||||
#include "llpanel.h"
|
||||
#include "llremoteparcelrequest.h"
|
||||
|
||||
class LLPanelScriptLimitsInfo;
|
||||
class LLTabContainer;
|
||||
|
||||
class LLPanelScriptLimitsRegionMemory;
|
||||
|
||||
class LLFloaterScriptLimits : public LLFloater, public LLFloaterSingleton<LLFloaterScriptLimits>
|
||||
{
|
||||
friend class LLUISingleton<LLFloaterScriptLimits, VisibilityPolicy<LLFloater> >;
|
||||
public:
|
||||
|
||||
/*virtual*/ BOOL postBuild();
|
||||
|
||||
// from LLPanel
|
||||
virtual void refresh();
|
||||
|
||||
private:
|
||||
|
||||
LLFloaterScriptLimits(const LLSD& seed);
|
||||
~LLFloaterScriptLimits();
|
||||
|
||||
protected:
|
||||
|
||||
LLTabContainer* mTab;
|
||||
typedef std::vector<LLPanelScriptLimitsInfo*> info_panels_t;
|
||||
info_panels_t mInfoPanels;
|
||||
};
|
||||
|
||||
|
||||
// Base class for all script limits information panels.
|
||||
class LLPanelScriptLimitsInfo : public LLPanel
|
||||
{
|
||||
public:
|
||||
LLPanelScriptLimitsInfo();
|
||||
|
||||
virtual BOOL postBuild();
|
||||
virtual void updateChild(LLUICtrl* child_ctrl);
|
||||
|
||||
protected:
|
||||
void initCtrl(const std::string& name);
|
||||
|
||||
typedef std::vector<std::string> strings_t;
|
||||
|
||||
LLHost mHost;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Responders
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
class AIHTTPTimeoutPolicy;
|
||||
|
||||
extern AIHTTPTimeoutPolicy fetchScriptLimitsRegionInfoResponder_timeout;
|
||||
class fetchScriptLimitsRegionInfoResponder: public LLHTTPClient::ResponderWithResult
|
||||
{
|
||||
public:
|
||||
fetchScriptLimitsRegionInfoResponder(const LLSD& info) : mInfo(info) {};
|
||||
|
||||
void result(const LLSD& content);
|
||||
void error(U32 status, const std::string& reason);
|
||||
public:
|
||||
/*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return fetchScriptLimitsRegionInfoResponder_timeout; }
|
||||
/*virtual*/ char const* getName(void) const { return "fetchScriptLimitsRegionInfoResponder"; }
|
||||
protected:
|
||||
LLSD mInfo;
|
||||
};
|
||||
|
||||
extern AIHTTPTimeoutPolicy fetchScriptLimitsRegionSummaryResponder_timeout;
|
||||
class fetchScriptLimitsRegionSummaryResponder: public LLHTTPClient::ResponderWithResult
|
||||
{
|
||||
public:
|
||||
fetchScriptLimitsRegionSummaryResponder(const LLSD& info) : mInfo(info) {};
|
||||
|
||||
void result(const LLSD& content);
|
||||
void error(U32 status, const std::string& reason);
|
||||
public:
|
||||
/*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return fetchScriptLimitsRegionSummaryResponder_timeout; }
|
||||
/*virtual*/ char const* getName(void) const { return "fetchScriptLimitsRegionSummaryResponder"; }
|
||||
protected:
|
||||
LLSD mInfo;
|
||||
};
|
||||
|
||||
extern AIHTTPTimeoutPolicy fetchScriptLimitsRegionDetailsResponder_timeout;
|
||||
class fetchScriptLimitsRegionDetailsResponder: public LLHTTPClient::ResponderWithResult
|
||||
{
|
||||
public:
|
||||
fetchScriptLimitsRegionDetailsResponder(const LLSD& info) : mInfo(info) {};
|
||||
|
||||
void result(const LLSD& content);
|
||||
void error(U32 status, const std::string& reason);
|
||||
public:
|
||||
/*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return fetchScriptLimitsRegionDetailsResponder_timeout; }
|
||||
/*virtual*/ char const* getName(void) const { return "fetchScriptLimitsRegionDetailsResponder"; }
|
||||
protected:
|
||||
LLSD mInfo;
|
||||
};
|
||||
|
||||
extern AIHTTPTimeoutPolicy fetchScriptLimitsAttachmentInfoResponder_timeout;
|
||||
class fetchScriptLimitsAttachmentInfoResponder: public LLHTTPClient::ResponderWithResult
|
||||
{
|
||||
public:
|
||||
fetchScriptLimitsAttachmentInfoResponder() {};
|
||||
|
||||
void result(const LLSD& content);
|
||||
void error(U32 status, const std::string& reason);
|
||||
public:
|
||||
/*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return fetchScriptLimitsAttachmentInfoResponder_timeout; }
|
||||
/*virtual*/ char const* getName(void) const { return "fetchScriptLimitsAttachmentInfoResponder"; }
|
||||
protected:
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Memory panel
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class LLPanelScriptLimitsRegionMemory : public LLPanelScriptLimitsInfo, LLRemoteParcelInfoObserver
|
||||
{
|
||||
|
||||
public:
|
||||
LLPanelScriptLimitsRegionMemory()
|
||||
: LLPanelScriptLimitsInfo(), LLRemoteParcelInfoObserver(),
|
||||
|
||||
mParcelId(LLUUID()),
|
||||
mGotParcelMemoryUsed(false),
|
||||
mGotParcelMemoryMax(false),
|
||||
mParcelMemoryMax(0),
|
||||
mParcelMemoryUsed(0) {};
|
||||
|
||||
~LLPanelScriptLimitsRegionMemory();
|
||||
|
||||
// LLPanel
|
||||
virtual BOOL postBuild();
|
||||
|
||||
void setRegionDetails(LLSD content);
|
||||
void setRegionSummary(LLSD content);
|
||||
|
||||
BOOL StartRequestChain();
|
||||
|
||||
BOOL getLandScriptResources();
|
||||
void clearList();
|
||||
void showBeacon();
|
||||
void returnObjectsFromParcel(S32 local_id);
|
||||
void returnObjects();
|
||||
|
||||
private:
|
||||
void onNameCache(const LLUUID& id,
|
||||
const std::string& name);
|
||||
|
||||
LLSD mContent;
|
||||
LLUUID mParcelId;
|
||||
bool mGotParcelMemoryUsed;
|
||||
bool mGotParcelMemoryUsedDetails;
|
||||
bool mGotParcelMemoryMax;
|
||||
S32 mParcelMemoryMax;
|
||||
S32 mParcelMemoryUsed;
|
||||
S32 mParcelMemoryUsedDetails;
|
||||
|
||||
bool mGotParcelURLsUsed;
|
||||
bool mGotParcelURLsUsedDetails;
|
||||
bool mGotParcelURLsMax;
|
||||
S32 mParcelURLsMax;
|
||||
S32 mParcelURLsUsed;
|
||||
S32 mParcelURLsUsedDetails;
|
||||
|
||||
std::vector<LLSD> mObjectListItems;
|
||||
|
||||
protected:
|
||||
|
||||
// LLRemoteParcelInfoObserver interface:
|
||||
/*virtual*/ void processParcelInfo(const LLParcelData& parcel_data);
|
||||
/*virtual*/ void setParcelID(const LLUUID& parcel_id);
|
||||
/*virtual*/ void setErrorStatus(U32 status, const std::string& reason);
|
||||
|
||||
static void onClickRefresh(void* userdata);
|
||||
static void onClickHighlight(void* userdata);
|
||||
static void onClickReturn(void* userdata);
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Attachment panel
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class LLPanelScriptLimitsAttachment : public LLPanelScriptLimitsInfo
|
||||
{
|
||||
|
||||
public:
|
||||
LLPanelScriptLimitsAttachment()
|
||||
: LLPanelScriptLimitsInfo(),
|
||||
mGotAttachmentMemoryUsed(false),
|
||||
mGotAttachmentMemoryUsedDetails(false),
|
||||
mGotAttachmentMemoryMax(false),
|
||||
mAttachmentMemoryMax(0),
|
||||
mAttachmentMemoryUsed(0),
|
||||
mAttachmentMemoryUsedDetails(0),
|
||||
mGotAttachmentURLsUsed(false),
|
||||
mGotAttachmentURLsUsedDetails(false),
|
||||
mGotAttachmentURLsMax(false),
|
||||
mAttachmentURLsMax(0),
|
||||
mAttachmentURLsUsed(0),
|
||||
mAttachmentURLsUsedDetails(0)
|
||||
{};
|
||||
|
||||
~LLPanelScriptLimitsAttachment()
|
||||
{
|
||||
};
|
||||
|
||||
// LLPanel
|
||||
virtual BOOL postBuild();
|
||||
|
||||
void setAttachmentDetails(LLSD content);
|
||||
|
||||
void setAttachmentSummary(LLSD content);
|
||||
BOOL requestAttachmentDetails();
|
||||
void clearList();
|
||||
|
||||
private:
|
||||
|
||||
bool mGotAttachmentMemoryUsed;
|
||||
bool mGotAttachmentMemoryUsedDetails;
|
||||
bool mGotAttachmentMemoryMax;
|
||||
S32 mAttachmentMemoryMax;
|
||||
S32 mAttachmentMemoryUsed;
|
||||
S32 mAttachmentMemoryUsedDetails;
|
||||
|
||||
bool mGotAttachmentURLsUsed;
|
||||
bool mGotAttachmentURLsUsedDetails;
|
||||
bool mGotAttachmentURLsMax;
|
||||
S32 mAttachmentURLsMax;
|
||||
S32 mAttachmentURLsUsed;
|
||||
S32 mAttachmentURLsUsedDetails;
|
||||
|
||||
protected:
|
||||
|
||||
static void onClickRefresh(void* userdata);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -91,8 +91,8 @@
|
||||
///----------------------------------------------------------------------------
|
||||
/// Local function declarations, constants, enums, and typedefs
|
||||
///----------------------------------------------------------------------------
|
||||
S32 LLFloaterSnapshot::sUIWinHeightLong = 619 ;
|
||||
S32 LLFloaterSnapshot::sUIWinHeightShort = LLFloaterSnapshot::sUIWinHeightLong - 260 ;
|
||||
S32 LLFloaterSnapshot::sUIWinHeightLong = 625 ;
|
||||
S32 LLFloaterSnapshot::sUIWinHeightShort = LLFloaterSnapshot::sUIWinHeightLong - 266 ;
|
||||
S32 LLFloaterSnapshot::sUIWinWidth = 219 ;
|
||||
S32 const THUMBHEIGHT = 159;
|
||||
|
||||
@@ -111,6 +111,8 @@ S32 BORDER_WIDTH = 6;
|
||||
const S32 MAX_POSTCARD_DATASIZE = 1024 * 1024; // one megabyte
|
||||
const S32 MAX_TEXTURE_SIZE = 512 ; //max upload texture size 512 * 512
|
||||
|
||||
static std::string snapshotKeepAspectName();
|
||||
|
||||
///----------------------------------------------------------------------------
|
||||
/// Class LLSnapshotLivePreview
|
||||
///----------------------------------------------------------------------------
|
||||
@@ -172,6 +174,7 @@ public:
|
||||
BOOL getThumbnailUpToDate() const { return mThumbnailUpToDate ;}
|
||||
bool getShowFreezeFrameSnapshot() const { return mShowFreezeFrameSnapshot; }
|
||||
LLViewerTexture* getCurrentImage();
|
||||
char const* resolutionComboName() const;
|
||||
char const* aspectComboName() const;
|
||||
|
||||
void setSnapshotType(ESnapshotType type) { mSnapshotType = type; }
|
||||
@@ -305,6 +308,7 @@ public:
|
||||
static void onClickUICheck(LLUICtrl *ctrl, void* data);
|
||||
static void onClickHUDCheck(LLUICtrl *ctrl, void* data);
|
||||
static void onClickKeepOpenCheck(LLUICtrl *ctrl, void* data);
|
||||
static void onClickKeepAspect(LLUICtrl* ctrl, void* data);
|
||||
static void onCommitQuality(LLUICtrl* ctrl, void* data);
|
||||
static void onCommitFeedResolution(LLUICtrl* ctrl, void* data);
|
||||
static void onCommitPostcardResolution(LLUICtrl* ctrl, void* data);
|
||||
@@ -327,10 +331,14 @@ public:
|
||||
static LLSnapshotLivePreview* getPreviewView(void);
|
||||
static void setResolution(LLFloaterSnapshot* floater, const std::string& comboname, bool visible, bool update_controls = true);
|
||||
static void setAspect(LLFloaterSnapshot* floater, const std::string& comboname, bool update_controls = true);
|
||||
static void storeAspectSetting(LLComboBox* combo, const std::string& comboname);
|
||||
static void enforceAspect(LLFloaterSnapshot* floater, F32 new_aspect);
|
||||
static void enforceResolution(LLFloaterSnapshot* floater, F32 new_aspect);
|
||||
static void updateControls(LLFloaterSnapshot* floater, bool delayed_formatted = false);
|
||||
static void resetFeedAndPostcardAspect(LLFloaterSnapshot* floater);
|
||||
static void updateLayout(LLFloaterSnapshot* floater);
|
||||
static void freezeTime(bool on);
|
||||
static void keepAspect(LLFloaterSnapshot* view, bool on, bool force = false);
|
||||
|
||||
static LLHandle<LLView> sPreviewHandle;
|
||||
|
||||
@@ -345,7 +353,6 @@ public:
|
||||
|
||||
LLToolset* mLastToolset;
|
||||
boost::signals2::connection mQualityMouseUpConnection;
|
||||
LLFocusableElement* mPrevDefaultKeyboardFocus;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -404,7 +411,7 @@ LLSnapshotLivePreview::LLSnapshotLivePreview (const LLRect& rect) :
|
||||
mNeedsFlash(TRUE),
|
||||
mSnapshotQuality(gSavedSettings.getS32("SnapshotQuality")),
|
||||
mFormattedDataSize(0),
|
||||
mSnapshotType(SNAPSHOT_FEED),
|
||||
mSnapshotType((ESnapshotType)gSavedSettings.getS32("LastSnapshotType")),
|
||||
mSnapshotFormat(LLFloaterSnapshot::ESnapshotFormat(gSavedSettings.getS32("SnapshotFormat"))),
|
||||
mShowFreezeFrameSnapshot(FALSE),
|
||||
mCameraPos(LLViewerCamera::getInstance()->getOrigin()),
|
||||
@@ -1716,14 +1723,12 @@ void LLFloaterSnapshot::Impl::freezeTime(bool on)
|
||||
}
|
||||
|
||||
// Make sure the floater keeps focus so that pressing ESC stops Freeze Time mode.
|
||||
sInstance->impl.mPrevDefaultKeyboardFocus = gFocusMgr.getDefaultKeyboardFocus();
|
||||
gFocusMgr.setDefaultKeyboardFocus(sInstance);
|
||||
}
|
||||
else if (gSavedSettings.getBOOL("FreezeTime")) // turning off freeze frame mode
|
||||
{
|
||||
// Restore default keyboard focus.
|
||||
gFocusMgr.setDefaultKeyboardFocus(sInstance->impl.mPrevDefaultKeyboardFocus);
|
||||
sInstance->impl.mPrevDefaultKeyboardFocus = NULL;
|
||||
gFocusMgr.restoreDefaultKeyboardFocus(sInstance);
|
||||
|
||||
gSnapshotFloaterView->setMouseOpaque(FALSE);
|
||||
|
||||
@@ -1803,7 +1808,6 @@ void LLFloaterSnapshot::Impl::updateControls(LLFloaterSnapshot* floater, bool de
|
||||
LLSnapshotLivePreview* previewp = getPreviewView();
|
||||
if (previewp)
|
||||
{
|
||||
previewp->setSnapshotType(shot_type);
|
||||
LLViewerWindow::ESnapshotType layer_type =
|
||||
(shot_type == LLSnapshotLivePreview::SNAPSHOT_LOCAL) ?
|
||||
(LLViewerWindow::ESnapshotType)gSavedSettings.getS32("SnapshotLayerType") :
|
||||
@@ -1844,6 +1848,7 @@ void LLFloaterSnapshot::Impl::updateControls(LLFloaterSnapshot* floater, bool de
|
||||
floater->childSetVisible("more_btn", !is_advance); // the only item hidden in advanced mode
|
||||
floater->childSetVisible("less_btn", is_advance);
|
||||
floater->childSetVisible("type_label2", is_advance);
|
||||
floater->childSetVisible("keep_aspect", is_advance);
|
||||
floater->childSetVisible("type_label3", is_advance);
|
||||
floater->childSetVisible("format_label", is_advance && is_local);
|
||||
floater->childSetVisible("local_format_combo", is_local);
|
||||
@@ -1899,6 +1904,8 @@ void LLFloaterSnapshot::Impl::updateControls(LLFloaterSnapshot* floater, bool de
|
||||
shot_type == LLSnapshotLivePreview::SNAPSHOT_POSTCARD
|
||||
&& got_bytes
|
||||
&& previewp->getDataSize() > MAX_POSTCARD_DATASIZE ? LLColor4::red : gColors.getColor( "LabelTextColor" ));
|
||||
std::string target_size_str = gSavedSettings.getBOOL(snapshotKeepAspectName()) ? floater->getString("sourceAR") : floater->getString("targetAR");
|
||||
floater->childSetValue("type_label3", target_size_str);
|
||||
|
||||
bool up_to_date = previewp && previewp->getSnapshotUpToDate();
|
||||
bool can_upload = up_to_date && !previewp->isUsedBy(shot_type);
|
||||
@@ -1987,6 +1994,11 @@ void LLFloaterSnapshot::Impl::onCommitFeedAspect(LLUICtrl* ctrl, void* data)
|
||||
previewp->addManualOverride(LLSnapshotLivePreview::SNAPSHOT_FEED);
|
||||
}
|
||||
updateAspect(ctrl, data);
|
||||
LLFloaterSnapshot* floater = (LLFloaterSnapshot*)data;
|
||||
if (floater && previewp && gSavedSettings.getBOOL(snapshotKeepAspectName()))
|
||||
{
|
||||
enforceResolution(floater, previewp->getAspect());
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
@@ -2000,6 +2012,11 @@ void LLFloaterSnapshot::Impl::onCommitPostcardAspect(LLUICtrl* ctrl, void* data)
|
||||
previewp->addManualOverride(LLSnapshotLivePreview::SNAPSHOT_POSTCARD);
|
||||
}
|
||||
updateAspect(ctrl, data);
|
||||
LLFloaterSnapshot* floater = (LLFloaterSnapshot*)data;
|
||||
if (floater && previewp && gSavedSettings.getBOOL(snapshotKeepAspectName()))
|
||||
{
|
||||
enforceResolution(floater, previewp->getAspect());
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
@@ -2026,6 +2043,11 @@ void LLFloaterSnapshot::Impl::onCommitLocalAspect(LLUICtrl* ctrl, void* data)
|
||||
previewp->addManualOverride(LLSnapshotLivePreview::SNAPSHOT_LOCAL);
|
||||
}
|
||||
updateAspect(ctrl, data);
|
||||
LLFloaterSnapshot* floater = (LLFloaterSnapshot*)data;
|
||||
if (floater && previewp && gSavedSettings.getBOOL(snapshotKeepAspectName()))
|
||||
{
|
||||
enforceResolution(floater, previewp->getAspect());
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
@@ -2252,6 +2274,18 @@ void LLFloaterSnapshot::Impl::onClickKeepOpenCheck(LLUICtrl* ctrl, void* data)
|
||||
gSavedSettings.setBOOL( "CloseSnapshotOnKeep", !check->get() );
|
||||
}
|
||||
|
||||
// static
|
||||
void LLFloaterSnapshot::Impl::onClickKeepAspect(LLUICtrl* ctrl, void* data)
|
||||
{
|
||||
LLFloaterSnapshot* view = (LLFloaterSnapshot*)data;
|
||||
if (view)
|
||||
{
|
||||
LLCheckBoxCtrl* check = (LLCheckBoxCtrl*)ctrl;
|
||||
keepAspect(view, check->get());
|
||||
updateControls(view);
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void LLFloaterSnapshot::Impl::onCommitQuality(LLUICtrl* ctrl, void* data)
|
||||
{
|
||||
@@ -2321,6 +2355,46 @@ static std::string lastSnapshotAspectName()
|
||||
}
|
||||
}
|
||||
|
||||
static std::string snapshotKeepAspectName()
|
||||
{
|
||||
switch(gSavedSettings.getS32("LastSnapshotType"))
|
||||
{
|
||||
case LLSnapshotLivePreview::SNAPSHOT_FEED: return "SnapshotFeedKeepAspect";
|
||||
case LLSnapshotLivePreview::SNAPSHOT_POSTCARD: return "SnapshotPostcardKeepAspect";
|
||||
case LLSnapshotLivePreview::SNAPSHOT_TEXTURE: return "SnapshotTextureKeepAspect";
|
||||
default: return "SnapshotLocalKeepAspect";
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void LLFloaterSnapshot::Impl::keepAspect(LLFloaterSnapshot* view, bool on, bool force)
|
||||
{
|
||||
DoutEntering(dc::snapshot, "LLFloaterSnapshot::Impl::keepAspect(view, " << on << ", " << force << ")");
|
||||
bool cur_on = gSavedSettings.getBOOL(snapshotKeepAspectName());
|
||||
if ((!force && cur_on == on) ||
|
||||
gSavedSettings.getBOOL("RenderUIInSnapshot") ||
|
||||
gSavedSettings.getBOOL("RenderHUDInSnapshot"))
|
||||
{
|
||||
// No change.
|
||||
return;
|
||||
}
|
||||
view->childSetValue("keep_aspect", on);
|
||||
gSavedSettings.setBOOL(snapshotKeepAspectName(), on);
|
||||
if (on)
|
||||
{
|
||||
LLSnapshotLivePreview* previewp = getPreviewView();
|
||||
if (previewp)
|
||||
{
|
||||
S32 w = llround(view->childGetValue("snapshot_width").asReal(), 1.0);
|
||||
S32 h = llround(view->childGetValue("snapshot_height").asReal(), 1.0);
|
||||
gSavedSettings.setS32(lastSnapshotWidthName(), w);
|
||||
gSavedSettings.setS32(lastSnapshotHeightName(), h);
|
||||
comboSetCustom(view, previewp->resolutionComboName());
|
||||
enforceAspect(view, (F32)w / h);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void LLFloaterSnapshot::Impl::updateResolution(LLUICtrl* ctrl, void* data, bool update_controls)
|
||||
{
|
||||
@@ -2332,192 +2406,12 @@ void LLFloaterSnapshot::Impl::updateResolution(LLUICtrl* ctrl, void* data, bool
|
||||
return;
|
||||
}
|
||||
|
||||
S32 new_width = 0;
|
||||
S32 new_height = 0;
|
||||
F32 new_aspect = 0;
|
||||
LLSnapshotLivePreview* previewp = getPreviewView();
|
||||
#if 0 // Broken -- not doing this for now.
|
||||
LLSnapshotLivePreview::ESnapshotType shot_type = (LLSnapshotLivePreview::ESnapshotType)gSavedSettings.getS32("LastSnapshotType");
|
||||
|
||||
// Is the snapshot was already used (saved or uploaded) and no manual changes
|
||||
// have been made since to the current destination type, and the raw snapshot
|
||||
// is still up to date with regard to visibility of UI, HUD and BufferType etc?
|
||||
if (previewp && previewp->isUsed() && !previewp->isOverriddenBy(shot_type) && previewp->getRawSnapshotUpToDate())
|
||||
{
|
||||
previewp->getSize(new_width, new_height);
|
||||
new_aspect = previewp->getAspect();
|
||||
S32 const old_width = new_width;
|
||||
S32 const old_height = new_height;
|
||||
F32 const old_aspect = new_aspect;
|
||||
S32 raw_width;
|
||||
S32 raw_height;
|
||||
previewp->getRawSize(raw_width, raw_height);
|
||||
F32 const raw_aspect = (F32)raw_width / raw_height;
|
||||
bool fixed_crop = false;
|
||||
bool fixed_size = false;
|
||||
bool fixed_scale = false;
|
||||
bool done = false;
|
||||
bool fail = false;
|
||||
while (!done)
|
||||
{
|
||||
// Attempt to change the size and aspect so the raw snapshot can also be used for this new destination.
|
||||
S32 w, h, crop_offset;
|
||||
bool crop_vertically;
|
||||
previewp->setSize(new_width, new_height);
|
||||
previewp->setAspect(new_aspect);
|
||||
LLSnapshotLivePreview::EAspectSizeProblem ret = previewp->getAspectSizeProblem(w, h, crop_vertically, crop_offset);
|
||||
switch(ret)
|
||||
{
|
||||
case LLSnapshotLivePreview::ASPECTSIZE_OK:
|
||||
done = true; // Don't change anything (else) if the current settings are usable.
|
||||
break;
|
||||
case LLSnapshotLivePreview::CANNOT_CROP_HORIZONTALLY:
|
||||
case LLSnapshotLivePreview::CANNOT_CROP_VERTICALLY:
|
||||
if (fixed_crop)
|
||||
{
|
||||
done = fail = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Set target aspect to aspect of the raw snapshot we have (no reason to crop anything).
|
||||
new_aspect = raw_aspect;
|
||||
fixed_crop = true;
|
||||
}
|
||||
break;
|
||||
case LLSnapshotLivePreview::SIZE_TOO_LARGE:
|
||||
if (fixed_size)
|
||||
{
|
||||
done = fail = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (new_width > w)
|
||||
{
|
||||
new_width = w;
|
||||
new_height = llround(new_width / new_aspect);
|
||||
}
|
||||
if (new_height > h)
|
||||
{
|
||||
new_width = llmin(w, llround(h * new_aspect));
|
||||
new_height = llmin(h, llround(new_width / new_aspect));
|
||||
}
|
||||
fixed_size = true;
|
||||
}
|
||||
break;
|
||||
case LLSnapshotLivePreview::CANNOT_RESIZE:
|
||||
if (fixed_scale)
|
||||
{
|
||||
done = fail = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
F32 ratio = llmin((F32)w / new_width, (F32)h / new_height);
|
||||
new_width = llround(new_width * ratio);
|
||||
new_height = llround(new_height * ratio);
|
||||
fixed_scale = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
previewp->setAspect(old_aspect);
|
||||
previewp->setSize(old_width, old_height);
|
||||
if (fail)
|
||||
{
|
||||
new_aspect = 0;
|
||||
new_width = new_height = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
LLComboBox* size_combo_box = NULL;
|
||||
LLComboBox* aspect_combo_box = NULL;
|
||||
switch(shot_type)
|
||||
{
|
||||
case LLSnapshotLivePreview::SNAPSHOT_FEED:
|
||||
size_combo_box = view->getChild<LLComboBox>("feed_size_combo");
|
||||
aspect_combo_box = view->getChild<LLComboBox>("feed_aspect_combo");
|
||||
break;
|
||||
case LLSnapshotLivePreview::SNAPSHOT_POSTCARD:
|
||||
size_combo_box = view->getChild<LLComboBox>("postcard_size_combo");
|
||||
aspect_combo_box = view->getChild<LLComboBox>("postcard_aspect_combo");
|
||||
break;
|
||||
case LLSnapshotLivePreview::SNAPSHOT_TEXTURE:
|
||||
size_combo_box = view->getChild<LLComboBox>("texture_size_combo");
|
||||
aspect_combo_box = view->getChild<LLComboBox>("texture_aspect_combo");
|
||||
break;
|
||||
case LLSnapshotLivePreview::SNAPSHOT_LOCAL:
|
||||
size_combo_box = view->getChild<LLComboBox>("local_size_combo");
|
||||
aspect_combo_box = view->getChild<LLComboBox>("local_aspect_combo");
|
||||
break;
|
||||
}
|
||||
S32 index = 0;
|
||||
S32 const size_custom = size_combo_box->getItemCount() - (shot_type == LLSnapshotLivePreview::SNAPSHOT_TEXTURE ? 0 : 1); // Texture does not end on 'Custom'.
|
||||
while (index < size_custom)
|
||||
{
|
||||
size_combo_box->setCurrentByIndex(index);
|
||||
std::string sdstring = size_combo_box->getSelectedValue();
|
||||
LLSD sdres;
|
||||
std::stringstream sstream(sdstring);
|
||||
LLSDSerialize::fromNotation(sdres, sstream, sdstring.size());
|
||||
S32 width = sdres[0];
|
||||
S32 height = sdres[1];
|
||||
if (width == 0 || height == 0)
|
||||
{
|
||||
width = gViewerWindow->getWindowDisplayWidth();
|
||||
height = gViewerWindow->getWindowDisplayHeight();
|
||||
}
|
||||
if (width == new_width && height == new_height)
|
||||
{
|
||||
break;
|
||||
}
|
||||
++index;
|
||||
}
|
||||
if (index == size_custom && shot_type != LLSnapshotLivePreview::SNAPSHOT_TEXTURE)
|
||||
{
|
||||
size_combo_box->setCurrentByIndex(index);
|
||||
}
|
||||
index = 0;
|
||||
S32 const aspect_custom = aspect_combo_box->getItemCount() - 1;
|
||||
while (index < aspect_custom)
|
||||
{
|
||||
aspect_combo_box->setCurrentByIndex(index);
|
||||
std::string sdstring = aspect_combo_box->getSelectedValue();
|
||||
std::stringstream sstream;
|
||||
sstream << sdstring;
|
||||
F32 aspect;
|
||||
sstream >> aspect;
|
||||
if (aspect == -2) // Default
|
||||
{
|
||||
aspect = (F32)new_width / new_height;
|
||||
}
|
||||
if (aspect == 0) // Current window
|
||||
{
|
||||
aspect = (F32)gViewerWindow->getWindowDisplayWidth() / gViewerWindow->getWindowDisplayHeight();
|
||||
}
|
||||
if (llabs(aspect - new_aspect) < 0.0001)
|
||||
{
|
||||
break;
|
||||
}
|
||||
++index;
|
||||
}
|
||||
if (index == aspect_custom)
|
||||
{
|
||||
aspect_combo_box->setCurrentByIndex(index);
|
||||
setAspect(view, previewp->aspectComboName(), update_controls);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
view->getChild<LLComboBox>("feed_size_combo")->selectNthItem(gSavedSettings.getS32("SnapshotFeedLastResolution"));
|
||||
view->getChild<LLComboBox>("feed_aspect_combo")->selectNthItem(gSavedSettings.getS32("SnapshotFeedLastAspect"));
|
||||
view->getChild<LLComboBox>("postcard_size_combo")->selectNthItem(gSavedSettings.getS32("SnapshotPostcardLastResolution"));
|
||||
view->getChild<LLComboBox>("postcard_aspect_combo")->selectNthItem(gSavedSettings.getS32("SnapshotPostcardLastAspect"));
|
||||
view->getChild<LLComboBox>("texture_size_combo")->selectNthItem(gSavedSettings.getS32("SnapshotTextureLastResolution"));
|
||||
view->getChild<LLComboBox>("texture_aspect_combo")->selectNthItem(gSavedSettings.getS32("SnapshotTextureLastAspect"));
|
||||
view->getChild<LLComboBox>("local_size_combo")->selectNthItem(gSavedSettings.getS32("SnapshotLocalLastResolution"));
|
||||
view->getChild<LLComboBox>("local_aspect_combo")->selectNthItem(gSavedSettings.getS32("SnapshotLocalLastAspect"));
|
||||
}
|
||||
view->getChild<LLComboBox>("feed_size_combo")->selectNthItem(gSavedSettings.getS32("SnapshotFeedLastResolution"));
|
||||
view->getChild<LLComboBox>("postcard_size_combo")->selectNthItem(gSavedSettings.getS32("SnapshotPostcardLastResolution"));
|
||||
view->getChild<LLComboBox>("texture_size_combo")->selectNthItem(gSavedSettings.getS32("SnapshotTextureLastResolution"));
|
||||
view->getChild<LLComboBox>("local_size_combo")->selectNthItem(gSavedSettings.getS32("SnapshotLocalLastResolution"));
|
||||
|
||||
std::string sdstring = combobox->getSelectedValue();
|
||||
LLSD sdres;
|
||||
@@ -2526,6 +2420,12 @@ void LLFloaterSnapshot::Impl::updateResolution(LLUICtrl* ctrl, void* data, bool
|
||||
|
||||
S32 width = sdres[0];
|
||||
S32 height = sdres[1];
|
||||
|
||||
if (width != -1 && height != -1)
|
||||
{
|
||||
// Not "Custom".
|
||||
keepAspect(view, false);
|
||||
}
|
||||
|
||||
if (previewp && combobox->getCurrentIndex() >= 0)
|
||||
{
|
||||
@@ -2538,15 +2438,8 @@ void LLFloaterSnapshot::Impl::updateResolution(LLUICtrl* ctrl, void* data, bool
|
||||
}
|
||||
else if (width == -1 || height == -1)
|
||||
{
|
||||
if (previewp->isUsed() && new_width != 0 && new_height != 0)
|
||||
{
|
||||
previewp->setSize(new_width, new_height);
|
||||
}
|
||||
else
|
||||
{
|
||||
// load last custom value
|
||||
previewp->setSize(gSavedSettings.getS32(lastSnapshotWidthName()), gSavedSettings.getS32(lastSnapshotHeightName()));
|
||||
}
|
||||
// load last custom value
|
||||
previewp->setSize(gSavedSettings.getS32(lastSnapshotWidthName()), gSavedSettings.getS32(lastSnapshotHeightName()));
|
||||
}
|
||||
else if (height == -2)
|
||||
{
|
||||
@@ -2597,17 +2490,8 @@ void LLFloaterSnapshot::Impl::updateResolution(LLUICtrl* ctrl, void* data, bool
|
||||
|
||||
if (previewp)
|
||||
{
|
||||
if (new_aspect == 0)
|
||||
{
|
||||
// In case the aspect is 'Default', need to update aspect (which will call updateControls, if necessary).
|
||||
setAspect(view, previewp->aspectComboName(), update_controls);
|
||||
}
|
||||
else
|
||||
{
|
||||
LLSpinCtrl* aspect_spinner = view->getChild<LLSpinCtrl>("aspect_ratio");
|
||||
aspect_spinner->set(new_aspect);
|
||||
previewp->setAspect(new_aspect);
|
||||
}
|
||||
// In case the aspect is 'Default', need to update aspect (which will call updateControls, if necessary).
|
||||
setAspect(view, previewp->aspectComboName(), update_controls);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2640,6 +2524,8 @@ void LLFloaterSnapshot::Impl::updateAspect(LLUICtrl* ctrl, void* data, bool upda
|
||||
S32 width, height;
|
||||
previewp->getSize(width, height);
|
||||
aspect = (F32)width / height;
|
||||
// Turn off "Keep aspect" when aspect is set to Default.
|
||||
keepAspect(view, false);
|
||||
}
|
||||
else if (aspect == -1) // Custom
|
||||
{
|
||||
@@ -2651,6 +2537,7 @@ void LLFloaterSnapshot::Impl::updateAspect(LLUICtrl* ctrl, void* data, bool upda
|
||||
}
|
||||
|
||||
LLSpinCtrl* aspect_spinner = view->getChild<LLSpinCtrl>("aspect_ratio");
|
||||
LLCheckBoxCtrl* keep_aspect = view->getChild<LLCheckBoxCtrl>("keep_aspect");
|
||||
|
||||
// Set whether or not the spinners can be changed.
|
||||
if (gSavedSettings.getBOOL("RenderUIInSnapshot") ||
|
||||
@@ -2660,11 +2547,13 @@ void LLFloaterSnapshot::Impl::updateAspect(LLUICtrl* ctrl, void* data, bool upda
|
||||
// Disable without making label gray.
|
||||
aspect_spinner->setAllowEdit(FALSE);
|
||||
aspect_spinner->setIncrement(0);
|
||||
keep_aspect->setEnabled(FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
aspect_spinner->setAllowEdit(TRUE);
|
||||
aspect_spinner->setIncrement(llmax(0.01f, lltrunc(aspect) / 100.0f));
|
||||
keep_aspect->setEnabled(TRUE);
|
||||
}
|
||||
|
||||
// Sync the spinner and cache value.
|
||||
@@ -2685,6 +2574,77 @@ void LLFloaterSnapshot::Impl::updateAspect(LLUICtrl* ctrl, void* data, bool upda
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void LLFloaterSnapshot::Impl::enforceAspect(LLFloaterSnapshot* floater, F32 new_aspect)
|
||||
{
|
||||
LLSnapshotLivePreview* previewp = getPreviewView();
|
||||
if (previewp)
|
||||
{
|
||||
LLComboBox* combo = floater->getChild<LLComboBox>(previewp->aspectComboName());
|
||||
S32 const aspect_custom = combo->getItemCount() - 1;
|
||||
for (S32 index = 0; index <= aspect_custom; ++index)
|
||||
{
|
||||
combo->setCurrentByIndex(index);
|
||||
if (index == aspect_custom)
|
||||
{
|
||||
gSavedSettings.setF32(lastSnapshotAspectName(), new_aspect);
|
||||
break;
|
||||
}
|
||||
std::string sdstring = combo->getSelectedValue();
|
||||
std::stringstream sstream;
|
||||
sstream << sdstring;
|
||||
F32 aspect;
|
||||
sstream >> aspect;
|
||||
if (aspect == -2) // Default
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (aspect == 0) // Current window
|
||||
{
|
||||
aspect = (F32)gViewerWindow->getWindowDisplayWidth() / gViewerWindow->getWindowDisplayHeight();
|
||||
}
|
||||
if (llabs(aspect - new_aspect) < 0.0001)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
storeAspectSetting(combo, previewp->aspectComboName());
|
||||
updateAspect(combo, floater, true);
|
||||
}
|
||||
}
|
||||
|
||||
void LLFloaterSnapshot::Impl::enforceResolution(LLFloaterSnapshot* floater, F32 new_aspect)
|
||||
{
|
||||
LLSnapshotLivePreview* previewp = getPreviewView();
|
||||
if (previewp)
|
||||
{
|
||||
// Get current size.
|
||||
S32 w, h;
|
||||
previewp->getSize(w, h);
|
||||
// Do all calculation in floating point.
|
||||
F32 cw = w;
|
||||
F32 ch = h;
|
||||
// Get the current raw size.
|
||||
previewp->getRawSize(w, h);
|
||||
F32 rw = w;
|
||||
F32 rh = h;
|
||||
// Fit rectangle with aspect new_aspect, around current rectangle, but cropped to raw size.
|
||||
F32 nw = llmin(llmax(cw, ch * new_aspect), rw);
|
||||
F32 nh = llmin(llmax(ch, cw / new_aspect), rh);
|
||||
// Fit rectangle with aspect new_aspect inside that rectangle (in case it was cropped).
|
||||
nw = llmin(nw, nh * new_aspect);
|
||||
nh = llmin(nh, nw / new_aspect);
|
||||
// Round off to nearest integer.
|
||||
S32 new_width = llround(nw);
|
||||
S32 new_height = llround(nh);
|
||||
|
||||
gSavedSettings.setS32(lastSnapshotWidthName(), new_width);
|
||||
gSavedSettings.setS32(lastSnapshotHeightName(), new_height);
|
||||
comboSetCustom(floater, previewp->resolutionComboName());
|
||||
updateResolution(floater->getChild<LLComboBox>(previewp->resolutionComboName()), floater, false);
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void LLFloaterSnapshot::Impl::onCommitLayerTypes(LLUICtrl* ctrl, void*data)
|
||||
{
|
||||
@@ -2703,13 +2663,20 @@ void LLFloaterSnapshot::Impl::onCommitSnapshotType(LLUICtrl* ctrl, void* data)
|
||||
LLFloaterSnapshot *view = (LLFloaterSnapshot *)data;
|
||||
if (view)
|
||||
{
|
||||
gSavedSettings.setS32("LastSnapshotType", getTypeIndex(view));
|
||||
LLSnapshotLivePreview::ESnapshotType snapshot_type = getTypeIndex(view);
|
||||
gSavedSettings.setS32("LastSnapshotType", snapshot_type);
|
||||
LLSnapshotLivePreview* previewp = getPreviewView();
|
||||
if (previewp)
|
||||
{
|
||||
previewp->setSnapshotType(snapshot_type);
|
||||
}
|
||||
keepAspect(view, gSavedSettings.getBOOL(snapshotKeepAspectName()), true);
|
||||
updateControls(view);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//static
|
||||
//static
|
||||
void LLFloaterSnapshot::Impl::onCommitSnapshotFormat(LLUICtrl* ctrl, void* data)
|
||||
{
|
||||
LLFloaterSnapshot *view = (LLFloaterSnapshot *)data;
|
||||
@@ -2729,7 +2696,12 @@ void LLFloaterSnapshot::Impl::comboSetCustom(LLFloaterSnapshot* floater, const s
|
||||
LLComboBox* combo = floater->getChild<LLComboBox>(comboname);
|
||||
|
||||
combo->setCurrentByIndex(combo->getItemCount() - 1); // "custom" is always the last index
|
||||
storeAspectSetting(combo, comboname);
|
||||
}
|
||||
|
||||
// static
|
||||
void LLFloaterSnapshot::Impl::storeAspectSetting(LLComboBox* combo, const std::string& comboname)
|
||||
{
|
||||
if(comboname == "feed_size_combo")
|
||||
{
|
||||
gSavedSettings.setS32("SnapshotFeedLastResolution", combo->getCurrentIndex());
|
||||
@@ -2766,8 +2738,11 @@ void LLFloaterSnapshot::Impl::onCommitCustomResolution(LLUICtrl *ctrl, void* dat
|
||||
LLFloaterSnapshot *view = (LLFloaterSnapshot *)data;
|
||||
if (view)
|
||||
{
|
||||
S32 w = llround(view->childGetValue("snapshot_width").asReal(), 1.0);
|
||||
S32 h = llround(view->childGetValue("snapshot_height").asReal(), 1.0);
|
||||
LLSpinCtrl* width_spinner = view->getChild<LLSpinCtrl>("snapshot_width");
|
||||
LLSpinCtrl* height_spinner = view->getChild<LLSpinCtrl>("snapshot_height");
|
||||
|
||||
S32 w = llround((F32)width_spinner->getValue().asReal(), 1.0f);
|
||||
S32 h = llround((F32)height_spinner->getValue().asReal(), 1.0f);
|
||||
|
||||
LLSnapshotLivePreview* previewp = getPreviewView();
|
||||
if (previewp)
|
||||
@@ -2777,6 +2752,33 @@ void LLFloaterSnapshot::Impl::onCommitCustomResolution(LLUICtrl *ctrl, void* dat
|
||||
|
||||
if (w != curw || h != curh)
|
||||
{
|
||||
// Enforce multiple of 32 if the step was 32.
|
||||
Dout(dc::snapshot, "w = " << w << "; curw = " << curw);
|
||||
if (llabs(w - curw) == 32)
|
||||
{
|
||||
w = (w + 16) & -32;
|
||||
Dout(dc::snapshot, "w = (w + 16) & -32 = " << w);
|
||||
}
|
||||
if (llabs(h - curh) == 32)
|
||||
{
|
||||
h = (h + 16) & -32;
|
||||
}
|
||||
if (gSavedSettings.getBOOL(snapshotKeepAspectName()))
|
||||
{
|
||||
F32 aspect = previewp->getAspect();
|
||||
if (h == curh)
|
||||
{
|
||||
// Width was changed. Change height to keep aspect constant.
|
||||
h = llround(w / aspect);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Height was changed. Change width to keep aspect constant.
|
||||
w = llround(h * aspect);
|
||||
}
|
||||
}
|
||||
width_spinner->forceSetValue(LLSD::Real(w));
|
||||
height_spinner->forceSetValue(LLSD::Real(h));
|
||||
previewp->setMaxImageSize((S32)((LLSpinCtrl *)ctrl)->getMaxValue()) ;
|
||||
previewp->setSize(w,h);
|
||||
checkAutoSnapshot(previewp, FALSE);
|
||||
@@ -2794,6 +2796,30 @@ void LLFloaterSnapshot::Impl::onCommitCustomResolution(LLUICtrl *ctrl, void* dat
|
||||
}
|
||||
}
|
||||
|
||||
char const* LLSnapshotLivePreview::resolutionComboName() const
|
||||
{
|
||||
char const* result;
|
||||
switch(mSnapshotType)
|
||||
{
|
||||
case SNAPSHOT_FEED:
|
||||
result = "feed_size_combo";
|
||||
break;
|
||||
case SNAPSHOT_POSTCARD:
|
||||
result = "postcard_size_combo";
|
||||
break;
|
||||
case SNAPSHOT_TEXTURE:
|
||||
result = "texture_size_combo";
|
||||
break;
|
||||
case SNAPSHOT_LOCAL:
|
||||
result = "local_size_combo";
|
||||
break;
|
||||
default:
|
||||
result= "";
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
char const* LLSnapshotLivePreview::aspectComboName() const
|
||||
{
|
||||
char const* result;
|
||||
@@ -2841,6 +2867,11 @@ void LLFloaterSnapshot::Impl::onCommitCustomAspect(LLUICtrl *ctrl, void* data)
|
||||
|
||||
gSavedSettings.setF32(lastSnapshotAspectName(), a);
|
||||
|
||||
if (gSavedSettings.getBOOL(snapshotKeepAspectName()))
|
||||
{
|
||||
enforceResolution(view, a);
|
||||
}
|
||||
|
||||
updateControls(view, true);
|
||||
}
|
||||
}
|
||||
@@ -2902,6 +2933,7 @@ BOOL LLFloaterSnapshot::postBuild()
|
||||
childSetCommitCallback("snapshot_height", Impl::onCommitCustomResolution, this);
|
||||
|
||||
childSetCommitCallback("aspect_ratio", Impl::onCommitCustomAspect, this);
|
||||
childSetCommitCallback("keep_aspect", Impl::onClickKeepAspect, this);
|
||||
|
||||
childSetCommitCallback("ui_check", Impl::onClickUICheck, this);
|
||||
childSetValue("ui_check", gSavedSettings.getBOOL("RenderUIInSnapshot"));
|
||||
@@ -2952,8 +2984,9 @@ BOOL LLFloaterSnapshot::postBuild()
|
||||
|
||||
Impl::sPreviewHandle = previewp->getHandle();
|
||||
|
||||
impl.updateControls(this);
|
||||
impl.keepAspect(sInstance, gSavedSettings.getBOOL(snapshotKeepAspectName()), true);
|
||||
impl.freezeTime(gSavedSettings.getBOOL("SnapshotOpenFreezeTime"));
|
||||
impl.updateControls(this);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
#include "pipeline.h"
|
||||
#include "llviewerobjectlist.h"
|
||||
#include "llviewertexturelist.h"
|
||||
#include "lltexturefetch.h"
|
||||
#include "sgmemstat.h"
|
||||
|
||||
const S32 LL_SCROLL_BORDER = 1;
|
||||
@@ -151,10 +152,36 @@ void LLFloaterStats::buildStats()
|
||||
stat_barp->mLabelSpacing = 500.f;
|
||||
stat_barp->mPerSec = TRUE;
|
||||
|
||||
stat_barp = render_statviewp->addStat("Object Cache Hit Rate", &(LLViewerStats::getInstance()->mNumNewObjectsStat), std::string(), false, true);
|
||||
stat_barp->setLabel("Object Cache Hit Rate");
|
||||
stat_barp->setUnitLabel("%");
|
||||
stat_barp->mMinBar = 0.f;
|
||||
stat_barp->mMaxBar = 100.f;
|
||||
stat_barp->mTickSpacing = 20.f;
|
||||
stat_barp->mLabelSpacing = 20.f;
|
||||
stat_barp->mPerSec = FALSE;
|
||||
|
||||
// Texture statistics
|
||||
LLStatView *texture_statviewp = render_statviewp->addStatView("texture stat view", "Texture", "OpenDebugStatTexture", rect);
|
||||
|
||||
stat_barp = texture_statviewp->addStat("Cache Hit Rate", &(LLTextureFetch::sCacheHitRate), std::string(), false, true);
|
||||
stat_barp->setLabel("Cache Hit Rate");
|
||||
stat_barp->setUnitLabel("%");
|
||||
stat_barp->mMinBar = 0.f;
|
||||
stat_barp->mMaxBar = 100.f;
|
||||
stat_barp->mTickSpacing = 20.f;
|
||||
stat_barp->mLabelSpacing = 20.f;
|
||||
stat_barp->mPerSec = FALSE;
|
||||
|
||||
stat_barp = texture_statviewp->addStat("Cache Read Latency", &(LLTextureFetch::sCacheReadLatency), std::string(), false, true);
|
||||
stat_barp->setUnitLabel("msec");
|
||||
stat_barp->mMinBar = 0.f;
|
||||
stat_barp->mMaxBar = 1000.f;
|
||||
stat_barp->mTickSpacing = 100.f;
|
||||
stat_barp->mLabelSpacing = 200.f;
|
||||
stat_barp->mPerSec = FALSE;
|
||||
stat_barp->mDisplayMean = FALSE;
|
||||
|
||||
stat_barp = texture_statviewp->addStat("Count", &(LLViewerStats::getInstance()->mNumImagesStat), "DebugStatModeTextureCount");
|
||||
stat_barp->setUnitLabel("");
|
||||
stat_barp->mMinBar = 0.f;
|
||||
@@ -365,6 +392,15 @@ void LLFloaterStats::buildStats()
|
||||
stat_barp->mPerSec = FALSE;
|
||||
stat_barp->mDisplayMean = FALSE;
|
||||
|
||||
stat_barp = sim_statviewp->addStat("Scripts Run", &(LLViewerStats::getInstance()->mSimPctScriptsRun), std::string(), false, true);
|
||||
stat_barp->setUnitLabel("%");
|
||||
stat_barp->mPrecision = 3;
|
||||
stat_barp->mMinBar = 0.f;
|
||||
stat_barp->mMaxBar = 100.f;
|
||||
stat_barp->mTickSpacing = 10.f;
|
||||
stat_barp->mLabelSpacing = 20.f;
|
||||
stat_barp->mPerSec = FALSE;
|
||||
|
||||
stat_barp = sim_statviewp->addStat("Script Events", &(LLViewerStats::getInstance()->mSimScriptEPS), "DebugStatModeSimScriptEvents");
|
||||
stat_barp->setUnitLabel(" eps");
|
||||
stat_barp->mPrecision = 0;
|
||||
@@ -375,6 +411,35 @@ void LLFloaterStats::buildStats()
|
||||
stat_barp->mPerSec = FALSE;
|
||||
stat_barp->mDisplayMean = FALSE;
|
||||
|
||||
LLStatView *pathfinding_viewp = sim_statviewp->addStatView("pathfinding view", "Pathfinding Details", std::string(), rect);
|
||||
stat_barp = pathfinding_viewp->addStat("AI Step Time", &(LLViewerStats::getInstance()->mSimSimAIStepMsec));
|
||||
stat_barp->setUnitLabel("ms");
|
||||
stat_barp->mPrecision = 3;
|
||||
stat_barp->mMinBar = 0.f;
|
||||
stat_barp->mMaxBar = 40.f;
|
||||
stat_barp->mTickSpacing = 10.f;
|
||||
stat_barp->mLabelSpacing = 20.f;
|
||||
stat_barp->mPerSec = FALSE;
|
||||
stat_barp->mDisplayMean = FALSE;
|
||||
|
||||
stat_barp = render_statviewp->addStat("Skipped Silhouette Steps", &(LLViewerStats::getInstance()->mSimSimSkippedSilhouetteSteps));
|
||||
stat_barp->setUnitLabel("/sec");
|
||||
stat_barp->mMinBar = 0.f;
|
||||
stat_barp->mMaxBar = 45.f;
|
||||
stat_barp->mTickSpacing = 4.f;
|
||||
stat_barp->mLabelSpacing = 8.f;
|
||||
stat_barp->mPrecision = 0;
|
||||
|
||||
stat_barp = pathfinding_viewp->addStat("Characters Updated", &(LLViewerStats::getInstance()->mSimSimPctSteppedCharacters));
|
||||
stat_barp->setUnitLabel("%");
|
||||
stat_barp->mPrecision = 1;
|
||||
stat_barp->mMinBar = 0.f;
|
||||
stat_barp->mMaxBar = 100.f;
|
||||
stat_barp->mTickSpacing = 10.f;
|
||||
stat_barp->mLabelSpacing = 20.f;
|
||||
stat_barp->mPerSec = FALSE;
|
||||
stat_barp->mDisplayMean = TRUE;
|
||||
|
||||
stat_barp = sim_statviewp->addStat("Packets In", &(LLViewerStats::getInstance()->mSimInPPS), "DebugStatModeSimInPPS");
|
||||
stat_barp->setUnitLabel(" pps");
|
||||
stat_barp->mPrecision = 0;
|
||||
|
||||
@@ -103,27 +103,6 @@ LLFloaterURLEntry::LLFloaterURLEntry(LLHandle<LLPanel> parent)
|
||||
mPanelLandMediaHandle(parent)
|
||||
{
|
||||
LLUICtrlFactory::getInstance()->buildFloater(this, "floater_url_entry.xml");
|
||||
|
||||
mMediaURLEdit = getChild<LLComboBox>("media_entry");
|
||||
|
||||
// Cancel button
|
||||
childSetAction("cancel_btn", onBtnCancel, this);
|
||||
|
||||
// Cancel button
|
||||
childSetAction("clear_btn", onBtnClear, this);
|
||||
|
||||
// clear media list button
|
||||
LLSD parcel_history = LLURLHistory::getURLHistory("parcel");
|
||||
bool enable_clear_button = parcel_history.size() > 0 ? true : false;
|
||||
childSetEnabled( "clear_btn", enable_clear_button );
|
||||
|
||||
// OK button
|
||||
childSetAction("ok_btn", onBtnOK, this);
|
||||
|
||||
setDefaultBtn("ok_btn");
|
||||
buildURLHistory();
|
||||
|
||||
sInstance = this;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -134,6 +113,28 @@ LLFloaterURLEntry::~LLFloaterURLEntry()
|
||||
sInstance = NULL;
|
||||
}
|
||||
|
||||
BOOL LLFloaterURLEntry::postBuild()
|
||||
{
|
||||
mMediaURLEdit = getChild<LLComboBox>("media_entry");
|
||||
|
||||
// Cancel button
|
||||
childSetAction("cancel_btn", onBtnCancel, this);
|
||||
|
||||
// Cancel button
|
||||
childSetAction("clear_btn", onBtnClear, this);
|
||||
// clear media list button
|
||||
LLSD parcel_history = LLURLHistory::getURLHistory("parcel");
|
||||
bool enable_clear_button = parcel_history.size() > 0 ? true : false;
|
||||
getChildView("clear_btn")->setEnabled(enable_clear_button );
|
||||
|
||||
// OK button
|
||||
childSetAction("ok_btn", onBtnOK, this);
|
||||
|
||||
setDefaultBtn("ok_btn");
|
||||
buildURLHistory();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
void LLFloaterURLEntry::buildURLHistory()
|
||||
{
|
||||
LLCtrlListInterface* url_list = childGetListInterface("media_entry");
|
||||
@@ -157,7 +158,7 @@ void LLFloaterURLEntry::buildURLHistory()
|
||||
|
||||
void LLFloaterURLEntry::headerFetchComplete(U32 status, const std::string& mime_type)
|
||||
{
|
||||
LLPanelLandMedia* panel_media = (LLPanelLandMedia*)mPanelLandMediaHandle.get();
|
||||
LLPanelLandMedia* panel_media = dynamic_cast<LLPanelLandMedia*>(mPanelLandMediaHandle.get());
|
||||
if (panel_media)
|
||||
{
|
||||
// status is ignored for now -- error = "none/none"
|
||||
@@ -166,21 +167,18 @@ void LLFloaterURLEntry::headerFetchComplete(U32 status, const std::string& mime_
|
||||
}
|
||||
// Decrement the cursor
|
||||
getWindow()->decBusyCount();
|
||||
childSetVisible("loading_label", false);
|
||||
getChildView("loading_label")->setVisible( false);
|
||||
close();
|
||||
}
|
||||
|
||||
// static
|
||||
LLHandle<LLFloater> LLFloaterURLEntry::show(LLHandle<LLPanel> parent)
|
||||
{
|
||||
if (sInstance)
|
||||
{
|
||||
sInstance->open();
|
||||
}
|
||||
else
|
||||
if (!sInstance)
|
||||
{
|
||||
sInstance = new LLFloaterURLEntry(parent);
|
||||
}
|
||||
sInstance->open();
|
||||
sInstance->updateFromLandMediaPanel();
|
||||
return sInstance->getHandle();
|
||||
}
|
||||
@@ -239,7 +237,8 @@ void LLFloaterURLEntry::onBtnOK( void* userdata )
|
||||
}
|
||||
|
||||
// Discover the MIME type only for "http" scheme.
|
||||
if(scheme == "http" || scheme == "https")
|
||||
if(!media_url.empty() &&
|
||||
(scheme == "http" || scheme == "https"))
|
||||
{
|
||||
LLHTTPClient::getHeaderOnly( media_url,
|
||||
new LLMediaTypeResponder(self->getHandle()));
|
||||
@@ -250,13 +249,13 @@ void LLFloaterURLEntry::onBtnOK( void* userdata )
|
||||
}
|
||||
|
||||
// Grey the buttons until we get the header response
|
||||
self->childSetEnabled("ok_btn", false);
|
||||
self->childSetEnabled("cancel_btn", false);
|
||||
self->childSetEnabled("media_entry", false);
|
||||
self->getChildView("ok_btn")->setEnabled(false);
|
||||
self->getChildView("cancel_btn")->setEnabled(false);
|
||||
self->getChildView("media_entry")->setEnabled(false);
|
||||
|
||||
// show progress bar here?
|
||||
getWindow()->incBusyCount();
|
||||
self->childSetVisible("loading_label", true);
|
||||
self->getChildView("loading_label")->setVisible( true);
|
||||
}
|
||||
|
||||
// static
|
||||
@@ -298,7 +297,7 @@ bool LLFloaterURLEntry::callback_clear_url_list(const LLSD& notification, const
|
||||
LLURLHistory::clear("parcel");
|
||||
|
||||
// cleared the list so disable Clear button
|
||||
childSetEnabled( "clear_btn", false );
|
||||
getChildView("clear_btn")->setEnabled(false );
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ public:
|
||||
// Can only be shown by LLPanelLandMedia, and pushes data back into
|
||||
// that panel via the handle.
|
||||
static LLHandle<LLFloater> show(LLHandle<LLPanel> panel_land_media_handle);
|
||||
|
||||
/*virtual*/ BOOL postBuild();
|
||||
void updateFromLandMediaPanel();
|
||||
|
||||
void headerFetchComplete(U32 status, const std::string& mime_type);
|
||||
|
||||
@@ -1513,12 +1513,6 @@ BOOL LLFolderView::handleKeyHere( KEY key, MASK mask )
|
||||
LLMenuGL::sMenuContainer->hideMenus();
|
||||
}
|
||||
|
||||
LLView *item = NULL;
|
||||
if (getChildCount() > 0)
|
||||
{
|
||||
item = *(getChildList()->begin());
|
||||
}
|
||||
|
||||
switch( key )
|
||||
{
|
||||
case KEY_F2:
|
||||
@@ -2074,6 +2068,12 @@ void LLFolderView::scrollToShowItem(LLFolderViewItem* item, const LLRect& constr
|
||||
}
|
||||
}
|
||||
|
||||
void LLFolderView::setScrollContainer(LLScrollableContainerView* parent)
|
||||
{
|
||||
mScrollContainer = parent;
|
||||
parent->setPassBackToChildren(false);
|
||||
}
|
||||
|
||||
LLRect LLFolderView::getVisibleRect()
|
||||
{
|
||||
S32 visible_height = mScrollContainer->getRect().getHeight();
|
||||
|
||||
@@ -217,7 +217,7 @@ public:
|
||||
|
||||
void scrollToShowSelection();
|
||||
void scrollToShowItem(LLFolderViewItem* item, const LLRect& constraint_rect);
|
||||
void setScrollContainer( LLScrollableContainerView* parent ) { mScrollContainer = parent; }
|
||||
void setScrollContainer(LLScrollableContainerView* parent);
|
||||
LLRect getVisibleRect();
|
||||
|
||||
BOOL search(LLFolderViewItem* first_item, const std::string &search_string, BOOL backward);
|
||||
|
||||
@@ -104,6 +104,7 @@ void LLMemoryView::refreshProfile()
|
||||
|
||||
mLines.clear();
|
||||
|
||||
#if MEM_TRACK_MEM
|
||||
if(mAlloc->isProfiling())
|
||||
{
|
||||
const LLAllocatorHeapProfile &prof = mAlloc->getProfile();
|
||||
@@ -118,6 +119,7 @@ void LLMemoryView::refreshProfile()
|
||||
mLines.push_back(utf8string_to_wstring(ss.str()));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void LLMemoryView::draw()
|
||||
|
||||
@@ -71,6 +71,7 @@
|
||||
#include "lluistring.h"
|
||||
#include "llviewerobject.h"
|
||||
#include "llviewerobjectlist.h"
|
||||
#include "llenvmanager.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
@@ -253,6 +254,9 @@ void LLMuteList::loadUserVolumes()
|
||||
{
|
||||
mUserVolumeSettings.insert(std::make_pair(LLUUID(iter->first), (F32)iter->second.asReal()));
|
||||
}
|
||||
|
||||
LLEnvManagerNew::instance().setRegionChangeCallback(boost::bind(&LLMuteList::checkNewRegion, this));
|
||||
checkNewRegion();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -280,8 +284,18 @@ LLMuteList::~LLMuteList()
|
||||
}
|
||||
}
|
||||
|
||||
bool LLMuteList::isLinden(const LLUUID& id) const
|
||||
{
|
||||
std::string name;
|
||||
gCacheName->getFullName(id, name);
|
||||
return isLinden(name);
|
||||
}
|
||||
|
||||
BOOL LLMuteList::isLinden(const std::string& name) const
|
||||
{
|
||||
if (mGodFullNames.find(name) != mGodFullNames.end()) return true;
|
||||
if (mGodLastNames.empty()) return false;
|
||||
|
||||
typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
|
||||
boost::char_separator<char> sep(" ");
|
||||
tokenizer tokens(name, sep);
|
||||
@@ -292,7 +306,7 @@ BOOL LLMuteList::isLinden(const std::string& name) const
|
||||
if (token_iter == tokens.end()) return FALSE;
|
||||
|
||||
std::string last_name = *token_iter;
|
||||
return last_name == "Linden";
|
||||
return mGodLastNames.find(last_name) != mGodLastNames.end();
|
||||
}
|
||||
|
||||
static LLVOAvatar* find_avatar(const LLUUID& id)
|
||||
@@ -542,7 +556,7 @@ void notify_automute_callback(const LLUUID& agent_id, const std::string& full_na
|
||||
|
||||
LLSD args;
|
||||
args["NAME"] = full_name;
|
||||
|
||||
|
||||
LLNotificationPtr notif_ptr = LLNotifications::instance().add(notif_name, args);
|
||||
if (notif_ptr)
|
||||
{
|
||||
@@ -878,3 +892,53 @@ void LLMuteList::notifyObservers()
|
||||
it = mObservers.upper_bound(observer);
|
||||
}
|
||||
}
|
||||
|
||||
void LLMuteList::checkNewRegion()
|
||||
{
|
||||
LLViewerRegion* regionp = gAgent.getRegion();
|
||||
if (!regionp) return;
|
||||
|
||||
if (regionp->getFeaturesReceived())
|
||||
{
|
||||
parseSimulatorFeatures();
|
||||
}
|
||||
else
|
||||
{
|
||||
regionp->setFeaturesReceivedCallback(boost::bind(&LLMuteList::parseSimulatorFeatures, this));
|
||||
}
|
||||
}
|
||||
|
||||
void LLMuteList::parseSimulatorFeatures()
|
||||
{
|
||||
LLViewerRegion* regionp = gAgent.getRegion();
|
||||
if (!regionp) return;
|
||||
|
||||
LLSD info;
|
||||
regionp->getSimulatorFeatures(info);
|
||||
|
||||
mGodLastNames.clear();
|
||||
mGodFullNames.clear();
|
||||
|
||||
if (info.has("god_names"))
|
||||
{
|
||||
if (info["god_names"].has("last_names"))
|
||||
{
|
||||
LLSD godNames = info["god_names"]["last_names"];
|
||||
|
||||
for (LLSD::array_iterator godNames_it = godNames.beginArray(); godNames_it != godNames.endArray(); godNames_it++)
|
||||
mGodLastNames.insert((*godNames_it).asString());
|
||||
}
|
||||
|
||||
if (info["god_names"].has("full_names"))
|
||||
{
|
||||
LLSD godNames = info["god_names"]["full_names"];
|
||||
|
||||
for (LLSD::array_iterator godNames_it = godNames.beginArray(); godNames_it != godNames.endArray(); godNames_it++)
|
||||
mGodFullNames.insert((*godNames_it).asString());
|
||||
}
|
||||
}
|
||||
else // Just use Linden
|
||||
{
|
||||
mGodLastNames.insert("Linden");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,6 +116,7 @@ public:
|
||||
BOOL isMuted(const LLUUID& id, U32 flags) const { return isMuted(id, LLStringUtil::null, flags); };
|
||||
|
||||
BOOL isLinden(const std::string& name) const;
|
||||
bool isLinden(const LLUUID& id) const;
|
||||
|
||||
BOOL isLoaded() const { return mIsLoaded; }
|
||||
|
||||
@@ -148,6 +149,9 @@ private:
|
||||
|
||||
static void onFileMuteList(void** user_data, S32 code, LLExtStat ext_status);
|
||||
|
||||
void checkNewRegion();
|
||||
void parseSimulatorFeatures();
|
||||
|
||||
private:
|
||||
struct compare_by_name
|
||||
{
|
||||
@@ -185,6 +189,9 @@ private:
|
||||
|
||||
typedef std::map<LLUUID, F32> user_volume_map_t;
|
||||
user_volume_map_t mUserVolumeSettings;
|
||||
|
||||
std::set<std::string> mGodLastNames;
|
||||
std::set<std::string> mGodFullNames;
|
||||
};
|
||||
|
||||
class LLMuteListObserver
|
||||
|
||||
@@ -409,7 +409,7 @@ void LLNetMap::draw()
|
||||
avColor = it->second;
|
||||
}
|
||||
//Lindens are always more Linden than your friend, make that take precedence
|
||||
else if(LLMuteList::getInstance()->isLinden(avName))
|
||||
else if(LLMuteList::getInstance()->isLinden(id))
|
||||
{
|
||||
avColor = linden_color;
|
||||
}
|
||||
|
||||
@@ -121,6 +121,8 @@ BOOL LLPanelDirClassified::postBuild()
|
||||
// Don't do this every time we open find, it's expensive; require clicking 'search'
|
||||
//requestClassified();
|
||||
|
||||
childSetVisible("filter_gaming", (gAgent.getRegion()->getGamingFlags() & REGION_GAMING_PRESENT) && !(gAgent.getRegion()->getGamingFlags() & REGION_GAMING_HIDE_FIND_CLASSIFIEDS));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -206,6 +208,7 @@ void LLPanelDirClassified::performQuery()
|
||||
BOOL filter_auto_renew = FALSE;
|
||||
U32 query_flags = pack_classified_flags_request(filter_auto_renew, inc_pg, inc_mature, inc_adult);
|
||||
//if (gAgent.isTeen()) query_flags |= DFQ_PG_SIMS_ONLY;
|
||||
if (childGetValue("filter_gaming")) query_flags |= DFQ_FILTER_GAMING;
|
||||
|
||||
U32 category = childGetValue("Category").asInteger();
|
||||
|
||||
|
||||
@@ -51,6 +51,7 @@
|
||||
#include "llpanelevent.h"
|
||||
#include "llappviewer.h"
|
||||
#include "llnotificationsutil.h"
|
||||
#include "llviewerregion.h"
|
||||
|
||||
BOOL gDisplayEventHack = FALSE;
|
||||
|
||||
@@ -94,6 +95,8 @@ BOOL LLPanelDirEvents::postBuild()
|
||||
}
|
||||
gDisplayEventHack = FALSE;
|
||||
|
||||
childSetVisible("filter_gaming", (gAgent.getRegion()->getGamingFlags() & REGION_GAMING_PRESENT) && !(gAgent.getRegion()->getGamingFlags() & REGION_GAMING_HIDE_FIND_EVENTS));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -181,6 +184,7 @@ void LLPanelDirEvents::performQueryOrDelete(U32 event_id)
|
||||
if ( childGetValue("incpg").asBoolean() ) scope |= DFQ_INC_PG;
|
||||
if ( childGetValue("incmature").asBoolean() ) scope |= DFQ_INC_MATURE;
|
||||
if ( childGetValue("incadult").asBoolean() ) scope |= DFQ_INC_ADULT;
|
||||
if (childGetValue("filter_gaming").asBoolean()) scope |= DFQ_FILTER_GAMING;
|
||||
|
||||
// Add old query flags in case we are talking to an old server
|
||||
if ( childGetValue("incpg").asBoolean() && !childGetValue("incmature").asBoolean())
|
||||
|
||||
@@ -161,6 +161,8 @@ BOOL LLPanelDirFind::postBuild()
|
||||
navigateToDefaultPage();
|
||||
}
|
||||
|
||||
childSetVisible("filter_gaming", (gAgent.getRegion()->getGamingFlags() & REGION_GAMING_PRESENT) && !(gAgent.getRegion()->getGamingFlags() & REGION_GAMING_HIDE_FIND_ALL));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -309,9 +311,9 @@ void LLPanelDirFind::navigateToDefaultPage()
|
||||
mWebBrowser->navigateTo( start_url );
|
||||
}
|
||||
}
|
||||
// static
|
||||
std::string LLPanelDirFind::buildSearchURL(const std::string& search_text, const std::string& collection,
|
||||
bool inc_pg, bool inc_mature, bool inc_adult, bool is_web)
|
||||
|
||||
const std::string LLPanelDirFind::buildSearchURL(const std::string& search_text, const std::string& collection,
|
||||
bool inc_pg, bool inc_mature, bool inc_adult, bool is_web) const
|
||||
{
|
||||
std::string url;
|
||||
if (search_text.empty())
|
||||
@@ -363,8 +365,8 @@ std::string LLPanelDirFind::buildSearchURL(const std::string& search_text, const
|
||||
llinfos << "web search url " << url << llendl;
|
||||
return url;
|
||||
}
|
||||
// static
|
||||
std::string LLPanelDirFind::getSearchURLSuffix(bool inc_pg, bool inc_mature, bool inc_adult, bool is_web)
|
||||
|
||||
const std::string LLPanelDirFind::getSearchURLSuffix(bool inc_pg, bool inc_mature, bool inc_adult, bool is_web) const
|
||||
{
|
||||
std::string url = gHippoGridManager->getConnectedGrid()->getSearchUrl(HippoGridInfo::SEARCH_ALL_TEMPLATE, is_web);
|
||||
llinfos << "Suffix template " << url << llendl;
|
||||
@@ -426,6 +428,13 @@ std::string LLPanelDirFind::getSearchURLSuffix(bool inc_pg, bool inc_mature, boo
|
||||
std::string teen_string = gAgent.isTeen() ? "y" : "n";
|
||||
std::string teen_tag = "[TEEN]";
|
||||
url.replace( url.find( teen_tag ), teen_tag.length(), teen_string );
|
||||
|
||||
// and set the flag for gaming areas if not on SL Grid.
|
||||
if (!gHippoGridManager->getConnectedGrid()->isSecondLife())
|
||||
{
|
||||
substring = "[DICE]";
|
||||
url.replace(url.find(substring), substring.length(), childGetValue("filter_gaming").asBoolean() ? "y" : "n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -561,6 +570,8 @@ BOOL LLPanelDirFindAllOld::postBuild()
|
||||
childDisable("Search");
|
||||
setDefaultBtn( "Search" );
|
||||
|
||||
childSetVisible("filter_gaming", (gAgent.getRegion()->getGamingFlags() & REGION_GAMING_PRESENT) && !(gAgent.getRegion()->getGamingFlags() & REGION_GAMING_HIDE_FIND_ALL_CLASSIC));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -623,6 +634,11 @@ void LLPanelDirFindAllOld::onClickSearch(void *userdata)
|
||||
scope |= DFQ_INC_ADULT;
|
||||
}
|
||||
|
||||
if (self->childGetValue("filter_gaming").asBoolean())
|
||||
{
|
||||
scope |= DFQ_FILTER_GAMING;
|
||||
}
|
||||
|
||||
// send the message
|
||||
LLMessageSystem *msg = gMessageSystem;
|
||||
S32 start_row = 0;
|
||||
|
||||
@@ -61,8 +61,8 @@ public:
|
||||
virtual void navigateToDefaultPage();
|
||||
void focus();
|
||||
|
||||
static std::string buildSearchURL(const std::string& search_text, const std::string& collection, bool inc_pg, bool inc_mature, bool inc_adult, bool is_web);
|
||||
static std::string getSearchURLSuffix(bool inc_pg, bool inc_mature, bool inc_adult, bool is_web);
|
||||
const std::string buildSearchURL(const std::string& search_text, const std::string& collection, bool inc_pg, bool inc_mature, bool inc_adult, bool is_web) const;
|
||||
const std::string getSearchURLSuffix(bool inc_pg, bool inc_mature, bool inc_adult, bool is_web) const;
|
||||
|
||||
private:
|
||||
static void onClickBack( void* data );
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
#include "message.h"
|
||||
#include "llqueryflags.h"
|
||||
#include "llviewercontrol.h"
|
||||
#include "llviewerregion.h"
|
||||
#include "llviewerwindow.h"
|
||||
#include "llnotificationsutil.h"
|
||||
|
||||
@@ -60,6 +61,8 @@ BOOL LLPanelDirGroups::postBuild()
|
||||
childDisable("Search");
|
||||
setDefaultBtn( "Search" );
|
||||
|
||||
childSetVisible("filter_gaming", (gAgent.getRegion()->getGamingFlags() & REGION_GAMING_PRESENT) && !(gAgent.getRegion()->getGamingFlags() & REGION_GAMING_HIDE_FIND_GROUPS));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -130,6 +133,10 @@ void LLPanelDirGroups::performQuery()
|
||||
{
|
||||
scope |= DFQ_INC_ADULT;
|
||||
}
|
||||
if (childGetValue("filter_gaming").asBoolean())
|
||||
{
|
||||
scope |= DFQ_FILTER_GAMING;
|
||||
}
|
||||
|
||||
mCurrentSortColumn = "score";
|
||||
mCurrentSortAscending = FALSE;
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
#include "lltextbox.h"
|
||||
#include "llviewercontrol.h"
|
||||
#include "llviewermessage.h"
|
||||
#include "llviewerregion.h"
|
||||
|
||||
#include "hippogridmanager.h"
|
||||
|
||||
@@ -125,6 +126,8 @@ BOOL LLPanelDirLand::postBuild()
|
||||
}
|
||||
}
|
||||
|
||||
childSetVisible("filter_gaming", (gAgent.getRegion()->getGamingFlags() & REGION_GAMING_PRESENT) && !(gAgent.getRegion()->getGamingFlags() & REGION_GAMING_HIDE_FIND_LAND));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -213,6 +216,11 @@ void LLPanelDirLand::performQuery()
|
||||
{
|
||||
query_flags |= DFQ_INC_ADULT;
|
||||
}
|
||||
|
||||
if (childGetValue("filter_gaming").asBoolean())
|
||||
{
|
||||
query_flags |= DFQ_FILTER_GAMING;
|
||||
}
|
||||
|
||||
// Add old flags in case we are talking to an old dataserver
|
||||
if (inc_pg && !inc_mature)
|
||||
|
||||
@@ -57,6 +57,7 @@
|
||||
#include "lluiconstants.h"
|
||||
#include "llviewercontrol.h"
|
||||
#include "llviewermessage.h"
|
||||
#include "llviewerregion.h"
|
||||
#include "llworldmap.h"
|
||||
|
||||
LLPanelDirPlaces::LLPanelDirPlaces(const std::string& name, LLFloaterDirectory* floater)
|
||||
@@ -98,6 +99,8 @@ BOOL LLPanelDirPlaces::postBuild()
|
||||
childSetEnabled("Category", true);
|
||||
}
|
||||
|
||||
childSetVisible("filter_gaming", (gAgent.getRegion()->getGamingFlags() & REGION_GAMING_PRESENT) && !(gAgent.getRegion()->getGamingFlags() & REGION_GAMING_HIDE_FIND_SIMS));
|
||||
|
||||
// Don't prepopulate the places list, as it hurts the database as of 2006-12-04. JC
|
||||
// initialQuery();
|
||||
|
||||
@@ -198,6 +201,11 @@ void LLPanelDirPlaces::performQuery()
|
||||
{
|
||||
flags |= DFQ_INC_ADULT;
|
||||
}
|
||||
|
||||
if (childGetValue("filter_gaming").asBoolean())
|
||||
{
|
||||
flags |= DFQ_FILTER_GAMING;
|
||||
}
|
||||
|
||||
// Pack old query flag in case we are talking to an old server
|
||||
if ( ((flags & DFQ_INC_PG) == DFQ_INC_PG) && !((flags & DFQ_INC_MATURE) == DFQ_INC_MATURE) )
|
||||
|
||||
@@ -424,8 +424,8 @@ void LLPanelMediaHUD::setAlpha(F32 alpha)
|
||||
LLViewQuery query;
|
||||
|
||||
LLView* query_view = mMediaFocus ? getChildView("media_focused_controls") : getChildView("media_hover_controls");
|
||||
child_list_t children = query(query_view);
|
||||
for (child_list_iter_t child_iter = children.begin();
|
||||
viewList_t children = query(query_view);
|
||||
for (viewList_t::iterator child_iter = children.begin();
|
||||
child_iter != children.end(); ++child_iter)
|
||||
{
|
||||
LLUICtrl* ctrl = dynamic_cast<LLUICtrl*>(*child_iter);
|
||||
|
||||
@@ -39,7 +39,6 @@
|
||||
#include "message.h"
|
||||
#include "llui.h"
|
||||
#include "llsecondlifeurls.h"
|
||||
#include "llremoteparcelrequest.h"
|
||||
#include "llfloater.h"
|
||||
|
||||
#include "llagent.h"
|
||||
@@ -62,9 +61,6 @@
|
||||
|
||||
#include "hippogridmanager.h"
|
||||
|
||||
//static
|
||||
std::list<LLPanelPlace*> LLPanelPlace::sAllPanels;
|
||||
|
||||
LLPanelPlace::LLPanelPlace()
|
||||
: LLPanel(std::string("Places Panel")),
|
||||
mParcelID(),
|
||||
@@ -74,14 +70,14 @@ LLPanelPlace::LLPanelPlace()
|
||||
mPosRegion(),
|
||||
mAuctionID(0),
|
||||
mLandmarkAssetID()
|
||||
{
|
||||
sAllPanels.push_back(this);
|
||||
}
|
||||
{}
|
||||
|
||||
|
||||
LLPanelPlace::~LLPanelPlace()
|
||||
{
|
||||
sAllPanels.remove(this);
|
||||
if (mParcelID.isNull()) return;
|
||||
|
||||
LLRemoteParcelInfoProcessor::getInstance()->removeObserver(mParcelID, this);
|
||||
}
|
||||
|
||||
|
||||
@@ -179,8 +175,14 @@ void LLPanelPlace::resetName(const std::string& name)
|
||||
|
||||
void LLPanelPlace::setParcelID(const LLUUID& parcel_id)
|
||||
{
|
||||
if (parcel_id.isNull()) return;
|
||||
|
||||
if(mParcelID.notNull())
|
||||
LLRemoteParcelInfoProcessor::getInstance()->removeObserver(mParcelID, this);
|
||||
|
||||
mParcelID = parcel_id;
|
||||
sendParcelInfoRequest();
|
||||
LLRemoteParcelInfoProcessor::getInstance()->addObserver(mParcelID, this);
|
||||
LLRemoteParcelInfoProcessor::getInstance()->sendParcelInfoRequest(mParcelID);
|
||||
}
|
||||
|
||||
void LLPanelPlace::setSnapshot(const LLUUID& snapshot_id)
|
||||
@@ -199,23 +201,6 @@ void LLPanelPlace::setLandTypeString(const std::string& land_type)
|
||||
mLandTypeEditor->setText(land_type);
|
||||
}
|
||||
|
||||
void LLPanelPlace::sendParcelInfoRequest()
|
||||
{
|
||||
LLMessageSystem *msg = gMessageSystem;
|
||||
|
||||
if (mParcelID != mRequestedID)
|
||||
{
|
||||
msg->newMessage("ParcelInfoRequest");
|
||||
msg->nextBlockFast(_PREHASH_AgentData);
|
||||
msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
|
||||
msg->addUUID("SessionID", gAgent.getSessionID());
|
||||
msg->nextBlock("Data");
|
||||
msg->addUUID("ParcelID", mParcelID);
|
||||
gAgent.sendReliableMessage();
|
||||
mRequestedID = mParcelID;
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelPlace::setErrorStatus(U32 status, const std::string& reason)
|
||||
{
|
||||
// We only really handle 404 and 499 errors
|
||||
@@ -231,141 +216,94 @@ void LLPanelPlace::setErrorStatus(U32 status, const std::string& reason)
|
||||
mDescEditor->setText(error_text);
|
||||
}
|
||||
|
||||
//static
|
||||
void LLPanelPlace::processParcelInfoReply(LLMessageSystem *msg, void **)
|
||||
void LLPanelPlace::processParcelInfo(const LLParcelData& parcel_data)
|
||||
{
|
||||
LLUUID agent_id;
|
||||
LLUUID parcel_id;
|
||||
LLUUID owner_id;
|
||||
std::string name;
|
||||
std::string desc;
|
||||
S32 actual_area;
|
||||
S32 billable_area;
|
||||
U8 flags;
|
||||
F32 global_x;
|
||||
F32 global_y;
|
||||
F32 global_z;
|
||||
std::string sim_name;
|
||||
LLUUID snapshot_id;
|
||||
F32 dwell;
|
||||
S32 sale_price;
|
||||
S32 auction_id;
|
||||
mAuctionID = parcel_data.auction_id;
|
||||
|
||||
msg->getUUID("AgentData", "AgentID", agent_id );
|
||||
msg->getUUID("Data", "ParcelID", parcel_id);
|
||||
|
||||
// look up all panels which have this avatar
|
||||
for (panel_list_t::iterator iter = sAllPanels.begin(); iter != sAllPanels.end(); ++iter)
|
||||
if (parcel_data.snapshot_id.notNull())
|
||||
{
|
||||
LLPanelPlace* self = *iter;
|
||||
if (self->mParcelID != parcel_id)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
msg->getUUID ("Data", "OwnerID", owner_id);
|
||||
msg->getString ("Data", "Name", name);
|
||||
msg->getString ("Data", "Desc", desc);
|
||||
msg->getS32 ("Data", "ActualArea", actual_area);
|
||||
msg->getS32 ("Data", "BillableArea", billable_area);
|
||||
msg->getU8 ("Data", "Flags", flags);
|
||||
msg->getF32 ("Data", "GlobalX", global_x);
|
||||
msg->getF32 ("Data", "GlobalY", global_y);
|
||||
msg->getF32 ("Data", "GlobalZ", global_z);
|
||||
msg->getString ("Data", "SimName", sim_name);
|
||||
msg->getUUID ("Data", "SnapshotID", snapshot_id);
|
||||
msg->getF32 ("Data", "Dwell", dwell);
|
||||
msg->getS32 ("Data", "SalePrice", sale_price);
|
||||
msg->getS32 ("Data", "AuctionID", auction_id);
|
||||
|
||||
|
||||
self->mAuctionID = auction_id;
|
||||
|
||||
if(snapshot_id.notNull())
|
||||
{
|
||||
self->mSnapshotCtrl->setImageAssetID(snapshot_id);
|
||||
}
|
||||
|
||||
// Only assign the name and description if they are not empty and there is not a
|
||||
// value present (passed in from a landmark, e.g.)
|
||||
|
||||
if( !name.empty()
|
||||
&& self->mNameEditor && self->mNameEditor->getText().empty())
|
||||
{
|
||||
self->mNameEditor->setText(name);
|
||||
}
|
||||
|
||||
if( !desc.empty()
|
||||
&& self->mDescEditor && self->mDescEditor->getText().empty())
|
||||
{
|
||||
self->mDescEditor->setText(desc);
|
||||
}
|
||||
|
||||
std::string info_text;
|
||||
LLUIString traffic = self->getString("traffic_text");
|
||||
traffic.setArg("[TRAFFIC]", llformat("%d ", (int)dwell));
|
||||
info_text = traffic;
|
||||
LLUIString area = self->getString("area_text");
|
||||
area.setArg("[AREA]", llformat("%d", actual_area));
|
||||
info_text += area;
|
||||
if (flags & DFQ_FOR_SALE)
|
||||
{
|
||||
LLUIString forsale = self->getString("forsale_text");
|
||||
forsale.setArg("[CURRENCY]", gHippoGridManager->getConnectedGrid()->getCurrencySymbol());
|
||||
forsale.setArg("[PRICE]", llformat("%d", sale_price));
|
||||
info_text += forsale;
|
||||
}
|
||||
if (auction_id != 0)
|
||||
{
|
||||
LLUIString auction = self->getString("auction_text");
|
||||
auction.setArg("[ID]", llformat("%010d ", auction_id));
|
||||
info_text += auction;
|
||||
}
|
||||
if (self->mInfoEditor)
|
||||
{
|
||||
self->mInfoEditor->setText(info_text);
|
||||
}
|
||||
|
||||
// HACK: Flag 0x2 == adult region,
|
||||
// Flag 0x1 == mature region, otherwise assume PG
|
||||
std::string rating = LLViewerRegion::accessToString(SIM_ACCESS_PG);
|
||||
if (flags & 0x2)
|
||||
{
|
||||
rating = LLViewerRegion::accessToString(SIM_ACCESS_ADULT);
|
||||
}
|
||||
else if (flags & 0x1)
|
||||
{
|
||||
rating = LLViewerRegion::accessToString(SIM_ACCESS_MATURE);
|
||||
}
|
||||
|
||||
// Just use given region position for display
|
||||
S32 region_x = llround(self->mPosRegion.mV[0]);
|
||||
S32 region_y = llround(self->mPosRegion.mV[1]);
|
||||
S32 region_z = llround(self->mPosRegion.mV[2]);
|
||||
|
||||
// If the region position is zero, grab position from the global
|
||||
if(self->mPosRegion.isExactlyZero())
|
||||
{
|
||||
region_x = llround(global_x) % REGION_WIDTH_UNITS;
|
||||
region_y = llround(global_y) % REGION_WIDTH_UNITS;
|
||||
region_z = llround(global_z);
|
||||
}
|
||||
|
||||
if(self->mPosGlobal.isExactlyZero())
|
||||
{
|
||||
self->mPosGlobal.setVec(global_x, global_y, global_z);
|
||||
}
|
||||
|
||||
std::string location = llformat("%s %d, %d, %d (%s)",
|
||||
sim_name.c_str(), region_x, region_y, region_z, rating.c_str());
|
||||
if (self->mLocationDisplay)
|
||||
{
|
||||
self->mLocationDisplay->setText(location);
|
||||
}
|
||||
|
||||
BOOL show_auction = (auction_id > 0);
|
||||
self->mAuctionBtn->setVisible(show_auction);
|
||||
setSnapshot(parcel_data.snapshot_id);
|
||||
}
|
||||
|
||||
// Only assign the name and description if they are not empty and there is not a
|
||||
// value present (passed in from a landmark, e.g.)
|
||||
|
||||
if( !parcel_data.name.empty()
|
||||
&& mNameEditor && mNameEditor->getText().empty())
|
||||
{
|
||||
mNameEditor->setText(parcel_data.name);
|
||||
}
|
||||
|
||||
if( !parcel_data.desc.empty()
|
||||
&& mDescEditor && mDescEditor->getText().empty())
|
||||
{
|
||||
mDescEditor->setText(parcel_data.desc);
|
||||
}
|
||||
|
||||
std::string info_text;
|
||||
LLUIString traffic = getString("traffic_text");
|
||||
traffic.setArg("[TRAFFIC]", llformat("%d ", (int)parcel_data.dwell));
|
||||
info_text = traffic;
|
||||
LLUIString area = getString("area_text");
|
||||
area.setArg("[AREA]", llformat("%d", parcel_data.actual_area));
|
||||
info_text += area;
|
||||
if (parcel_data.flags & DFQ_FOR_SALE)
|
||||
{
|
||||
LLUIString forsale = getString("forsale_text");
|
||||
forsale.setArg("[CURRENCY]", gHippoGridManager->getConnectedGrid()->getCurrencySymbol());
|
||||
forsale.setArg("[PRICE]", llformat("%d", parcel_data.sale_price));
|
||||
info_text += forsale;
|
||||
}
|
||||
if (parcel_data.auction_id != 0)
|
||||
{
|
||||
LLUIString auction = getString("auction_text");
|
||||
auction.setArg("[ID]", llformat("%010d ", parcel_data.auction_id));
|
||||
info_text += auction;
|
||||
}
|
||||
if (mInfoEditor)
|
||||
{
|
||||
mInfoEditor->setText(info_text);
|
||||
}
|
||||
|
||||
// HACK: Flag 0x2 == adult region,
|
||||
// Flag 0x1 == mature region, otherwise assume PG
|
||||
std::string rating = LLViewerRegion::accessToString(SIM_ACCESS_PG);
|
||||
if (parcel_data.flags & 0x2)
|
||||
{
|
||||
rating = LLViewerRegion::accessToString(SIM_ACCESS_ADULT);
|
||||
}
|
||||
else if (parcel_data.flags & 0x1)
|
||||
{
|
||||
rating = LLViewerRegion::accessToString(SIM_ACCESS_MATURE);
|
||||
}
|
||||
|
||||
// Just use given region position for display
|
||||
S32 region_x = llround(mPosRegion.mV[0]);
|
||||
S32 region_y = llround(mPosRegion.mV[1]);
|
||||
S32 region_z = llround(mPosRegion.mV[2]);
|
||||
|
||||
// If the region position is zero, grab position from the global
|
||||
if(mPosRegion.isExactlyZero())
|
||||
{
|
||||
region_x = llround(parcel_data.global_x) % REGION_WIDTH_UNITS;
|
||||
region_y = llround(parcel_data.global_y) % REGION_WIDTH_UNITS;
|
||||
region_z = llround(parcel_data.global_z);
|
||||
}
|
||||
|
||||
if(mPosGlobal.isExactlyZero())
|
||||
{
|
||||
mPosGlobal.setVec(parcel_data.global_x, parcel_data.global_y, parcel_data.global_z);
|
||||
}
|
||||
|
||||
std::string location = llformat("%s %d, %d, %d (%s)",
|
||||
parcel_data.sim_name.c_str(), region_x, region_y, region_z, rating.c_str());
|
||||
if (mLocationDisplay)
|
||||
{
|
||||
mLocationDisplay->setText(location);
|
||||
}
|
||||
|
||||
BOOL show_auction = (parcel_data.auction_id > 0);
|
||||
mAuctionBtn->setVisible(show_auction);
|
||||
}
|
||||
|
||||
|
||||
@@ -391,7 +329,7 @@ void LLPanelPlace::displayParcelInfo(const LLVector3& pos_region,
|
||||
U64 region_handle = to_region_handle(pos_global);
|
||||
body["region_handle"] = ll_sd_from_U64(region_handle);
|
||||
}
|
||||
LLHTTPClient::post(url, body, new LLRemoteParcelRequestResponder(this->getHandle()));
|
||||
LLHTTPClient::post(url, body, new LLRemoteParcelRequestResponder(this->getObserverHandle()));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#define LL_LLPANELPLACE_H
|
||||
|
||||
#include "llpanel.h"
|
||||
#include "llremoteparcelrequest.h"
|
||||
|
||||
#include "v3dmath.h"
|
||||
#include "lluuid.h"
|
||||
@@ -46,7 +47,7 @@ class LLTextureCtrl;
|
||||
class LLMessageSystem;
|
||||
class LLInventoryItem;
|
||||
|
||||
class LLPanelPlace : public LLPanel
|
||||
class LLPanelPlace : public LLPanel, public LLRemoteParcelInfoObserver
|
||||
{
|
||||
public:
|
||||
LLPanelPlace();
|
||||
@@ -58,7 +59,7 @@ public:
|
||||
// Ignore all old location information, useful if you are
|
||||
// recycling an existing dialog and need to clear it.
|
||||
|
||||
void setParcelID(const LLUUID& parcel_id);
|
||||
/*virtual*/ void setParcelID(const LLUUID& parcel_id);
|
||||
// Sends a request for data about the given parcel, which will
|
||||
// only update the location if there is none already available.
|
||||
|
||||
@@ -67,15 +68,14 @@ public:
|
||||
void setSnapshot(const LLUUID& snapshot_id);
|
||||
void setLocationString(const std::string& location);
|
||||
void setLandTypeString(const std::string& land_type);
|
||||
void setErrorStatus(U32 status, const std::string& reason);
|
||||
/*virtual*/ void setErrorStatus(U32 status, const std::string& reason);
|
||||
void resetName(const std::string& name);
|
||||
|
||||
void sendParcelInfoRequest();
|
||||
void displayParcelInfo(const LLVector3& pos_region,
|
||||
const LLUUID& landmark_asset_id,
|
||||
const LLUUID& region_id,
|
||||
const LLVector3d& pos_global);
|
||||
static void processParcelInfoReply(LLMessageSystem* msg, void**);
|
||||
/*virtual*/ void processParcelInfo(const LLParcelData& parcel_data);
|
||||
|
||||
LLTextureCtrl *getSnapshotCtrl() const { return mSnapshotCtrl; }
|
||||
|
||||
@@ -113,9 +113,6 @@ protected:
|
||||
LLButton* mMapBtn;
|
||||
//LLButton* mLandmarkBtn;
|
||||
LLButton* mAuctionBtn;
|
||||
|
||||
typedef std::list<LLPanelPlace*> panel_list_t;
|
||||
static panel_list_t sAllPanels;
|
||||
};
|
||||
|
||||
#endif // LL_LLPANELPLACE_H
|
||||
|
||||
@@ -34,46 +34,172 @@
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
|
||||
#include "llagent.h"
|
||||
#include "llremoteparcelrequest.h"
|
||||
#include "message.h"
|
||||
|
||||
#include "llpanelplace.h"
|
||||
#include "llpanel.h"
|
||||
#include "llhttpclient.h"
|
||||
#include "llsdserialize.h"
|
||||
//#include "llurlentry.h"
|
||||
#include "llviewerregion.h"
|
||||
#include "llview.h"
|
||||
#include "message.h"
|
||||
|
||||
LLRemoteParcelRequestResponder::LLRemoteParcelRequestResponder(LLHandle<LLPanel> place_panel_handle)
|
||||
{
|
||||
mPlacePanelHandle = place_panel_handle;
|
||||
}
|
||||
/*virtual*/
|
||||
#include "llagent.h"
|
||||
#include "llremoteparcelrequest.h"
|
||||
|
||||
|
||||
LLRemoteParcelRequestResponder::LLRemoteParcelRequestResponder(LLHandle<LLRemoteParcelInfoObserver> observer_handle)
|
||||
: mObserverHandle(observer_handle)
|
||||
{}
|
||||
|
||||
//If we get back a normal response, handle it here
|
||||
//virtual
|
||||
void LLRemoteParcelRequestResponder::result(const LLSD& content)
|
||||
{
|
||||
LLUUID parcel_id = content["parcel_id"];
|
||||
|
||||
LLPanelPlace* place_panelp = (LLPanelPlace*)mPlacePanelHandle.get();
|
||||
|
||||
if(place_panelp)
|
||||
// Panel inspecting the information may be closed and destroyed
|
||||
// before this response is received.
|
||||
LLRemoteParcelInfoObserver* observer = mObserverHandle.get();
|
||||
if (observer)
|
||||
{
|
||||
place_panelp->setParcelID(parcel_id);
|
||||
observer->setParcelID(parcel_id);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*virtual*/
|
||||
//If we get back an error (not found, etc...), handle it here
|
||||
//virtual
|
||||
void LLRemoteParcelRequestResponder::error(U32 status, const std::string& reason)
|
||||
{
|
||||
llinfos << "LLRemoteParcelRequest::error("
|
||||
<< status << ": " << reason << ")" << llendl;
|
||||
LLPanelPlace* place_panelp = (LLPanelPlace*)mPlacePanelHandle.get();
|
||||
|
||||
if(place_panelp)
|
||||
// Panel inspecting the information may be closed and destroyed
|
||||
// before this response is received.
|
||||
LLRemoteParcelInfoObserver* observer = mObserverHandle.get();
|
||||
if (observer)
|
||||
{
|
||||
place_panelp->setErrorStatus(status, reason);
|
||||
observer->setErrorStatus(status, reason);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void LLRemoteParcelInfoProcessor::addObserver(const LLUUID& parcel_id, LLRemoteParcelInfoObserver* observer)
|
||||
{
|
||||
observer_multimap_t::iterator it;
|
||||
observer_multimap_t::iterator start = mObservers.lower_bound(parcel_id);
|
||||
observer_multimap_t::iterator end = mObservers.upper_bound(parcel_id);
|
||||
|
||||
// Check if the observer is already in observers list for this UUID
|
||||
for(it = start; it != end; ++it)
|
||||
{
|
||||
if (it->second.get() == observer)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
mObservers.insert(std::make_pair(parcel_id, observer->getObserverHandle()));
|
||||
}
|
||||
|
||||
void LLRemoteParcelInfoProcessor::removeObserver(const LLUUID& parcel_id, LLRemoteParcelInfoObserver* observer)
|
||||
{
|
||||
if (!observer)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
observer_multimap_t::iterator it;
|
||||
observer_multimap_t::iterator start = mObservers.lower_bound(parcel_id);
|
||||
observer_multimap_t::iterator end = mObservers.upper_bound(parcel_id);
|
||||
|
||||
for(it = start; it != end; ++it)
|
||||
{
|
||||
if (it->second.get() == observer)
|
||||
{
|
||||
mObservers.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//static
|
||||
void LLRemoteParcelInfoProcessor::processParcelInfoReply(LLMessageSystem* msg, void**)
|
||||
{
|
||||
LLParcelData parcel_data;
|
||||
|
||||
msg->getUUID ("Data", "ParcelID", parcel_data.parcel_id);
|
||||
msg->getUUID ("Data", "OwnerID", parcel_data.owner_id);
|
||||
msg->getString ("Data", "Name", parcel_data.name);
|
||||
msg->getString ("Data", "Desc", parcel_data.desc);
|
||||
msg->getS32 ("Data", "ActualArea", parcel_data.actual_area);
|
||||
msg->getS32 ("Data", "BillableArea", parcel_data.billable_area);
|
||||
msg->getU8 ("Data", "Flags", parcel_data.flags);
|
||||
msg->getF32 ("Data", "GlobalX", parcel_data.global_x);
|
||||
msg->getF32 ("Data", "GlobalY", parcel_data.global_y);
|
||||
msg->getF32 ("Data", "GlobalZ", parcel_data.global_z);
|
||||
msg->getString ("Data", "SimName", parcel_data.sim_name);
|
||||
msg->getUUID ("Data", "SnapshotID", parcel_data.snapshot_id);
|
||||
msg->getF32 ("Data", "Dwell", parcel_data.dwell);
|
||||
msg->getS32 ("Data", "SalePrice", parcel_data.sale_price);
|
||||
msg->getS32 ("Data", "AuctionID", parcel_data.auction_id);
|
||||
|
||||
LLRemoteParcelInfoProcessor::observer_multimap_t & observers = LLRemoteParcelInfoProcessor::getInstance()->mObservers;
|
||||
|
||||
typedef std::vector<observer_multimap_t::iterator> deadlist_t;
|
||||
deadlist_t dead_iters;
|
||||
|
||||
observer_multimap_t::iterator oi = observers.lower_bound(parcel_data.parcel_id);
|
||||
observer_multimap_t::iterator end = observers.upper_bound(parcel_data.parcel_id);
|
||||
|
||||
while (oi != end)
|
||||
{
|
||||
// increment the loop iterator now since it may become invalid below
|
||||
observer_multimap_t::iterator cur_oi = oi++;
|
||||
|
||||
LLRemoteParcelInfoObserver * observer = cur_oi->second.get();
|
||||
if(observer)
|
||||
{
|
||||
// may invalidate cur_oi if the observer removes itself
|
||||
observer->processParcelInfo(parcel_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
// the handle points to an expired observer, so don't keep it
|
||||
// around anymore
|
||||
dead_iters.push_back(cur_oi);
|
||||
}
|
||||
}
|
||||
|
||||
deadlist_t::iterator i;
|
||||
deadlist_t::iterator end_dead = dead_iters.end();
|
||||
for(i = dead_iters.begin(); i != end_dead; ++i)
|
||||
{
|
||||
observers.erase(*i);
|
||||
}
|
||||
|
||||
#ifdef LL_LLURLENTRY_H
|
||||
LLUrlEntryParcel::LLParcelData url_data;
|
||||
url_data.parcel_id = parcel_data.parcel_id;
|
||||
url_data.name = parcel_data.name;
|
||||
url_data.sim_name = parcel_data.sim_name;
|
||||
url_data.global_x = parcel_data.global_x;
|
||||
url_data.global_y = parcel_data.global_y;
|
||||
url_data.global_z = parcel_data.global_z;
|
||||
|
||||
// Pass the parcel data to LLUrlEntryParcel to render
|
||||
// human readable parcel name.
|
||||
LLUrlEntryParcel::processParcelInfo(url_data);
|
||||
#endif //LL_LLURLENTRY_H
|
||||
}
|
||||
|
||||
void LLRemoteParcelInfoProcessor::sendParcelInfoRequest(const LLUUID& parcel_id)
|
||||
{
|
||||
LLMessageSystem *msg = gMessageSystem;
|
||||
|
||||
msg->newMessage("ParcelInfoRequest");
|
||||
msg->nextBlockFast(_PREHASH_AgentData);
|
||||
msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
|
||||
msg->addUUID("SessionID", gAgent.getSessionID());
|
||||
msg->nextBlock("Data");
|
||||
msg->addUUID("ParcelID", parcel_id);
|
||||
gAgent.sendReliableMessage();
|
||||
}
|
||||
|
||||
@@ -38,22 +38,78 @@
|
||||
#include "llhttpclient.h"
|
||||
#include "llpanel.h"
|
||||
|
||||
class LLRemoteParcelInfoObserver;
|
||||
|
||||
class AIHTTPTimeoutPolicy;
|
||||
extern AIHTTPTimeoutPolicy remoteParcelRequestResponder_timeout;
|
||||
|
||||
class LLRemoteParcelRequestResponder : public LLHTTPClient::ResponderWithResult
|
||||
{
|
||||
public:
|
||||
LLRemoteParcelRequestResponder(LLHandle<LLPanel> place_panel_handle);
|
||||
LLRemoteParcelRequestResponder(LLHandle<LLRemoteParcelInfoObserver> observer_handle);
|
||||
|
||||
//If we get back a normal response, handle it here
|
||||
/*virtual*/ void result(const LLSD& content);
|
||||
|
||||
//If we get back an error (not found, etc...), handle it here
|
||||
/*virtual*/ void error(U32 status, const std::string& reason);
|
||||
/*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return remoteParcelRequestResponder_timeout; }
|
||||
/*virtual*/ char const* getName(void) const { return "LLRemoteParcelRequestResponder"; }
|
||||
|
||||
protected:
|
||||
LLHandle<LLPanel> mPlacePanelHandle;
|
||||
LLHandle<LLRemoteParcelInfoObserver> mObserverHandle;
|
||||
};
|
||||
|
||||
struct LLParcelData
|
||||
{
|
||||
LLUUID parcel_id;
|
||||
LLUUID owner_id;
|
||||
std::string name;
|
||||
std::string desc;
|
||||
S32 actual_area;
|
||||
S32 billable_area;
|
||||
U8 flags;
|
||||
F32 global_x;
|
||||
F32 global_y;
|
||||
F32 global_z;
|
||||
std::string sim_name;
|
||||
LLUUID snapshot_id;
|
||||
F32 dwell;
|
||||
S32 sale_price;
|
||||
S32 auction_id;
|
||||
};
|
||||
|
||||
// An interface class for panels which display parcel information
|
||||
// like name, description, area, snapshot etc.
|
||||
class LLRemoteParcelInfoObserver
|
||||
{
|
||||
public:
|
||||
LLRemoteParcelInfoObserver() { mObserverHandle.bind(this); }
|
||||
virtual ~LLRemoteParcelInfoObserver() {}
|
||||
virtual void processParcelInfo(const LLParcelData& parcel_data) = 0;
|
||||
virtual void setParcelID(const LLUUID& parcel_id) = 0;
|
||||
virtual void setErrorStatus(U32 status, const std::string& reason) = 0;
|
||||
LLHandle<LLRemoteParcelInfoObserver> getObserverHandle() const { return mObserverHandle; }
|
||||
|
||||
protected:
|
||||
LLRootHandle<LLRemoteParcelInfoObserver> mObserverHandle;
|
||||
};
|
||||
|
||||
class LLRemoteParcelInfoProcessor : public LLSingleton<LLRemoteParcelInfoProcessor>
|
||||
{
|
||||
public:
|
||||
virtual ~LLRemoteParcelInfoProcessor() {}
|
||||
|
||||
void addObserver(const LLUUID& parcel_id, LLRemoteParcelInfoObserver* observer);
|
||||
void removeObserver(const LLUUID& parcel_id, LLRemoteParcelInfoObserver* observer);
|
||||
|
||||
void sendParcelInfoRequest(const LLUUID& parcel_id);
|
||||
|
||||
static void processParcelInfoReply(LLMessageSystem* msg, void**);
|
||||
|
||||
private:
|
||||
typedef std::multimap<LLUUID, LLHandle<LLRemoteParcelInfoObserver> > observer_multimap_t;
|
||||
observer_multimap_t mObservers;
|
||||
};
|
||||
|
||||
#endif // LL_LLREMOTEPARCELREQUEST_H
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user