Merge branch 'master' of github.com:singularity-viewer/SingularityViewer

This commit is contained in:
Siana Gearz
2013-02-19 21:10:06 +01:00
319 changed files with 18396 additions and 3535 deletions

82
doc/responders.txt Normal file
View 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.

View File

@@ -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

View File

@@ -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);

View File

@@ -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

View File

@@ -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()

View File

@@ -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

View File

@@ -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
{

View File

@@ -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

View File

@@ -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)
{

View File

@@ -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)
{
}

View File

@@ -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);

View File

@@ -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*)&param);
}
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*)&param, 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*)&param, 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*)&param);
}
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*)&param, 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

View File

@@ -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

View File

@@ -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
};
//----------------------------------------------------------------------------

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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;

View File

@@ -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

View File

@@ -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;

View File

@@ -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;
};

View File

@@ -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()

View File

@@ -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(&timestamp);
U16 our_clock_seq = clock_seq;
// if clock went backward change clockseq
if (cmpTime(&timestamp, &time_last) == -1) {
// if clock hasn't changed or went backward, change clockseq
if (cmpTime(&timestamp, &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;

View File

@@ -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);

View File

@@ -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

View File

@@ -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;

View File

@@ -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.

View File

@@ -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);

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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)

View File

@@ -364,7 +364,6 @@ public:
{
if (mHandlerFunc)
{
LLPerfBlock msg_cb_time("msg_cb", mName);
mHandlerFunc(msgsystem, mUserData);
return TRUE;
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -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

View File

@@ -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
View 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

View File

@@ -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++)
{

View File

@@ -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;
}
}

View File

@@ -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

View File

@@ -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 );

View File

@@ -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;

View File

@@ -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

View File

@@ -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;
};

View File

@@ -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);
}

View File

@@ -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())
{

View File

@@ -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();

View File

@@ -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()));
}

View File

@@ -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;

View File

@@ -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;
}
}

View File

@@ -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

View File

@@ -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>

View File

@@ -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>

View File

@@ -209,7 +209,7 @@
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
<integer>0</integer>
</map>
<key>RLVaWearReplaceUnlocked</key>
<map>

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -63,7 +63,7 @@ protected:
bool mAnnounceSnapshots;
bool mAnnounceStreamMetadata;
//Tags\Colors
BOOL mAscentUseTag;
BOOL mAscentBroadcastTag;
std::string mReportClientUUID;
U32 mSelectedClient;
BOOL mShowSelfClientTag;

View File

@@ -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]&region=[REGION]&x=[X]&y=[Y]&z=[Z]&session=[SESSION]";
return "lang=[LANG]&mat=[MATURITY]&t=[TEEN]&region=[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]&region=[REGION]&x=[X]&y=[Y]&z=[Z]&session=[SESSION]";
return "lang=[LANG]&m=[MATURITY]&t=[TEEN]&region=[REGION]&x=[X]&y=[Y]&z=[Z]&session=[SESSION]&dice=[DICE]";
}
else
{

View File

@@ -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);

View File

@@ -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();
}
////////////////////////////////////////

View File

@@ -275,7 +275,6 @@ const S32 AGENT_UPDATES_PER_SECOND = 10;
extern LLSD gDebugInfo;
extern BOOL gAllowIdleAFK;
extern BOOL gAllowTapTapHoldRun;
extern BOOL gShowObjectUpdates;

View File

@@ -278,3 +278,10 @@ void LLContainerView::setDisplayChildren(const BOOL displayChildren)
childp->setVisible(mDisplayChildren);
}
}
void LLContainerView::setScrollContainer(LLScrollableContainerView* scroll)
{
mScrollContainer = scroll;
scroll->setPassBackToChildren(false);
}

View File

@@ -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;

View File

@@ -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();

View File

@@ -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;

View File

@@ -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();
}

View File

@@ -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;
};

View File

@@ -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;
}

View File

@@ -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)

View File

@@ -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);

View File

@@ -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;

View File

@@ -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)

View File

@@ -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;

View File

@@ -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)

File diff suppressed because it is too large Load Diff

View 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

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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();

View File

@@ -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);

View File

@@ -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()

View File

@@ -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");
}
}

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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();

View File

@@ -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())

View File

@@ -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;

View File

@@ -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 );

View File

@@ -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;

View File

@@ -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)

View File

@@ -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) )

View File

@@ -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);

View File

@@ -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
{

View File

@@ -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

View File

@@ -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();
}

View File

@@ -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