Merge branch 'DRTVWR-588-maint-W' into marchcat/588-w-pbr-merge
# Conflicts: # indra/llrender/llgl.cpp # indra/llrender/llvertexbuffer.cpp # indra/llui/llflatlistview.cpp # indra/newview/lldrawpoolground.cpp # indra/newview/llspatialpartition.cpp # indra/newview/lltexturefetch.cpp # indra/newview/llviewergenericmessage.cpp # indra/newview/llviewertexture.cpp # indra/newview/llvosky.cpp # indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml # indra/newview/skins/default/xui/en/floater_stats.xml # indra/newview/skins/default/xui/en/floater_texture_fetch_debugger.xml # indra/newview/skins/default/xui/en/notifications.xml # indra/newview/skins/default/xui/en/panel_performance_preferences.xmlmaster
commit
0465c761a4
|
|
@ -360,6 +360,11 @@ jobs:
|
|||
# name the release page for the build number so we can find it
|
||||
# easily (analogous to looking up a codeticket build page)
|
||||
name: "v${{ github.run_id }}"
|
||||
# SL-20546: want the channel and version to be visible on the
|
||||
# release page
|
||||
body: |
|
||||
${{ needs.build.outputs.viewer_channel }}
|
||||
${{ needs.build.outputs.viewer_version }}
|
||||
prerelease: true
|
||||
generate_release_notes: true
|
||||
# the only reason we generate a GH release is to post build products
|
||||
|
|
|
|||
|
|
@ -291,6 +291,7 @@ Beq Janus
|
|||
SL-18637
|
||||
SL-19317
|
||||
SL-19660
|
||||
SL-20610
|
||||
Beth Walcher
|
||||
Bezilon Kasei
|
||||
Biancaluce Robbiani
|
||||
|
|
|
|||
|
|
@ -104,7 +104,6 @@ BOOL LLApp::sLogInSignal = FALSE;
|
|||
// Keeps track of application status
|
||||
LLScalarCond<LLApp::EAppStatus> LLApp::sStatus{LLApp::APP_STATUS_STOPPED};
|
||||
LLAppErrorHandler LLApp::sErrorHandler = NULL;
|
||||
BOOL LLApp::sErrorThreadRunning = FALSE;
|
||||
|
||||
|
||||
LLApp::LLApp()
|
||||
|
|
@ -787,13 +786,8 @@ void default_unix_signal_handler(int signum, siginfo_t *info, void *)
|
|||
return;
|
||||
}
|
||||
|
||||
// Flag status to ERROR, so thread_error does its work.
|
||||
// Flag status to ERROR
|
||||
LLApp::setError();
|
||||
// Block in the signal handler until somebody says that we're done.
|
||||
while (LLApp::sErrorThreadRunning && !LLApp::isStopped())
|
||||
{
|
||||
ms_sleep(10);
|
||||
}
|
||||
|
||||
if (LLApp::sLogInSignal)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -291,7 +291,6 @@ protected:
|
|||
|
||||
static void setStatus(EAppStatus status); // Use this to change the application status.
|
||||
static LLScalarCond<EAppStatus> sStatus; // Reflects current application status
|
||||
static BOOL sErrorThreadRunning; // Set while the error thread is running
|
||||
static BOOL sDisableCrashlogger; // Let the OS handle crashes for us.
|
||||
std::wstring mCrashReportPipeStr; //Name of pipe to use for crash reporting.
|
||||
|
||||
|
|
|
|||
|
|
@ -38,6 +38,12 @@ const S32 FULL_VOLATILE_APR_POOL = 1024 ; //number of references to LLVolatileAP
|
|||
|
||||
bool gAPRInitialized = false;
|
||||
|
||||
int abortfunc(int retcode)
|
||||
{
|
||||
LL_WARNS("APR") << "Allocation failure in apr pool with code " << (S32)retcode << LL_ENDL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ll_init_apr()
|
||||
{
|
||||
// Initialize APR and create the global pool
|
||||
|
|
@ -45,7 +51,7 @@ void ll_init_apr()
|
|||
|
||||
if (!gAPRPoolp)
|
||||
{
|
||||
apr_pool_create(&gAPRPoolp, NULL);
|
||||
apr_pool_create_ex(&gAPRPoolp, NULL, abortfunc, NULL);
|
||||
}
|
||||
|
||||
if(!LLAPRFile::sAPRFilePoolp)
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@ LLCoros::LLCoros():
|
|||
// Previously we used
|
||||
// boost::context::guarded_stack_allocator::default_stacksize();
|
||||
// empirically this is insufficient.
|
||||
mStackSize(768*1024),
|
||||
mStackSize(900*1024),
|
||||
// mCurrent does NOT own the current CoroData instance -- it simply
|
||||
// points to it. So initialize it with a no-op deleter.
|
||||
mCurrent{ [](CoroData*){} }
|
||||
|
|
|
|||
|
|
@ -87,11 +87,10 @@ protected:
|
|||
}
|
||||
void addEntry(Index index, Entry *entry)
|
||||
{
|
||||
if (lookup(index))
|
||||
if (!this->emplace(index, entry).second)
|
||||
{
|
||||
LL_ERRS() << "Dictionary entry already added (attempted to add duplicate entry)" << LL_ENDL;
|
||||
}
|
||||
(*this)[index] = entry;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -46,33 +46,32 @@
|
|||
template <class Type> class LLPointer
|
||||
{
|
||||
public:
|
||||
|
||||
LLPointer() :
|
||||
LLPointer() :
|
||||
mPointer(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
LLPointer(Type* ptr) :
|
||||
LLPointer(Type* ptr) :
|
||||
mPointer(ptr)
|
||||
{
|
||||
ref();
|
||||
}
|
||||
|
||||
LLPointer(const LLPointer<Type>& ptr) :
|
||||
LLPointer(const LLPointer<Type>& ptr) :
|
||||
mPointer(ptr.mPointer)
|
||||
{
|
||||
ref();
|
||||
}
|
||||
|
||||
// support conversion up the type hierarchy. See Item 45 in Effective C++, 3rd Ed.
|
||||
// Support conversion up the type hierarchy. See Item 45 in Effective C++, 3rd Ed.
|
||||
template<typename Subclass>
|
||||
LLPointer(const LLPointer<Subclass>& ptr) :
|
||||
LLPointer(const LLPointer<Subclass>& ptr) :
|
||||
mPointer(ptr.get())
|
||||
{
|
||||
ref();
|
||||
}
|
||||
|
||||
~LLPointer()
|
||||
~LLPointer()
|
||||
{
|
||||
unref();
|
||||
}
|
||||
|
|
@ -83,39 +82,39 @@ public:
|
|||
const Type& operator*() const { return *mPointer; }
|
||||
Type& operator*() { return *mPointer; }
|
||||
|
||||
operator BOOL() const { return (mPointer != NULL); }
|
||||
operator bool() const { return (mPointer != NULL); }
|
||||
operator BOOL() const { return (mPointer != NULL); }
|
||||
operator bool() const { return (mPointer != NULL); }
|
||||
bool operator!() const { return (mPointer == NULL); }
|
||||
bool isNull() const { return (mPointer == NULL); }
|
||||
bool notNull() const { return (mPointer != NULL); }
|
||||
|
||||
operator Type*() const { return mPointer; }
|
||||
bool operator !=(Type* ptr) const { return (mPointer != ptr); }
|
||||
bool operator ==(Type* ptr) const { return (mPointer == ptr); }
|
||||
bool operator ==(const LLPointer<Type>& ptr) const { return (mPointer == ptr.mPointer); }
|
||||
bool operator < (const LLPointer<Type>& ptr) const { return (mPointer < ptr.mPointer); }
|
||||
bool operator > (const LLPointer<Type>& ptr) const { return (mPointer > ptr.mPointer); }
|
||||
operator Type*() const { return mPointer; }
|
||||
bool operator !=(Type* ptr) const { return (mPointer != ptr); }
|
||||
bool operator ==(Type* ptr) const { return (mPointer == ptr); }
|
||||
bool operator ==(const LLPointer<Type>& ptr) const { return (mPointer == ptr.mPointer); }
|
||||
bool operator < (const LLPointer<Type>& ptr) const { return (mPointer < ptr.mPointer); }
|
||||
bool operator > (const LLPointer<Type>& ptr) const { return (mPointer > ptr.mPointer); }
|
||||
|
||||
LLPointer<Type>& operator =(Type* ptr)
|
||||
{
|
||||
LLPointer<Type>& operator =(Type* ptr)
|
||||
{
|
||||
assign(ptr);
|
||||
return *this;
|
||||
return *this;
|
||||
}
|
||||
|
||||
LLPointer<Type>& operator =(const LLPointer<Type>& ptr)
|
||||
{
|
||||
LLPointer<Type>& operator =(const LLPointer<Type>& ptr)
|
||||
{
|
||||
assign(ptr);
|
||||
return *this;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// support assignment up the type hierarchy. See Item 45 in Effective C++, 3rd Ed.
|
||||
template<typename Subclass>
|
||||
LLPointer<Type>& operator =(const LLPointer<Subclass>& ptr)
|
||||
{
|
||||
LLPointer<Type>& operator =(const LLPointer<Subclass>& ptr)
|
||||
{
|
||||
assign(ptr.get());
|
||||
return *this;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
// Just exchange the pointers, which will not change the reference counts.
|
||||
static void swap(LLPointer<Type>& a, LLPointer<Type>& b)
|
||||
{
|
||||
|
|
@ -129,16 +128,6 @@ protected:
|
|||
void ref();
|
||||
void unref();
|
||||
#else
|
||||
|
||||
void assign(const LLPointer<Type>& ptr)
|
||||
{
|
||||
if( mPointer != ptr.mPointer )
|
||||
{
|
||||
unref();
|
||||
mPointer = ptr.mPointer;
|
||||
ref();
|
||||
}
|
||||
}
|
||||
void ref()
|
||||
{
|
||||
if (mPointer)
|
||||
|
|
@ -161,7 +150,18 @@ protected:
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif // LL_LIBRARY_INCLUDE
|
||||
|
||||
void assign(const LLPointer<Type>& ptr)
|
||||
{
|
||||
if (mPointer != ptr.mPointer)
|
||||
{
|
||||
unref();
|
||||
mPointer = ptr.mPointer;
|
||||
ref();
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
Type* mPointer;
|
||||
};
|
||||
|
|
@ -169,18 +169,18 @@ protected:
|
|||
template <class Type> class LLConstPointer
|
||||
{
|
||||
public:
|
||||
LLConstPointer() :
|
||||
LLConstPointer() :
|
||||
mPointer(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
LLConstPointer(const Type* ptr) :
|
||||
LLConstPointer(const Type* ptr) :
|
||||
mPointer(ptr)
|
||||
{
|
||||
ref();
|
||||
}
|
||||
|
||||
LLConstPointer(const LLConstPointer<Type>& ptr) :
|
||||
LLConstPointer(const LLConstPointer<Type>& ptr) :
|
||||
mPointer(ptr.mPointer)
|
||||
{
|
||||
ref();
|
||||
|
|
@ -188,7 +188,7 @@ public:
|
|||
|
||||
// support conversion up the type hierarchy. See Item 45 in Effective C++, 3rd Ed.
|
||||
template<typename Subclass>
|
||||
LLConstPointer(const LLConstPointer<Subclass>& ptr) :
|
||||
LLConstPointer(const LLConstPointer<Subclass>& ptr) :
|
||||
mPointer(ptr.get())
|
||||
{
|
||||
ref();
|
||||
|
|
@ -203,55 +203,55 @@ public:
|
|||
const Type* operator->() const { return mPointer; }
|
||||
const Type& operator*() const { return *mPointer; }
|
||||
|
||||
operator BOOL() const { return (mPointer != NULL); }
|
||||
operator bool() const { return (mPointer != NULL); }
|
||||
operator BOOL() const { return (mPointer != NULL); }
|
||||
operator bool() const { return (mPointer != NULL); }
|
||||
bool operator!() const { return (mPointer == NULL); }
|
||||
bool isNull() const { return (mPointer == NULL); }
|
||||
bool notNull() const { return (mPointer != NULL); }
|
||||
|
||||
operator const Type*() const { return mPointer; }
|
||||
bool operator !=(const Type* ptr) const { return (mPointer != ptr); }
|
||||
bool operator ==(const Type* ptr) const { return (mPointer == ptr); }
|
||||
bool operator ==(const LLConstPointer<Type>& ptr) const { return (mPointer == ptr.mPointer); }
|
||||
bool operator < (const LLConstPointer<Type>& ptr) const { return (mPointer < ptr.mPointer); }
|
||||
bool operator > (const LLConstPointer<Type>& ptr) const { return (mPointer > ptr.mPointer); }
|
||||
operator const Type*() const { return mPointer; }
|
||||
bool operator !=(const Type* ptr) const { return (mPointer != ptr); }
|
||||
bool operator ==(const Type* ptr) const { return (mPointer == ptr); }
|
||||
bool operator ==(const LLConstPointer<Type>& ptr) const { return (mPointer == ptr.mPointer); }
|
||||
bool operator < (const LLConstPointer<Type>& ptr) const { return (mPointer < ptr.mPointer); }
|
||||
bool operator > (const LLConstPointer<Type>& ptr) const { return (mPointer > ptr.mPointer); }
|
||||
|
||||
LLConstPointer<Type>& operator =(const Type* ptr)
|
||||
LLConstPointer<Type>& operator =(const Type* ptr)
|
||||
{
|
||||
if( mPointer != ptr )
|
||||
{
|
||||
unref();
|
||||
mPointer = ptr;
|
||||
unref();
|
||||
mPointer = ptr;
|
||||
ref();
|
||||
}
|
||||
|
||||
return *this;
|
||||
return *this;
|
||||
}
|
||||
|
||||
LLConstPointer<Type>& operator =(const LLConstPointer<Type>& ptr)
|
||||
{
|
||||
LLConstPointer<Type>& operator =(const LLConstPointer<Type>& ptr)
|
||||
{
|
||||
if( mPointer != ptr.mPointer )
|
||||
{
|
||||
unref();
|
||||
unref();
|
||||
mPointer = ptr.mPointer;
|
||||
ref();
|
||||
}
|
||||
return *this;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// support assignment up the type hierarchy. See Item 45 in Effective C++, 3rd Ed.
|
||||
template<typename Subclass>
|
||||
LLConstPointer<Type>& operator =(const LLConstPointer<Subclass>& ptr)
|
||||
{
|
||||
LLConstPointer<Type>& operator =(const LLConstPointer<Subclass>& ptr)
|
||||
{
|
||||
if( mPointer != ptr.get() )
|
||||
{
|
||||
unref();
|
||||
unref();
|
||||
mPointer = ptr.get();
|
||||
ref();
|
||||
}
|
||||
return *this;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
// Just exchange the pointers, which will not change the reference counts.
|
||||
static void swap(LLConstPointer<Type>& a, LLConstPointer<Type>& b)
|
||||
{
|
||||
|
|
@ -262,11 +262,11 @@ public:
|
|||
|
||||
protected:
|
||||
#ifdef LL_LIBRARY_INCLUDE
|
||||
void ref();
|
||||
void ref();
|
||||
void unref();
|
||||
#else
|
||||
void ref()
|
||||
{
|
||||
#else // LL_LIBRARY_INCLUDE
|
||||
void ref()
|
||||
{
|
||||
if (mPointer)
|
||||
{
|
||||
mPointer->ref();
|
||||
|
|
@ -277,9 +277,9 @@ protected:
|
|||
{
|
||||
if (mPointer)
|
||||
{
|
||||
const Type *tempp = mPointer;
|
||||
const Type *temp = mPointer;
|
||||
mPointer = NULL;
|
||||
tempp->unref();
|
||||
temp->unref();
|
||||
if (mPointer != NULL)
|
||||
{
|
||||
LL_WARNS() << "Unreference did assignment to non-NULL because of destructor" << LL_ENDL;
|
||||
|
|
@ -287,7 +287,8 @@ protected:
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif // LL_LIBRARY_INCLUDE
|
||||
|
||||
protected:
|
||||
const Type* mPointer;
|
||||
};
|
||||
|
|
@ -297,13 +298,13 @@ class LLCopyOnWritePointer : public LLPointer<Type>
|
|||
{
|
||||
public:
|
||||
typedef LLCopyOnWritePointer<Type> self_t;
|
||||
typedef LLPointer<Type> pointer_t;
|
||||
|
||||
LLCopyOnWritePointer()
|
||||
typedef LLPointer<Type> pointer_t;
|
||||
|
||||
LLCopyOnWritePointer()
|
||||
: mStayUnique(false)
|
||||
{}
|
||||
|
||||
LLCopyOnWritePointer(Type* ptr)
|
||||
LLCopyOnWritePointer(Type* ptr)
|
||||
: LLPointer<Type>(ptr),
|
||||
mStayUnique(false)
|
||||
{}
|
||||
|
|
|
|||
|
|
@ -529,6 +529,7 @@ LLProcess::LLProcess(const LLSDOrParams& params):
|
|||
// preserve existing semantics, we promise that mAttached defaults to the
|
||||
// same setting as mAutokill.
|
||||
mAttached(params.attached.isProvided()? params.attached : params.autokill),
|
||||
mPool(NULL),
|
||||
mPipes(NSLOTS)
|
||||
{
|
||||
// Hmm, when you construct a ptr_vector with a size, it merely reserves
|
||||
|
|
@ -549,8 +550,14 @@ LLProcess::LLProcess(const LLSDOrParams& params):
|
|||
|
||||
mPostend = params.postend;
|
||||
|
||||
apr_pool_create(&mPool, gAPRPoolp);
|
||||
if (!mPool)
|
||||
{
|
||||
LLTHROW(LLProcessError(STRINGIZE("failed to create apr pool")));
|
||||
}
|
||||
|
||||
apr_procattr_t *procattr = NULL;
|
||||
chkapr(apr_procattr_create(&procattr, gAPRPoolp));
|
||||
chkapr(apr_procattr_create(&procattr, mPool));
|
||||
|
||||
// IQA-490, CHOP-900: On Windows, ask APR to jump through hoops to
|
||||
// constrain the set of handles passed to the child process. Before we
|
||||
|
|
@ -689,14 +696,14 @@ LLProcess::LLProcess(const LLSDOrParams& params):
|
|||
// one. Hand-expand chkapr() macro so we can fill in the actual command
|
||||
// string instead of the variable names.
|
||||
if (ll_apr_warn_status(apr_proc_create(&mProcess, argv[0], &argv[0], NULL, procattr,
|
||||
gAPRPoolp)))
|
||||
mPool)))
|
||||
{
|
||||
LLTHROW(LLProcessError(STRINGIZE(params << " failed")));
|
||||
}
|
||||
|
||||
// arrange to call status_callback()
|
||||
apr_proc_other_child_register(&mProcess, &LLProcess::status_callback, this, mProcess.in,
|
||||
gAPRPoolp);
|
||||
mPool);
|
||||
// and make sure we poll it once per "mainloop" tick
|
||||
sProcessListener.addPoll(*this);
|
||||
mStatus.mState = RUNNING;
|
||||
|
|
@ -815,6 +822,12 @@ LLProcess::~LLProcess()
|
|||
{
|
||||
kill("destructor");
|
||||
}
|
||||
|
||||
if (mPool)
|
||||
{
|
||||
apr_pool_destroy(mPool);
|
||||
mPool = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
bool LLProcess::kill(const std::string& who)
|
||||
|
|
|
|||
|
|
@ -568,6 +568,7 @@ private:
|
|||
// explicitly want this ptr_vector to be able to store NULLs
|
||||
typedef boost::ptr_vector< boost::nullable<BasePipe> > PipeVector;
|
||||
PipeVector mPipes;
|
||||
apr_pool_t* mPool;
|
||||
};
|
||||
|
||||
/// for logging
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
#include "llerror.h"
|
||||
|
||||
// maximum reference count before sounding memory leak alarm
|
||||
const S32 gMaxRefCount = S32_MAX;
|
||||
const S32 gMaxRefCount = LL_REFCOUNT_FREE;
|
||||
|
||||
LLRefCount::LLRefCount(const LLRefCount& other)
|
||||
: mRef(0)
|
||||
|
|
@ -49,7 +49,7 @@ LLRefCount::LLRefCount() :
|
|||
}
|
||||
|
||||
LLRefCount::~LLRefCount()
|
||||
{
|
||||
{
|
||||
if (mRef != LL_REFCOUNT_FREE && mRef != 0)
|
||||
{
|
||||
LL_ERRS() << "deleting non-zero reference" << LL_ENDL;
|
||||
|
|
|
|||
|
|
@ -51,24 +51,20 @@ protected:
|
|||
public:
|
||||
LLRefCount();
|
||||
|
||||
inline void validateRefCount() const
|
||||
{
|
||||
llassert(mRef > 0); // ref count below 0, likely corrupted
|
||||
llassert(mRef < gMaxRefCount); // ref count excessive, likely memory leak
|
||||
}
|
||||
|
||||
inline void ref() const
|
||||
{
|
||||
mRef++;
|
||||
validateRefCount();
|
||||
}
|
||||
{
|
||||
llassert(mRef != LL_REFCOUNT_FREE); // object is deleted
|
||||
mRef++;
|
||||
llassert(mRef < gMaxRefCount); // ref count excessive, likely memory leak
|
||||
}
|
||||
|
||||
inline S32 unref() const
|
||||
{
|
||||
validateRefCount();
|
||||
llassert(mRef != LL_REFCOUNT_FREE); // object is deleted
|
||||
llassert(mRef > 0); // ref count below 1, likely corrupted
|
||||
if (0 == --mRef)
|
||||
{
|
||||
mRef = LL_REFCOUNT_FREE; // set to nonsense yet recognizable value to aid in debugging
|
||||
mRef = LL_REFCOUNT_FREE; // set to nonsense yet recognizable value to aid in debugging
|
||||
delete this;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -82,8 +78,8 @@ public:
|
|||
return mRef;
|
||||
}
|
||||
|
||||
private:
|
||||
mutable S32 mRef;
|
||||
private:
|
||||
mutable S32 mRef;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -106,7 +102,7 @@ protected:
|
|||
public:
|
||||
LLThreadSafeRefCount();
|
||||
LLThreadSafeRefCount(const LLThreadSafeRefCount&);
|
||||
LLThreadSafeRefCount& operator=(const LLThreadSafeRefCount& ref)
|
||||
LLThreadSafeRefCount& operator=(const LLThreadSafeRefCount& ref)
|
||||
{
|
||||
mRef = 0;
|
||||
return *this;
|
||||
|
|
@ -114,8 +110,8 @@ public:
|
|||
|
||||
void ref()
|
||||
{
|
||||
mRef++;
|
||||
}
|
||||
mRef++;
|
||||
}
|
||||
|
||||
void unref()
|
||||
{
|
||||
|
|
@ -136,36 +132,36 @@ public:
|
|||
return currentVal;
|
||||
}
|
||||
|
||||
private:
|
||||
LLAtomicS32 mRef;
|
||||
private:
|
||||
LLAtomicS32 mRef;
|
||||
};
|
||||
|
||||
/**
|
||||
* intrusive pointer support for LLThreadSafeRefCount
|
||||
* this allows you to use boost::intrusive_ptr with any LLThreadSafeRefCount-derived type
|
||||
*/
|
||||
inline void intrusive_ptr_add_ref(LLThreadSafeRefCount* p)
|
||||
inline void intrusive_ptr_add_ref(LLThreadSafeRefCount* p)
|
||||
{
|
||||
p->ref();
|
||||
}
|
||||
|
||||
inline void intrusive_ptr_release(LLThreadSafeRefCount* p)
|
||||
inline void intrusive_ptr_release(LLThreadSafeRefCount* p)
|
||||
{
|
||||
p->unref();
|
||||
p->unref();
|
||||
}
|
||||
|
||||
/**
|
||||
* intrusive pointer support
|
||||
* this allows you to use boost::intrusive_ptr with any LLRefCount-derived type
|
||||
*/
|
||||
inline void intrusive_ptr_add_ref(LLRefCount* p)
|
||||
inline void intrusive_ptr_add_ref(LLRefCount* p)
|
||||
{
|
||||
p->ref();
|
||||
}
|
||||
|
||||
inline void intrusive_ptr_release(LLRefCount* p)
|
||||
inline void intrusive_ptr_release(LLRefCount* p)
|
||||
{
|
||||
p->unref();
|
||||
p->unref();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1235,9 +1235,17 @@ bool LLStringUtil::formatDatetime(std::string& replacement, std::string token,
|
|||
}
|
||||
else
|
||||
{
|
||||
#if 0
|
||||
// EXT-1565 : Zai Lynch, James Linden : 15/Oct/09
|
||||
// [BSI] Feedback: Viewer clock mentions SLT, but would prefer it to show PST/PDT
|
||||
// "slt" = Second Life Time, which is deprecated.
|
||||
// If not utc or user local time, fallback to Pacific time
|
||||
replacement = LLStringOps::getPacificDaylightTime() ? "PDT" : "PST";
|
||||
#else
|
||||
// SL-20370 : Steeltoe Linden : 29/Sep/23
|
||||
// Change "PDT" to "SLT" on menu bar
|
||||
replacement = "SLT";
|
||||
#endif
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,8 +33,6 @@
|
|||
namespace LLTrace
|
||||
{
|
||||
|
||||
MemStatHandle gTraceMemStat("LLTrace");
|
||||
|
||||
StatBase::StatBase( const char* name, const char* description )
|
||||
: mName(name),
|
||||
mDescription(description ? description : "")
|
||||
|
|
|
|||
|
|
@ -193,61 +193,6 @@ void add(CountStatHandle<T>& count, VALUE_T value)
|
|||
#endif
|
||||
}
|
||||
|
||||
template<>
|
||||
class StatType<MemAccumulator::AllocationFacet>
|
||||
: public StatType<MemAccumulator>
|
||||
{
|
||||
public:
|
||||
|
||||
StatType(const char* name, const char* description = "")
|
||||
: StatType<MemAccumulator>(name, description)
|
||||
{}
|
||||
};
|
||||
|
||||
template<>
|
||||
class StatType<MemAccumulator::DeallocationFacet>
|
||||
: public StatType<MemAccumulator>
|
||||
{
|
||||
public:
|
||||
|
||||
StatType(const char* name, const char* description = "")
|
||||
: StatType<MemAccumulator>(name, description)
|
||||
{}
|
||||
};
|
||||
|
||||
class MemStatHandle : public StatType<MemAccumulator>
|
||||
{
|
||||
public:
|
||||
typedef StatType<MemAccumulator> stat_t;
|
||||
MemStatHandle(const char* name, const char* description = "")
|
||||
: stat_t(name, description)
|
||||
{
|
||||
mName = name;
|
||||
}
|
||||
|
||||
void setName(const char* name)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
mName = name;
|
||||
setKey(name);
|
||||
}
|
||||
|
||||
/*virtual*/ const char* getUnitLabel() const { return "KB"; }
|
||||
|
||||
StatType<MemAccumulator::AllocationFacet>& allocations()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
return static_cast<StatType<MemAccumulator::AllocationFacet>&>(*(StatType<MemAccumulator>*)this);
|
||||
}
|
||||
|
||||
StatType<MemAccumulator::DeallocationFacet>& deallocations()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
return static_cast<StatType<MemAccumulator::DeallocationFacet>&>(*(StatType<MemAccumulator>*)this);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// measures effective memory footprint of specified type
|
||||
// specialize to cover different types
|
||||
template<typename T, typename IS_MEM_TRACKABLE = void, typename IS_UNITS = void>
|
||||
|
|
@ -334,33 +279,6 @@ struct MeasureMem<std::basic_string<T>, IS_MEM_TRACKABLE, IS_BYTES>
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
template<typename T>
|
||||
inline void claim_alloc(MemStatHandle& measurement, const T& value)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
#if LL_TRACE_ENABLED
|
||||
auto size = MeasureMem<T>::measureFootprint(value);
|
||||
if(size == 0) return;
|
||||
MemAccumulator& accumulator = measurement.getCurrentAccumulator();
|
||||
accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() + (F64)size : (F64)size);
|
||||
accumulator.mAllocations.record(size);
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void disclaim_alloc(MemStatHandle& measurement, const T& value)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
#if LL_TRACE_ENABLED
|
||||
auto size = MeasureMem<T>::measureFootprint(value);
|
||||
if(size == 0) return;
|
||||
MemAccumulator& accumulator = measurement.getCurrentAccumulator();
|
||||
accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() - (F64)size : -(F64)size);
|
||||
accumulator.mDeallocations.add(size);
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // LL_LLTRACE_H
|
||||
|
|
|
|||
|
|
@ -1,24 +1,24 @@
|
|||
/**
|
||||
/**
|
||||
* @file lltracesampler.cpp
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2012, 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$
|
||||
*/
|
||||
|
|
@ -32,66 +32,45 @@
|
|||
namespace LLTrace
|
||||
{
|
||||
|
||||
extern MemStatHandle gTraceMemStat;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// AccumulatorBufferGroup
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
AccumulatorBufferGroup::AccumulatorBufferGroup()
|
||||
AccumulatorBufferGroup::AccumulatorBufferGroup()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
claim_alloc(gTraceMemStat, mCounts.capacity() * sizeof(CountAccumulator));
|
||||
claim_alloc(gTraceMemStat, mSamples.capacity() * sizeof(SampleAccumulator));
|
||||
claim_alloc(gTraceMemStat, mEvents.capacity() * sizeof(EventAccumulator));
|
||||
claim_alloc(gTraceMemStat, mStackTimers.capacity() * sizeof(TimeBlockAccumulator));
|
||||
claim_alloc(gTraceMemStat, mMemStats.capacity() * sizeof(MemAccumulator));
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
}
|
||||
|
||||
AccumulatorBufferGroup::AccumulatorBufferGroup(const AccumulatorBufferGroup& other)
|
||||
: mCounts(other.mCounts),
|
||||
mSamples(other.mSamples),
|
||||
mEvents(other.mEvents),
|
||||
mStackTimers(other.mStackTimers),
|
||||
mMemStats(other.mMemStats)
|
||||
mStackTimers(other.mStackTimers)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
claim_alloc(gTraceMemStat, mCounts.capacity() * sizeof(CountAccumulator));
|
||||
claim_alloc(gTraceMemStat, mSamples.capacity() * sizeof(SampleAccumulator));
|
||||
claim_alloc(gTraceMemStat, mEvents.capacity() * sizeof(EventAccumulator));
|
||||
claim_alloc(gTraceMemStat, mStackTimers.capacity() * sizeof(TimeBlockAccumulator));
|
||||
claim_alloc(gTraceMemStat, mMemStats.capacity() * sizeof(MemAccumulator));
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
}
|
||||
|
||||
AccumulatorBufferGroup::~AccumulatorBufferGroup()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
disclaim_alloc(gTraceMemStat, mCounts.capacity() * sizeof(CountAccumulator));
|
||||
disclaim_alloc(gTraceMemStat, mSamples.capacity() * sizeof(SampleAccumulator));
|
||||
disclaim_alloc(gTraceMemStat, mEvents.capacity() * sizeof(EventAccumulator));
|
||||
disclaim_alloc(gTraceMemStat, mStackTimers.capacity() * sizeof(TimeBlockAccumulator));
|
||||
disclaim_alloc(gTraceMemStat, mMemStats.capacity() * sizeof(MemAccumulator));
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
}
|
||||
|
||||
void AccumulatorBufferGroup::handOffTo(AccumulatorBufferGroup& other)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
other.mCounts.reset(&mCounts);
|
||||
other.mSamples.reset(&mSamples);
|
||||
other.mEvents.reset(&mEvents);
|
||||
other.mStackTimers.reset(&mStackTimers);
|
||||
other.mMemStats.reset(&mMemStats);
|
||||
}
|
||||
|
||||
void AccumulatorBufferGroup::makeCurrent()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
mCounts.makeCurrent();
|
||||
mSamples.makeCurrent();
|
||||
mEvents.makeCurrent();
|
||||
mStackTimers.makeCurrent();
|
||||
mMemStats.makeCurrent();
|
||||
|
||||
ThreadRecorder* thread_recorder = get_thread_recorder();
|
||||
AccumulatorBuffer<TimeBlockAccumulator>& timer_accumulator_buffer = mStackTimers;
|
||||
|
|
@ -109,12 +88,11 @@ void AccumulatorBufferGroup::makeCurrent()
|
|||
//static
|
||||
void AccumulatorBufferGroup::clearCurrent()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
AccumulatorBuffer<CountAccumulator>::clearCurrent();
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
AccumulatorBuffer<CountAccumulator>::clearCurrent();
|
||||
AccumulatorBuffer<SampleAccumulator>::clearCurrent();
|
||||
AccumulatorBuffer<EventAccumulator>::clearCurrent();
|
||||
AccumulatorBuffer<TimeBlockAccumulator>::clearCurrent();
|
||||
AccumulatorBuffer<MemAccumulator>::clearCurrent();
|
||||
}
|
||||
|
||||
bool AccumulatorBufferGroup::isCurrent() const
|
||||
|
|
@ -124,44 +102,39 @@ bool AccumulatorBufferGroup::isCurrent() const
|
|||
|
||||
void AccumulatorBufferGroup::append( const AccumulatorBufferGroup& other )
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
mCounts.addSamples(other.mCounts, SEQUENTIAL);
|
||||
mSamples.addSamples(other.mSamples, SEQUENTIAL);
|
||||
mEvents.addSamples(other.mEvents, SEQUENTIAL);
|
||||
mMemStats.addSamples(other.mMemStats, SEQUENTIAL);
|
||||
mStackTimers.addSamples(other.mStackTimers, SEQUENTIAL);
|
||||
}
|
||||
|
||||
void AccumulatorBufferGroup::merge( const AccumulatorBufferGroup& other)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
mCounts.addSamples(other.mCounts, NON_SEQUENTIAL);
|
||||
mSamples.addSamples(other.mSamples, NON_SEQUENTIAL);
|
||||
mEvents.addSamples(other.mEvents, NON_SEQUENTIAL);
|
||||
mMemStats.addSamples(other.mMemStats, NON_SEQUENTIAL);
|
||||
// for now, hold out timers from merge, need to be displayed per thread
|
||||
//mStackTimers.addSamples(other.mStackTimers, NON_SEQUENTIAL);
|
||||
}
|
||||
|
||||
void AccumulatorBufferGroup::reset(AccumulatorBufferGroup* other)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
mCounts.reset(other ? &other->mCounts : NULL);
|
||||
mSamples.reset(other ? &other->mSamples : NULL);
|
||||
mEvents.reset(other ? &other->mEvents : NULL);
|
||||
mStackTimers.reset(other ? &other->mStackTimers : NULL);
|
||||
mMemStats.reset(other ? &other->mMemStats : NULL);
|
||||
}
|
||||
|
||||
void AccumulatorBufferGroup::sync()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
if (isCurrent())
|
||||
{
|
||||
F64SecondsImplicit time_stamp = LLTimer::getTotalSeconds();
|
||||
|
||||
mSamples.sync(time_stamp);
|
||||
mMemStats.sync(time_stamp);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -197,10 +170,9 @@ F64 SampleAccumulator::mergeSumsOfSquares(const SampleAccumulator& a, const Samp
|
|||
return a.getSumOfSquares();
|
||||
}
|
||||
|
||||
|
||||
void SampleAccumulator::addSamples( const SampleAccumulator& other, EBufferAppendType append_type )
|
||||
{
|
||||
if (append_type == NON_SEQUENTIAL)
|
||||
if (append_type == NON_SEQUENTIAL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
@ -299,7 +271,7 @@ void EventAccumulator::addSamples( const EventAccumulator& other, EBufferAppendT
|
|||
|
||||
void EventAccumulator::reset( const EventAccumulator* other )
|
||||
{
|
||||
mNumSamples = 0;
|
||||
mNumSamples = 0;
|
||||
mSum = 0;
|
||||
mMin = F32(NaN);
|
||||
mMax = F32(NaN);
|
||||
|
|
@ -308,5 +280,4 @@ void EventAccumulator::reset( const EventAccumulator* other )
|
|||
mLastValue = other ? other->mLastValue : NaN;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,26 +1,26 @@
|
|||
|
||||
/**
|
||||
/**
|
||||
* @file lltraceaccumulators.h
|
||||
* @brief Storage for accumulating statistics
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2012, 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$
|
||||
*/
|
||||
|
|
@ -28,7 +28,6 @@
|
|||
#ifndef LL_LLTRACEACCUMULATORS_H
|
||||
#define LL_LLTRACEACCUMULATORS_H
|
||||
|
||||
|
||||
#include "stdtypes.h"
|
||||
#include "llpreprocessor.h"
|
||||
#include "llunits.h"
|
||||
|
|
@ -66,7 +65,7 @@ namespace LLTrace
|
|||
: mStorageSize(0),
|
||||
mStorage(NULL)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
const AccumulatorBuffer& other = *getDefaultBuffer();
|
||||
resize(sNextStorageSlot);
|
||||
for (S32 i = 0; i < sNextStorageSlot; i++)
|
||||
|
|
@ -77,7 +76,7 @@ namespace LLTrace
|
|||
|
||||
~AccumulatorBuffer()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
if (isCurrent())
|
||||
{
|
||||
LLThreadLocalSingletonPointer<ACCUMULATOR>::setInstance(NULL);
|
||||
|
|
@ -85,14 +84,14 @@ namespace LLTrace
|
|||
delete[] mStorage;
|
||||
}
|
||||
|
||||
LL_FORCE_INLINE ACCUMULATOR& operator[](size_t index)
|
||||
{
|
||||
return mStorage[index];
|
||||
LL_FORCE_INLINE ACCUMULATOR& operator[](size_t index)
|
||||
{
|
||||
return mStorage[index];
|
||||
}
|
||||
|
||||
LL_FORCE_INLINE const ACCUMULATOR& operator[](size_t index) const
|
||||
{
|
||||
return mStorage[index];
|
||||
{
|
||||
return mStorage[index];
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -100,7 +99,7 @@ namespace LLTrace
|
|||
: mStorageSize(0),
|
||||
mStorage(NULL)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
resize(sNextStorageSlot);
|
||||
for (S32 i = 0; i < sNextStorageSlot; i++)
|
||||
{
|
||||
|
|
@ -110,7 +109,7 @@ namespace LLTrace
|
|||
|
||||
void addSamples(const AccumulatorBuffer<ACCUMULATOR>& other, EBufferAppendType append_type)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
llassert(mStorageSize >= sNextStorageSlot && other.mStorageSize >= sNextStorageSlot);
|
||||
for (size_t i = 0; i < sNextStorageSlot; i++)
|
||||
{
|
||||
|
|
@ -120,7 +119,7 @@ namespace LLTrace
|
|||
|
||||
void copyFrom(const AccumulatorBuffer<ACCUMULATOR>& other)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
llassert(mStorageSize >= sNextStorageSlot && other.mStorageSize >= sNextStorageSlot);
|
||||
for (size_t i = 0; i < sNextStorageSlot; i++)
|
||||
{
|
||||
|
|
@ -130,7 +129,7 @@ namespace LLTrace
|
|||
|
||||
void reset(const AccumulatorBuffer<ACCUMULATOR>* other = NULL)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
llassert(mStorageSize >= sNextStorageSlot);
|
||||
for (size_t i = 0; i < sNextStorageSlot; i++)
|
||||
{
|
||||
|
|
@ -140,7 +139,7 @@ namespace LLTrace
|
|||
|
||||
void sync(F64SecondsImplicit time_stamp)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
llassert(mStorageSize >= sNextStorageSlot);
|
||||
for (size_t i = 0; i < sNextStorageSlot; i++)
|
||||
{
|
||||
|
|
@ -160,13 +159,13 @@ namespace LLTrace
|
|||
|
||||
static void clearCurrent()
|
||||
{
|
||||
LLThreadLocalSingletonPointer<ACCUMULATOR>::setInstance(NULL);
|
||||
LLThreadLocalSingletonPointer<ACCUMULATOR>::setInstance(NULL);
|
||||
}
|
||||
|
||||
// NOTE: this is not thread-safe. We assume that slots are reserved in the main thread before any child threads are spawned
|
||||
size_t reserveSlot()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
size_t next_slot = sNextStorageSlot++;
|
||||
if (next_slot >= mStorageSize)
|
||||
{
|
||||
|
|
@ -180,7 +179,7 @@ namespace LLTrace
|
|||
|
||||
void resize(size_t new_size)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
if (new_size <= mStorageSize) return;
|
||||
|
||||
ACCUMULATOR* old_storage = mStorage;
|
||||
|
|
@ -214,14 +213,14 @@ namespace LLTrace
|
|||
return mStorageSize;
|
||||
}
|
||||
|
||||
static size_t getNumIndices()
|
||||
static size_t getNumIndices()
|
||||
{
|
||||
return sNextStorageSlot;
|
||||
}
|
||||
|
||||
static self_t* getDefaultBuffer()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
static bool sInitialized = false;
|
||||
if (!sInitialized)
|
||||
{
|
||||
|
|
@ -336,7 +335,7 @@ namespace LLTrace
|
|||
|
||||
void sample(F64 value)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
F64SecondsImplicit time_stamp = LLTimer::getTotalSeconds();
|
||||
|
||||
// store effect of last value
|
||||
|
|
@ -399,7 +398,7 @@ namespace LLTrace
|
|||
F64 mMean,
|
||||
mSumOfSquares;
|
||||
|
||||
F64SecondsImplicit
|
||||
F64SecondsImplicit
|
||||
mLastSampleTimeStamp,
|
||||
mTotalSamplingTime;
|
||||
|
||||
|
|
@ -409,7 +408,7 @@ namespace LLTrace
|
|||
S32 mNumSamples;
|
||||
// distinct from mNumSamples, since we might have inherited a last value from
|
||||
// a previous sampling period
|
||||
bool mHasValue;
|
||||
bool mHasValue;
|
||||
};
|
||||
|
||||
class CountAccumulator
|
||||
|
|
@ -457,14 +456,14 @@ namespace LLTrace
|
|||
|
||||
class alignas(32) TimeBlockAccumulator
|
||||
{
|
||||
public:
|
||||
public:
|
||||
typedef F64Seconds value_t;
|
||||
static F64Seconds getDefaultValue() { return F64Seconds(0); }
|
||||
|
||||
typedef TimeBlockAccumulator self_t;
|
||||
|
||||
// fake classes that allows us to view different facets of underlying statistic
|
||||
struct CallCountFacet
|
||||
struct CallCountFacet
|
||||
{
|
||||
typedef S32 value_t;
|
||||
};
|
||||
|
|
@ -515,12 +514,12 @@ namespace LLTrace
|
|||
BlockTimerStatHandle* getParent() { return mParent; }
|
||||
|
||||
BlockTimerStatHandle* mBlock;
|
||||
BlockTimerStatHandle* mParent;
|
||||
BlockTimerStatHandle* mParent;
|
||||
std::vector<BlockTimerStatHandle*> mChildren;
|
||||
bool mCollapsed;
|
||||
bool mNeedsSorting;
|
||||
};
|
||||
|
||||
|
||||
struct BlockTimerStackRecord
|
||||
{
|
||||
class BlockTimer* mActiveTimer;
|
||||
|
|
@ -528,65 +527,6 @@ namespace LLTrace
|
|||
U64 mChildTime;
|
||||
};
|
||||
|
||||
struct MemAccumulator
|
||||
{
|
||||
typedef F64Bytes value_t;
|
||||
static F64Bytes getDefaultValue() { return F64Bytes(0); }
|
||||
|
||||
typedef MemAccumulator self_t;
|
||||
|
||||
// fake classes that allows us to view different facets of underlying statistic
|
||||
struct AllocationFacet
|
||||
{
|
||||
typedef F64Bytes value_t;
|
||||
static F64Bytes getDefaultValue() { return F64Bytes(0); }
|
||||
};
|
||||
|
||||
struct DeallocationFacet
|
||||
{
|
||||
typedef F64Bytes value_t;
|
||||
static F64Bytes getDefaultValue() { return F64Bytes(0); }
|
||||
};
|
||||
|
||||
void addSamples(const MemAccumulator& other, EBufferAppendType append_type)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
mAllocations.addSamples(other.mAllocations, append_type);
|
||||
mDeallocations.addSamples(other.mDeallocations, append_type);
|
||||
|
||||
if (append_type == SEQUENTIAL)
|
||||
{
|
||||
mSize.addSamples(other.mSize, SEQUENTIAL);
|
||||
}
|
||||
else
|
||||
{
|
||||
F64 allocation_delta(other.mAllocations.getSum() - other.mDeallocations.getSum());
|
||||
mSize.sample(mSize.hasValue()
|
||||
? mSize.getLastValue() + allocation_delta
|
||||
: allocation_delta);
|
||||
}
|
||||
}
|
||||
|
||||
void reset(const MemAccumulator* other)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
mSize.reset(other ? &other->mSize : NULL);
|
||||
mAllocations.reset(other ? &other->mAllocations : NULL);
|
||||
mDeallocations.reset(other ? &other->mDeallocations : NULL);
|
||||
}
|
||||
|
||||
void sync(F64SecondsImplicit time_stamp)
|
||||
{
|
||||
mSize.sync(time_stamp);
|
||||
}
|
||||
|
||||
bool hasValue() const { return mSize.hasValue(); }
|
||||
|
||||
SampleAccumulator mSize;
|
||||
EventAccumulator mAllocations;
|
||||
CountAccumulator mDeallocations;
|
||||
};
|
||||
|
||||
struct AccumulatorBufferGroup : public LLRefCount
|
||||
{
|
||||
AccumulatorBufferGroup();
|
||||
|
|
@ -607,9 +547,7 @@ namespace LLTrace
|
|||
AccumulatorBuffer<SampleAccumulator> mSamples;
|
||||
AccumulatorBuffer<EventAccumulator> mEvents;
|
||||
AccumulatorBuffer<TimeBlockAccumulator> mStackTimers;
|
||||
AccumulatorBuffer<MemAccumulator> mMemStats;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // LL_LLTRACEACCUMULATORS_H
|
||||
|
||||
|
|
|
|||
|
|
@ -1,24 +1,24 @@
|
|||
/**
|
||||
/**
|
||||
* @file lltracesampler.cpp
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2012, 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$
|
||||
*/
|
||||
|
|
@ -32,7 +32,7 @@
|
|||
#include "lltracethreadrecorder.h"
|
||||
#include "llthread.h"
|
||||
|
||||
inline F64 lerp(F64 a, F64 b, F64 u)
|
||||
inline F64 lerp(F64 a, F64 b, F64 u)
|
||||
{
|
||||
return a + ((b - a) * u);
|
||||
}
|
||||
|
|
@ -40,34 +40,29 @@ inline F64 lerp(F64 a, F64 b, F64 u)
|
|||
namespace LLTrace
|
||||
{
|
||||
|
||||
extern MemStatHandle gTraceMemStat;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// Recording
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
Recording::Recording(EPlayState state)
|
||||
Recording::Recording(EPlayState state)
|
||||
: mElapsedSeconds(0),
|
||||
mActiveBuffers(NULL)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
claim_alloc(gTraceMemStat, this);
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
mBuffers = new AccumulatorBufferGroup();
|
||||
claim_alloc(gTraceMemStat, mBuffers);
|
||||
setPlayState(state);
|
||||
}
|
||||
|
||||
Recording::Recording( const Recording& other )
|
||||
: mActiveBuffers(NULL)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
claim_alloc(gTraceMemStat, this);
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
*this = other;
|
||||
}
|
||||
|
||||
Recording& Recording::operator = (const Recording& other)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
// this will allow us to seamlessly start without affecting any data we've acquired from other
|
||||
setPlayState(PAUSED);
|
||||
|
||||
|
|
@ -85,14 +80,11 @@ Recording& Recording::operator = (const Recording& other)
|
|||
return *this;
|
||||
}
|
||||
|
||||
|
||||
Recording::~Recording()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
disclaim_alloc(gTraceMemStat, this);
|
||||
disclaim_alloc(gTraceMemStat, mBuffers);
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
|
||||
// allow recording destruction without thread recorder running,
|
||||
// allow recording destruction without thread recorder running,
|
||||
// otherwise thread shutdown could crash if a recording outlives the thread recorder
|
||||
// besides, recording construction and destruction is fine without a recorder...just don't attempt to start one
|
||||
if (isStarted() && LLTrace::get_thread_recorder() != NULL)
|
||||
|
|
@ -107,14 +99,14 @@ void Recording::update()
|
|||
#if LL_TRACE_ENABLED
|
||||
if (isStarted())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
mElapsedSeconds += mSamplingTimer.getElapsedTimeF64();
|
||||
|
||||
// must have
|
||||
llassert(mActiveBuffers != NULL
|
||||
// must have
|
||||
llassert(mActiveBuffers != NULL
|
||||
&& LLTrace::get_thread_recorder() != NULL);
|
||||
|
||||
if(!mActiveBuffers->isCurrent() && LLTrace::get_thread_recorder() != NULL)
|
||||
if (!mActiveBuffers->isCurrent() && LLTrace::get_thread_recorder() != NULL)
|
||||
{
|
||||
AccumulatorBufferGroup* buffers = mBuffers.write();
|
||||
LLTrace::get_thread_recorder()->deactivate(buffers);
|
||||
|
|
@ -128,7 +120,7 @@ void Recording::update()
|
|||
|
||||
void Recording::handleReset()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
#if LL_TRACE_ENABLED
|
||||
mBuffers.write()->reset();
|
||||
|
||||
|
|
@ -139,7 +131,7 @@ void Recording::handleReset()
|
|||
|
||||
void Recording::handleStart()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
#if LL_TRACE_ENABLED
|
||||
mSamplingTimer.reset();
|
||||
mBuffers.setStayUnique(true);
|
||||
|
|
@ -151,7 +143,7 @@ void Recording::handleStart()
|
|||
|
||||
void Recording::handleStop()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
#if LL_TRACE_ENABLED
|
||||
mElapsedSeconds += mSamplingTimer.getElapsedTimeF64();
|
||||
// must have thread recorder running on this thread
|
||||
|
|
@ -204,7 +196,6 @@ F64Seconds Recording::getSum(const StatType<TimeBlockAccumulator::SelfTimeFacet>
|
|||
return F64Seconds(((F64)(accumulator.mSelfTimeCounter) + (F64)(active_accumulator ? active_accumulator->mSelfTimeCounter : 0)) / (F64)LLTrace::BlockTimer::countsPerSecond());
|
||||
}
|
||||
|
||||
|
||||
S32 Recording::getSum(const StatType<TimeBlockAccumulator::CallCountFacet>& stat)
|
||||
{
|
||||
update();
|
||||
|
|
@ -219,7 +210,7 @@ F64Seconds Recording::getPerSec(const StatType<TimeBlockAccumulator>& stat)
|
|||
const TimeBlockAccumulator& accumulator = mBuffers->mStackTimers[stat.getIndex()];
|
||||
const TimeBlockAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mStackTimers[stat.getIndex()] : NULL;
|
||||
|
||||
return F64Seconds((F64)(accumulator.mTotalTimeCounter + (active_accumulator ? active_accumulator->mTotalTimeCounter : 0))
|
||||
return F64Seconds((F64)(accumulator.mTotalTimeCounter + (active_accumulator ? active_accumulator->mTotalTimeCounter : 0))
|
||||
/ ((F64)LLTrace::BlockTimer::countsPerSecond() * mElapsedSeconds.value()));
|
||||
}
|
||||
|
||||
|
|
@ -241,144 +232,9 @@ F32 Recording::getPerSec(const StatType<TimeBlockAccumulator::CallCountFacet>& s
|
|||
return (F32)(accumulator.mCalls + (active_accumulator ? active_accumulator->mCalls : 0)) / mElapsedSeconds.value();
|
||||
}
|
||||
|
||||
bool Recording::hasValue(const StatType<MemAccumulator>& stat)
|
||||
{
|
||||
update();
|
||||
const MemAccumulator& accumulator = mBuffers->mMemStats[stat.getIndex()];
|
||||
const MemAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mMemStats[stat.getIndex()] : NULL;
|
||||
return accumulator.mSize.hasValue() || (active_accumulator && active_accumulator->mSize.hasValue() ? active_accumulator->mSize.hasValue() : false);
|
||||
}
|
||||
|
||||
F64Kilobytes Recording::getMin(const StatType<MemAccumulator>& stat)
|
||||
{
|
||||
update();
|
||||
const MemAccumulator& accumulator = mBuffers->mMemStats[stat.getIndex()];
|
||||
const MemAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mMemStats[stat.getIndex()] : NULL;
|
||||
return F64Bytes(llmin(accumulator.mSize.getMin(), (active_accumulator && active_accumulator->mSize.hasValue() ? active_accumulator->mSize.getMin() : F32_MAX)));
|
||||
}
|
||||
|
||||
F64Kilobytes Recording::getMean(const StatType<MemAccumulator>& stat)
|
||||
{
|
||||
update();
|
||||
const MemAccumulator& accumulator = mBuffers->mMemStats[stat.getIndex()];
|
||||
const MemAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mMemStats[stat.getIndex()] : NULL;
|
||||
|
||||
if (active_accumulator && active_accumulator->mSize.hasValue())
|
||||
{
|
||||
F32 t = 0.0f;
|
||||
S32 div = accumulator.mSize.getSampleCount() + active_accumulator->mSize.getSampleCount();
|
||||
if (div > 0)
|
||||
{
|
||||
t = active_accumulator->mSize.getSampleCount() / div;
|
||||
}
|
||||
return F64Bytes(lerp(accumulator.mSize.getMean(), active_accumulator->mSize.getMean(), t));
|
||||
}
|
||||
else
|
||||
{
|
||||
return F64Bytes(accumulator.mSize.getMean());
|
||||
}
|
||||
}
|
||||
|
||||
F64Kilobytes Recording::getMax(const StatType<MemAccumulator>& stat)
|
||||
{
|
||||
update();
|
||||
const MemAccumulator& accumulator = mBuffers->mMemStats[stat.getIndex()];
|
||||
const MemAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mMemStats[stat.getIndex()] : NULL;
|
||||
return F64Bytes(llmax(accumulator.mSize.getMax(), active_accumulator && active_accumulator->mSize.hasValue() ? active_accumulator->mSize.getMax() : F32_MIN));
|
||||
}
|
||||
|
||||
F64Kilobytes Recording::getStandardDeviation(const StatType<MemAccumulator>& stat)
|
||||
{
|
||||
update();
|
||||
const MemAccumulator& accumulator = mBuffers->mMemStats[stat.getIndex()];
|
||||
const MemAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mMemStats[stat.getIndex()] : NULL;
|
||||
if (active_accumulator && active_accumulator->hasValue())
|
||||
{
|
||||
F64 sum_of_squares = SampleAccumulator::mergeSumsOfSquares(accumulator.mSize, active_accumulator->mSize);
|
||||
return F64Bytes(sqrtf(sum_of_squares / (accumulator.mSize.getSamplingTime().value() + active_accumulator->mSize.getSamplingTime().value())));
|
||||
}
|
||||
else
|
||||
{
|
||||
return F64Bytes(accumulator.mSize.getStandardDeviation());
|
||||
}
|
||||
}
|
||||
|
||||
F64Kilobytes Recording::getLastValue(const StatType<MemAccumulator>& stat)
|
||||
{
|
||||
update();
|
||||
const MemAccumulator& accumulator = mBuffers->mMemStats[stat.getIndex()];
|
||||
const MemAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mMemStats[stat.getIndex()] : NULL;
|
||||
return F64Bytes(active_accumulator ? active_accumulator->mSize.getLastValue() : accumulator.mSize.getLastValue());
|
||||
}
|
||||
|
||||
bool Recording::hasValue(const StatType<MemAccumulator::AllocationFacet>& stat)
|
||||
{
|
||||
update();
|
||||
const MemAccumulator& accumulator = mBuffers->mMemStats[stat.getIndex()];
|
||||
const MemAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mMemStats[stat.getIndex()] : NULL;
|
||||
return accumulator.mAllocations.hasValue() || (active_accumulator ? active_accumulator->mAllocations.hasValue() : false);
|
||||
}
|
||||
|
||||
F64Kilobytes Recording::getSum(const StatType<MemAccumulator::AllocationFacet>& stat)
|
||||
{
|
||||
update();
|
||||
const MemAccumulator& accumulator = mBuffers->mMemStats[stat.getIndex()];
|
||||
const MemAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mMemStats[stat.getIndex()] : NULL;
|
||||
return F64Bytes(accumulator.mAllocations.getSum() + (active_accumulator ? active_accumulator->mAllocations.getSum() : 0));
|
||||
}
|
||||
|
||||
F64Kilobytes Recording::getPerSec(const StatType<MemAccumulator::AllocationFacet>& stat)
|
||||
{
|
||||
update();
|
||||
const MemAccumulator& accumulator = mBuffers->mMemStats[stat.getIndex()];
|
||||
const MemAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mMemStats[stat.getIndex()] : NULL;
|
||||
return F64Bytes((accumulator.mAllocations.getSum() + (active_accumulator ? active_accumulator->mAllocations.getSum() : 0)) / mElapsedSeconds.value());
|
||||
}
|
||||
|
||||
S32 Recording::getSampleCount(const StatType<MemAccumulator::AllocationFacet>& stat)
|
||||
{
|
||||
update();
|
||||
const MemAccumulator& accumulator = mBuffers->mMemStats[stat.getIndex()];
|
||||
const MemAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mMemStats[stat.getIndex()] : NULL;
|
||||
return accumulator.mAllocations.getSampleCount() + (active_accumulator ? active_accumulator->mAllocations.getSampleCount() : 0);
|
||||
}
|
||||
|
||||
bool Recording::hasValue(const StatType<MemAccumulator::DeallocationFacet>& stat)
|
||||
{
|
||||
update();
|
||||
const MemAccumulator& accumulator = mBuffers->mMemStats[stat.getIndex()];
|
||||
const MemAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mMemStats[stat.getIndex()] : NULL;
|
||||
return accumulator.mDeallocations.hasValue() || (active_accumulator ? active_accumulator->mDeallocations.hasValue() : false);
|
||||
}
|
||||
|
||||
|
||||
F64Kilobytes Recording::getSum(const StatType<MemAccumulator::DeallocationFacet>& stat)
|
||||
{
|
||||
update();
|
||||
const MemAccumulator& accumulator = mBuffers->mMemStats[stat.getIndex()];
|
||||
const MemAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mMemStats[stat.getIndex()] : NULL;
|
||||
return F64Bytes(accumulator.mDeallocations.getSum() + (active_accumulator ? active_accumulator->mDeallocations.getSum() : 0));
|
||||
}
|
||||
|
||||
F64Kilobytes Recording::getPerSec(const StatType<MemAccumulator::DeallocationFacet>& stat)
|
||||
{
|
||||
update();
|
||||
const MemAccumulator& accumulator = mBuffers->mMemStats[stat.getIndex()];
|
||||
const MemAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mMemStats[stat.getIndex()] : NULL;
|
||||
return F64Bytes((accumulator.mDeallocations.getSum() + (active_accumulator ? active_accumulator->mDeallocations.getSum() : 0)) / mElapsedSeconds.value());
|
||||
}
|
||||
|
||||
S32 Recording::getSampleCount(const StatType<MemAccumulator::DeallocationFacet>& stat)
|
||||
{
|
||||
update();
|
||||
const MemAccumulator& accumulator = mBuffers->mMemStats[stat.getIndex()];
|
||||
const MemAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mMemStats[stat.getIndex()] : NULL;
|
||||
return accumulator.mDeallocations.getSampleCount() + (active_accumulator ? active_accumulator->mDeallocations.getSampleCount() : 0);
|
||||
}
|
||||
|
||||
bool Recording::hasValue(const StatType<CountAccumulator>& stat)
|
||||
{
|
||||
update();
|
||||
update();
|
||||
const CountAccumulator& accumulator = mBuffers->mCounts[stat.getIndex()];
|
||||
const CountAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mCounts[stat.getIndex()] : NULL;
|
||||
return accumulator.hasValue() || (active_accumulator ? active_accumulator->hasValue() : false);
|
||||
|
|
@ -386,7 +242,7 @@ bool Recording::hasValue(const StatType<CountAccumulator>& stat)
|
|||
|
||||
F64 Recording::getSum(const StatType<CountAccumulator>& stat)
|
||||
{
|
||||
update();
|
||||
update();
|
||||
const CountAccumulator& accumulator = mBuffers->mCounts[stat.getIndex()];
|
||||
const CountAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mCounts[stat.getIndex()] : NULL;
|
||||
return accumulator.getSum() + (active_accumulator ? active_accumulator->getSum() : 0);
|
||||
|
|
@ -394,7 +250,7 @@ F64 Recording::getSum(const StatType<CountAccumulator>& stat)
|
|||
|
||||
F64 Recording::getPerSec( const StatType<CountAccumulator>& stat )
|
||||
{
|
||||
update();
|
||||
update();
|
||||
const CountAccumulator& accumulator = mBuffers->mCounts[stat.getIndex()];
|
||||
const CountAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mCounts[stat.getIndex()] : NULL;
|
||||
F64 sum = accumulator.getSum() + (active_accumulator ? active_accumulator->getSum() : 0);
|
||||
|
|
@ -403,7 +259,7 @@ F64 Recording::getPerSec( const StatType<CountAccumulator>& stat )
|
|||
|
||||
S32 Recording::getSampleCount( const StatType<CountAccumulator>& stat )
|
||||
{
|
||||
update();
|
||||
update();
|
||||
const CountAccumulator& accumulator = mBuffers->mCounts[stat.getIndex()];
|
||||
const CountAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mCounts[stat.getIndex()] : NULL;
|
||||
return accumulator.getSampleCount() + (active_accumulator ? active_accumulator->getSampleCount() : 0);
|
||||
|
|
@ -411,7 +267,7 @@ S32 Recording::getSampleCount( const StatType<CountAccumulator>& stat )
|
|||
|
||||
bool Recording::hasValue(const StatType<SampleAccumulator>& stat)
|
||||
{
|
||||
update();
|
||||
update();
|
||||
const SampleAccumulator& accumulator = mBuffers->mSamples[stat.getIndex()];
|
||||
const SampleAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mSamples[stat.getIndex()] : NULL;
|
||||
return accumulator.hasValue() || (active_accumulator && active_accumulator->hasValue());
|
||||
|
|
@ -419,7 +275,7 @@ bool Recording::hasValue(const StatType<SampleAccumulator>& stat)
|
|||
|
||||
F64 Recording::getMin( const StatType<SampleAccumulator>& stat )
|
||||
{
|
||||
update();
|
||||
update();
|
||||
const SampleAccumulator& accumulator = mBuffers->mSamples[stat.getIndex()];
|
||||
const SampleAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mSamples[stat.getIndex()] : NULL;
|
||||
return llmin(accumulator.getMin(), active_accumulator && active_accumulator->hasValue() ? active_accumulator->getMin() : F32_MAX);
|
||||
|
|
@ -427,7 +283,7 @@ F64 Recording::getMin( const StatType<SampleAccumulator>& stat )
|
|||
|
||||
F64 Recording::getMax( const StatType<SampleAccumulator>& stat )
|
||||
{
|
||||
update();
|
||||
update();
|
||||
const SampleAccumulator& accumulator = mBuffers->mSamples[stat.getIndex()];
|
||||
const SampleAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mSamples[stat.getIndex()] : NULL;
|
||||
return llmax(accumulator.getMax(), active_accumulator && active_accumulator->hasValue() ? active_accumulator->getMax() : F32_MIN);
|
||||
|
|
@ -435,17 +291,17 @@ F64 Recording::getMax( const StatType<SampleAccumulator>& stat )
|
|||
|
||||
F64 Recording::getMean( const StatType<SampleAccumulator>& stat )
|
||||
{
|
||||
update();
|
||||
update();
|
||||
const SampleAccumulator& accumulator = mBuffers->mSamples[stat.getIndex()];
|
||||
const SampleAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mSamples[stat.getIndex()] : NULL;
|
||||
if (active_accumulator && active_accumulator->hasValue())
|
||||
{
|
||||
F32 t = 0.0f;
|
||||
S32 div = accumulator.getSampleCount() + active_accumulator->getSampleCount();
|
||||
if (div > 0)
|
||||
{
|
||||
t = active_accumulator->getSampleCount() / div;
|
||||
}
|
||||
F32 t = 0.0f;
|
||||
S32 div = accumulator.getSampleCount() + active_accumulator->getSampleCount();
|
||||
if (div > 0)
|
||||
{
|
||||
t = active_accumulator->getSampleCount() / div;
|
||||
}
|
||||
return lerp(accumulator.getMean(), active_accumulator->getMean(), t);
|
||||
}
|
||||
else
|
||||
|
|
@ -456,7 +312,7 @@ F64 Recording::getMean( const StatType<SampleAccumulator>& stat )
|
|||
|
||||
F64 Recording::getStandardDeviation( const StatType<SampleAccumulator>& stat )
|
||||
{
|
||||
update();
|
||||
update();
|
||||
const SampleAccumulator& accumulator = mBuffers->mSamples[stat.getIndex()];
|
||||
const SampleAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mSamples[stat.getIndex()] : NULL;
|
||||
|
||||
|
|
@ -473,7 +329,7 @@ F64 Recording::getStandardDeviation( const StatType<SampleAccumulator>& stat )
|
|||
|
||||
F64 Recording::getLastValue( const StatType<SampleAccumulator>& stat )
|
||||
{
|
||||
update();
|
||||
update();
|
||||
const SampleAccumulator& accumulator = mBuffers->mSamples[stat.getIndex()];
|
||||
const SampleAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mSamples[stat.getIndex()] : NULL;
|
||||
return (active_accumulator && active_accumulator->hasValue() ? active_accumulator->getLastValue() : accumulator.getLastValue());
|
||||
|
|
@ -481,7 +337,7 @@ F64 Recording::getLastValue( const StatType<SampleAccumulator>& stat )
|
|||
|
||||
S32 Recording::getSampleCount( const StatType<SampleAccumulator>& stat )
|
||||
{
|
||||
update();
|
||||
update();
|
||||
const SampleAccumulator& accumulator = mBuffers->mSamples[stat.getIndex()];
|
||||
const SampleAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mSamples[stat.getIndex()] : NULL;
|
||||
return accumulator.getSampleCount() + (active_accumulator && active_accumulator->hasValue() ? active_accumulator->getSampleCount() : 0);
|
||||
|
|
@ -489,7 +345,7 @@ S32 Recording::getSampleCount( const StatType<SampleAccumulator>& stat )
|
|||
|
||||
bool Recording::hasValue(const StatType<EventAccumulator>& stat)
|
||||
{
|
||||
update();
|
||||
update();
|
||||
const EventAccumulator& accumulator = mBuffers->mEvents[stat.getIndex()];
|
||||
const EventAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mEvents[stat.getIndex()] : NULL;
|
||||
return accumulator.hasValue() || (active_accumulator && active_accumulator->hasValue());
|
||||
|
|
@ -497,7 +353,7 @@ bool Recording::hasValue(const StatType<EventAccumulator>& stat)
|
|||
|
||||
F64 Recording::getSum( const StatType<EventAccumulator>& stat)
|
||||
{
|
||||
update();
|
||||
update();
|
||||
const EventAccumulator& accumulator = mBuffers->mEvents[stat.getIndex()];
|
||||
const EventAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mEvents[stat.getIndex()] : NULL;
|
||||
return (F64)(accumulator.getSum() + (active_accumulator && active_accumulator->hasValue() ? active_accumulator->getSum() : 0));
|
||||
|
|
@ -505,7 +361,7 @@ F64 Recording::getSum( const StatType<EventAccumulator>& stat)
|
|||
|
||||
F64 Recording::getMin( const StatType<EventAccumulator>& stat )
|
||||
{
|
||||
update();
|
||||
update();
|
||||
const EventAccumulator& accumulator = mBuffers->mEvents[stat.getIndex()];
|
||||
const EventAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mEvents[stat.getIndex()] : NULL;
|
||||
return llmin(accumulator.getMin(), active_accumulator && active_accumulator->hasValue() ? active_accumulator->getMin() : F32_MAX);
|
||||
|
|
@ -513,7 +369,7 @@ F64 Recording::getMin( const StatType<EventAccumulator>& stat )
|
|||
|
||||
F64 Recording::getMax( const StatType<EventAccumulator>& stat )
|
||||
{
|
||||
update();
|
||||
update();
|
||||
const EventAccumulator& accumulator = mBuffers->mEvents[stat.getIndex()];
|
||||
const EventAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mEvents[stat.getIndex()] : NULL;
|
||||
return llmax(accumulator.getMax(), active_accumulator && active_accumulator->hasValue() ? active_accumulator->getMax() : F32_MIN);
|
||||
|
|
@ -521,17 +377,17 @@ F64 Recording::getMax( const StatType<EventAccumulator>& stat )
|
|||
|
||||
F64 Recording::getMean( const StatType<EventAccumulator>& stat )
|
||||
{
|
||||
update();
|
||||
update();
|
||||
const EventAccumulator& accumulator = mBuffers->mEvents[stat.getIndex()];
|
||||
const EventAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mEvents[stat.getIndex()] : NULL;
|
||||
if (active_accumulator && active_accumulator->hasValue())
|
||||
{
|
||||
F32 t = 0.0f;
|
||||
S32 div = accumulator.getSampleCount() + active_accumulator->getSampleCount();
|
||||
if (div > 0)
|
||||
{
|
||||
t = active_accumulator->getSampleCount() / div;
|
||||
}
|
||||
S32 div = accumulator.getSampleCount() + active_accumulator->getSampleCount();
|
||||
if (div > 0)
|
||||
{
|
||||
t = active_accumulator->getSampleCount() / div;
|
||||
}
|
||||
return lerp(accumulator.getMean(), active_accumulator->getMean(), t);
|
||||
}
|
||||
else
|
||||
|
|
@ -542,7 +398,7 @@ F64 Recording::getMean( const StatType<EventAccumulator>& stat )
|
|||
|
||||
F64 Recording::getStandardDeviation( const StatType<EventAccumulator>& stat )
|
||||
{
|
||||
update();
|
||||
update();
|
||||
const EventAccumulator& accumulator = mBuffers->mEvents[stat.getIndex()];
|
||||
const EventAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mEvents[stat.getIndex()] : NULL;
|
||||
|
||||
|
|
@ -559,7 +415,7 @@ F64 Recording::getStandardDeviation( const StatType<EventAccumulator>& stat )
|
|||
|
||||
F64 Recording::getLastValue( const StatType<EventAccumulator>& stat )
|
||||
{
|
||||
update();
|
||||
update();
|
||||
const EventAccumulator& accumulator = mBuffers->mEvents[stat.getIndex()];
|
||||
const EventAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mEvents[stat.getIndex()] : NULL;
|
||||
return active_accumulator ? active_accumulator->getLastValue() : accumulator.getLastValue();
|
||||
|
|
@ -567,7 +423,7 @@ F64 Recording::getLastValue( const StatType<EventAccumulator>& stat )
|
|||
|
||||
S32 Recording::getSampleCount( const StatType<EventAccumulator>& stat )
|
||||
{
|
||||
update();
|
||||
update();
|
||||
const EventAccumulator& accumulator = mBuffers->mEvents[stat.getIndex()];
|
||||
const EventAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mEvents[stat.getIndex()] : NULL;
|
||||
return accumulator.getSampleCount() + (active_accumulator ? active_accumulator->getSampleCount() : 0);
|
||||
|
|
@ -577,7 +433,7 @@ S32 Recording::getSampleCount( const StatType<EventAccumulator>& stat )
|
|||
// PeriodicRecording
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
PeriodicRecording::PeriodicRecording( size_t num_periods, EPlayState state)
|
||||
PeriodicRecording::PeriodicRecording( size_t num_periods, EPlayState state)
|
||||
: mAutoResize(num_periods == 0),
|
||||
mCurPeriod(0),
|
||||
mNumRecordedPeriods(0),
|
||||
|
|
@ -585,15 +441,13 @@ PeriodicRecording::PeriodicRecording( size_t num_periods, EPlayState state)
|
|||
// code in several methods.
|
||||
mRecordingPeriods(num_periods ? num_periods : 1)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
setPlayState(state);
|
||||
claim_alloc(gTraceMemStat, this);
|
||||
}
|
||||
|
||||
PeriodicRecording::~PeriodicRecording()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
disclaim_alloc(gTraceMemStat, this);
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
}
|
||||
|
||||
void PeriodicRecording::nextPeriod()
|
||||
|
|
@ -615,12 +469,11 @@ void PeriodicRecording::nextPeriod()
|
|||
|
||||
void PeriodicRecording::appendRecording(Recording& recording)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
getCurRecording().appendRecording(recording);
|
||||
nextPeriod();
|
||||
}
|
||||
|
||||
|
||||
void PeriodicRecording::appendPeriodicRecording( PeriodicRecording& other )
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
|
|
@ -693,16 +546,14 @@ F64Seconds PeriodicRecording::getDuration() const
|
|||
return duration;
|
||||
}
|
||||
|
||||
|
||||
LLTrace::Recording PeriodicRecording::snapshotCurRecording() const
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
Recording recording_copy(getCurRecording());
|
||||
recording_copy.stop();
|
||||
return recording_copy;
|
||||
}
|
||||
|
||||
|
||||
Recording& PeriodicRecording::getLastRecording()
|
||||
{
|
||||
return getPrevRecording(1);
|
||||
|
|
@ -737,19 +588,19 @@ const Recording& PeriodicRecording::getPrevRecording( size_t offset ) const
|
|||
|
||||
void PeriodicRecording::handleStart()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
getCurRecording().start();
|
||||
}
|
||||
|
||||
void PeriodicRecording::handleStop()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
getCurRecording().pause();
|
||||
}
|
||||
|
||||
void PeriodicRecording::handleReset()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
getCurRecording().stop();
|
||||
|
||||
if (mAutoResize)
|
||||
|
|
@ -771,13 +622,13 @@ void PeriodicRecording::handleReset()
|
|||
|
||||
void PeriodicRecording::handleSplitTo(PeriodicRecording& other)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
getCurRecording().splitTo(other.getCurRecording());
|
||||
}
|
||||
|
||||
F64 PeriodicRecording::getPeriodMin( const StatType<EventAccumulator>& stat, size_t num_periods /*= std::numeric_limits<size_t>::max()*/ )
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
||||
bool has_value = false;
|
||||
|
|
@ -792,14 +643,14 @@ F64 PeriodicRecording::getPeriodMin( const StatType<EventAccumulator>& stat, siz
|
|||
}
|
||||
}
|
||||
|
||||
return has_value
|
||||
? min_val
|
||||
return has_value
|
||||
? min_val
|
||||
: NaN;
|
||||
}
|
||||
|
||||
F64 PeriodicRecording::getPeriodMax( const StatType<EventAccumulator>& stat, size_t num_periods /*= std::numeric_limits<size_t>::max()*/ )
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
||||
bool has_value = false;
|
||||
|
|
@ -814,15 +665,15 @@ F64 PeriodicRecording::getPeriodMax( const StatType<EventAccumulator>& stat, siz
|
|||
}
|
||||
}
|
||||
|
||||
return has_value
|
||||
? max_val
|
||||
return has_value
|
||||
? max_val
|
||||
: NaN;
|
||||
}
|
||||
|
||||
// calculates means using aggregates per period
|
||||
F64 PeriodicRecording::getPeriodMean( const StatType<EventAccumulator>& stat, size_t num_periods /*= std::numeric_limits<size_t>::max()*/ )
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
||||
F64 mean = 0;
|
||||
|
|
@ -838,14 +689,14 @@ F64 PeriodicRecording::getPeriodMean( const StatType<EventAccumulator>& stat, si
|
|||
}
|
||||
}
|
||||
|
||||
return valid_period_count
|
||||
return valid_period_count
|
||||
? mean / (F64)valid_period_count
|
||||
: NaN;
|
||||
}
|
||||
|
||||
F64 PeriodicRecording::getPeriodStandardDeviation( const StatType<EventAccumulator>& stat, size_t num_periods /*= std::numeric_limits<size_t>::max()*/ )
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
||||
F64 period_mean = getPeriodMean(stat, num_periods);
|
||||
|
|
@ -870,7 +721,7 @@ F64 PeriodicRecording::getPeriodStandardDeviation( const StatType<EventAccumulat
|
|||
|
||||
F64 PeriodicRecording::getPeriodMin( const StatType<SampleAccumulator>& stat, size_t num_periods /*= std::numeric_limits<size_t>::max()*/ )
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
||||
bool has_value = false;
|
||||
|
|
@ -885,14 +736,14 @@ F64 PeriodicRecording::getPeriodMin( const StatType<SampleAccumulator>& stat, si
|
|||
}
|
||||
}
|
||||
|
||||
return has_value
|
||||
? min_val
|
||||
return has_value
|
||||
? min_val
|
||||
: NaN;
|
||||
}
|
||||
|
||||
F64 PeriodicRecording::getPeriodMax(const StatType<SampleAccumulator>& stat, size_t num_periods /*= std::numeric_limits<size_t>::max()*/)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
||||
bool has_value = false;
|
||||
|
|
@ -907,15 +758,15 @@ F64 PeriodicRecording::getPeriodMax(const StatType<SampleAccumulator>& stat, siz
|
|||
}
|
||||
}
|
||||
|
||||
return has_value
|
||||
? max_val
|
||||
return has_value
|
||||
? max_val
|
||||
: NaN;
|
||||
}
|
||||
|
||||
|
||||
F64 PeriodicRecording::getPeriodMean( const StatType<SampleAccumulator>& stat, size_t num_periods /*= std::numeric_limits<size_t>::max()*/ )
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
||||
S32 valid_period_count = 0;
|
||||
|
|
@ -938,7 +789,7 @@ F64 PeriodicRecording::getPeriodMean( const StatType<SampleAccumulator>& stat, s
|
|||
|
||||
F64 PeriodicRecording::getPeriodMedian( const StatType<SampleAccumulator>& stat, size_t num_periods /*= std::numeric_limits<size_t>::max()*/ )
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
||||
std::vector<F64> buf;
|
||||
|
|
@ -964,7 +815,7 @@ F64 PeriodicRecording::getPeriodMedian( const StatType<SampleAccumulator>& stat,
|
|||
|
||||
F64 PeriodicRecording::getPeriodStandardDeviation( const StatType<SampleAccumulator>& stat, size_t num_periods /*= std::numeric_limits<size_t>::max()*/ )
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
||||
F64 period_mean = getPeriodMean(stat, num_periods);
|
||||
|
|
@ -987,105 +838,13 @@ F64 PeriodicRecording::getPeriodStandardDeviation( const StatType<SampleAccumula
|
|||
: NaN;
|
||||
}
|
||||
|
||||
|
||||
F64Kilobytes PeriodicRecording::getPeriodMin( const StatType<MemAccumulator>& stat, size_t num_periods /*= std::numeric_limits<size_t>::max()*/ )
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
||||
F64Kilobytes min_val(std::numeric_limits<F64>::max());
|
||||
for (size_t i = 1; i <= num_periods; i++)
|
||||
{
|
||||
Recording& recording = getPrevRecording(i);
|
||||
min_val = llmin(min_val, recording.getMin(stat));
|
||||
}
|
||||
|
||||
return min_val;
|
||||
}
|
||||
|
||||
F64Kilobytes PeriodicRecording::getPeriodMin(const MemStatHandle& stat, size_t num_periods)
|
||||
{
|
||||
return getPeriodMin(static_cast<const StatType<MemAccumulator>&>(stat), num_periods);
|
||||
}
|
||||
|
||||
F64Kilobytes PeriodicRecording::getPeriodMax(const StatType<MemAccumulator>& stat, size_t num_periods /*= std::numeric_limits<size_t>::max()*/)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
||||
F64Kilobytes max_val(0.0);
|
||||
for (size_t i = 1; i <= num_periods; i++)
|
||||
{
|
||||
Recording& recording = getPrevRecording(i);
|
||||
max_val = llmax(max_val, recording.getMax(stat));
|
||||
}
|
||||
|
||||
return max_val;
|
||||
}
|
||||
|
||||
F64Kilobytes PeriodicRecording::getPeriodMax(const MemStatHandle& stat, size_t num_periods)
|
||||
{
|
||||
return getPeriodMax(static_cast<const StatType<MemAccumulator>&>(stat), num_periods);
|
||||
}
|
||||
|
||||
F64Kilobytes PeriodicRecording::getPeriodMean( const StatType<MemAccumulator>& stat, size_t num_periods /*= std::numeric_limits<size_t>::max()*/ )
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
||||
F64Kilobytes mean(0);
|
||||
|
||||
for (size_t i = 1; i <= num_periods; i++)
|
||||
{
|
||||
Recording& recording = getPrevRecording(i);
|
||||
mean += recording.getMean(stat);
|
||||
}
|
||||
|
||||
return mean / F64(num_periods);
|
||||
}
|
||||
|
||||
F64Kilobytes PeriodicRecording::getPeriodMean(const MemStatHandle& stat, size_t num_periods)
|
||||
{
|
||||
return getPeriodMean(static_cast<const StatType<MemAccumulator>&>(stat), num_periods);
|
||||
}
|
||||
|
||||
F64Kilobytes PeriodicRecording::getPeriodStandardDeviation( const StatType<MemAccumulator>& stat, size_t num_periods /*= std::numeric_limits<size_t>::max()*/ )
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
||||
F64Kilobytes period_mean = getPeriodMean(stat, num_periods);
|
||||
S32 valid_period_count = 0;
|
||||
F64 sum_of_squares = 0;
|
||||
|
||||
for (size_t i = 1; i <= num_periods; i++)
|
||||
{
|
||||
Recording& recording = getPrevRecording(i);
|
||||
if (recording.hasValue(stat))
|
||||
{
|
||||
F64Kilobytes delta = recording.getMean(stat) - period_mean;
|
||||
sum_of_squares += delta.value() * delta.value();
|
||||
valid_period_count++;
|
||||
}
|
||||
}
|
||||
|
||||
return F64Kilobytes(valid_period_count
|
||||
? sqrt(sum_of_squares / (F64)valid_period_count)
|
||||
: NaN);
|
||||
}
|
||||
|
||||
F64Kilobytes PeriodicRecording::getPeriodStandardDeviation(const MemStatHandle& stat, size_t num_periods)
|
||||
{
|
||||
return getPeriodStandardDeviation(static_cast<const StatType<MemAccumulator>&>(stat), num_periods);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// ExtendableRecording
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
void ExtendableRecording::extend()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
// push the data back to accepted recording
|
||||
mAcceptedRecording.appendRecording(mPotentialRecording);
|
||||
// flush data, so we can start from scratch
|
||||
|
|
@ -1094,76 +853,72 @@ void ExtendableRecording::extend()
|
|||
|
||||
void ExtendableRecording::handleStart()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
mPotentialRecording.start();
|
||||
}
|
||||
|
||||
void ExtendableRecording::handleStop()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
mPotentialRecording.pause();
|
||||
}
|
||||
|
||||
void ExtendableRecording::handleReset()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
mAcceptedRecording.reset();
|
||||
mPotentialRecording.reset();
|
||||
}
|
||||
|
||||
void ExtendableRecording::handleSplitTo(ExtendableRecording& other)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
mPotentialRecording.splitTo(other.mPotentialRecording);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// ExtendablePeriodicRecording
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
ExtendablePeriodicRecording::ExtendablePeriodicRecording()
|
||||
: mAcceptedRecording(0),
|
||||
ExtendablePeriodicRecording::ExtendablePeriodicRecording()
|
||||
: mAcceptedRecording(0),
|
||||
mPotentialRecording(0)
|
||||
{}
|
||||
|
||||
void ExtendablePeriodicRecording::extend()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
// push the data back to accepted recording
|
||||
mAcceptedRecording.appendPeriodicRecording(mPotentialRecording);
|
||||
// flush data, so we can start from scratch
|
||||
mPotentialRecording.reset();
|
||||
}
|
||||
|
||||
|
||||
void ExtendablePeriodicRecording::handleStart()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
mPotentialRecording.start();
|
||||
}
|
||||
|
||||
void ExtendablePeriodicRecording::handleStop()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
mPotentialRecording.pause();
|
||||
}
|
||||
|
||||
void ExtendablePeriodicRecording::handleReset()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
mAcceptedRecording.reset();
|
||||
mPotentialRecording.reset();
|
||||
}
|
||||
|
||||
void ExtendablePeriodicRecording::handleSplitTo(ExtendablePeriodicRecording& other)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
mPotentialRecording.splitTo(other.mPotentialRecording);
|
||||
}
|
||||
|
||||
|
||||
PeriodicRecording& get_frame_recording()
|
||||
{
|
||||
static thread_local PeriodicRecording sRecording(200, PeriodicRecording::STARTED);
|
||||
|
|
@ -1174,7 +929,7 @@ PeriodicRecording& get_frame_recording()
|
|||
|
||||
void LLStopWatchControlsMixinCommon::start()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
switch (mPlayState)
|
||||
{
|
||||
case STOPPED:
|
||||
|
|
@ -1196,7 +951,7 @@ void LLStopWatchControlsMixinCommon::start()
|
|||
|
||||
void LLStopWatchControlsMixinCommon::stop()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
switch (mPlayState)
|
||||
{
|
||||
case STOPPED:
|
||||
|
|
@ -1216,7 +971,7 @@ void LLStopWatchControlsMixinCommon::stop()
|
|||
|
||||
void LLStopWatchControlsMixinCommon::pause()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
switch (mPlayState)
|
||||
{
|
||||
case STOPPED:
|
||||
|
|
@ -1236,7 +991,7 @@ void LLStopWatchControlsMixinCommon::pause()
|
|||
|
||||
void LLStopWatchControlsMixinCommon::unpause()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
switch (mPlayState)
|
||||
{
|
||||
case STOPPED:
|
||||
|
|
@ -1256,7 +1011,7 @@ void LLStopWatchControlsMixinCommon::unpause()
|
|||
|
||||
void LLStopWatchControlsMixinCommon::resume()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
switch (mPlayState)
|
||||
{
|
||||
case STOPPED:
|
||||
|
|
@ -1277,7 +1032,7 @@ void LLStopWatchControlsMixinCommon::resume()
|
|||
|
||||
void LLStopWatchControlsMixinCommon::restart()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
switch (mPlayState)
|
||||
{
|
||||
case STOPPED:
|
||||
|
|
@ -1301,13 +1056,13 @@ void LLStopWatchControlsMixinCommon::restart()
|
|||
|
||||
void LLStopWatchControlsMixinCommon::reset()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
handleReset();
|
||||
}
|
||||
|
||||
void LLStopWatchControlsMixinCommon::setPlayState( EPlayState state )
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
switch(state)
|
||||
{
|
||||
case STOPPED:
|
||||
|
|
|
|||
|
|
@ -1,25 +1,25 @@
|
|||
/**
|
||||
/**
|
||||
* @file lltracerecording.h
|
||||
* @brief Sampling object for collecting runtime statistics originating from lltrace.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2012, 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$
|
||||
*/
|
||||
|
|
@ -112,7 +112,6 @@ private:
|
|||
// atomically stop this object while starting the other
|
||||
// no data can be missed in between stop and start
|
||||
virtual void handleSplitTo(DERIVED& other) {};
|
||||
|
||||
};
|
||||
|
||||
namespace LLTrace
|
||||
|
|
@ -129,8 +128,6 @@ namespace LLTrace
|
|||
template<typename T>
|
||||
class EventStatHandle;
|
||||
|
||||
class MemStatHandle;
|
||||
|
||||
template<typename T>
|
||||
struct RelatedTypes
|
||||
{
|
||||
|
|
@ -152,7 +149,7 @@ namespace LLTrace
|
|||
typedef S32 sum_t;
|
||||
};
|
||||
|
||||
class Recording
|
||||
class Recording
|
||||
: public LLStopWatchControlsMixin<Recording>
|
||||
{
|
||||
public:
|
||||
|
|
@ -182,24 +179,6 @@ namespace LLTrace
|
|||
F64Seconds getPerSec(const StatType<TimeBlockAccumulator::SelfTimeFacet>& stat);
|
||||
F32 getPerSec(const StatType<TimeBlockAccumulator::CallCountFacet>& stat);
|
||||
|
||||
// Memory accessors
|
||||
bool hasValue(const StatType<MemAccumulator>& stat);
|
||||
F64Kilobytes getMin(const StatType<MemAccumulator>& stat);
|
||||
F64Kilobytes getMean(const StatType<MemAccumulator>& stat);
|
||||
F64Kilobytes getMax(const StatType<MemAccumulator>& stat);
|
||||
F64Kilobytes getStandardDeviation(const StatType<MemAccumulator>& stat);
|
||||
F64Kilobytes getLastValue(const StatType<MemAccumulator>& stat);
|
||||
|
||||
bool hasValue(const StatType<MemAccumulator::AllocationFacet>& stat);
|
||||
F64Kilobytes getSum(const StatType<MemAccumulator::AllocationFacet>& stat);
|
||||
F64Kilobytes getPerSec(const StatType<MemAccumulator::AllocationFacet>& stat);
|
||||
S32 getSampleCount(const StatType<MemAccumulator::AllocationFacet>& stat);
|
||||
|
||||
bool hasValue(const StatType<MemAccumulator::DeallocationFacet>& stat);
|
||||
F64Kilobytes getSum(const StatType<MemAccumulator::DeallocationFacet>& stat);
|
||||
F64Kilobytes getPerSec(const StatType<MemAccumulator::DeallocationFacet>& stat);
|
||||
S32 getSampleCount(const StatType<MemAccumulator::DeallocationFacet>& stat);
|
||||
|
||||
// CountStatHandle accessors
|
||||
bool hasValue(const StatType<CountAccumulator>& stat);
|
||||
F64 getSum(const StatType<CountAccumulator>& stat);
|
||||
|
|
@ -318,7 +297,7 @@ namespace LLTrace
|
|||
/*virtual*/ void handleSplitTo(Recording& other);
|
||||
|
||||
// returns data for current thread
|
||||
class ThreadRecorder* getThreadRecorder();
|
||||
class ThreadRecorder* getThreadRecorder();
|
||||
|
||||
LLTimer mSamplingTimer;
|
||||
F64Seconds mElapsedSeconds;
|
||||
|
|
@ -335,10 +314,10 @@ namespace LLTrace
|
|||
~PeriodicRecording();
|
||||
|
||||
void nextPeriod();
|
||||
auto getNumRecordedPeriods()
|
||||
{
|
||||
auto getNumRecordedPeriods()
|
||||
{
|
||||
// current period counts if not active
|
||||
return mNumRecordedPeriods + (isStarted() ? 0 : 1);
|
||||
return mNumRecordedPeriods + (isStarted() ? 0 : 1);
|
||||
}
|
||||
|
||||
F64Seconds getDuration() const;
|
||||
|
|
@ -367,7 +346,7 @@ namespace LLTrace
|
|||
}
|
||||
return num_samples;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// PERIODIC MIN
|
||||
//
|
||||
|
|
@ -376,7 +355,7 @@ namespace LLTrace
|
|||
template <typename T>
|
||||
typename T::value_t getPeriodMin(const StatType<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
||||
bool has_value = false;
|
||||
|
|
@ -391,15 +370,15 @@ namespace LLTrace
|
|||
}
|
||||
}
|
||||
|
||||
return has_value
|
||||
? min_val
|
||||
return has_value
|
||||
? min_val
|
||||
: T::getDefaultValue();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T getPeriodMin(const CountStatHandle<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
return T(getPeriodMin(static_cast<const StatType<CountAccumulator>&>(stat), num_periods));
|
||||
}
|
||||
|
||||
|
|
@ -407,7 +386,7 @@ namespace LLTrace
|
|||
template<typename T>
|
||||
T getPeriodMin(const SampleStatHandle<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
return T(getPeriodMin(static_cast<const StatType<SampleAccumulator>&>(stat), num_periods));
|
||||
}
|
||||
|
||||
|
|
@ -415,17 +394,14 @@ namespace LLTrace
|
|||
template<typename T>
|
||||
T getPeriodMin(const EventStatHandle<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
return T(getPeriodMin(static_cast<const StatType<EventAccumulator>&>(stat), num_periods));
|
||||
}
|
||||
|
||||
F64Kilobytes getPeriodMin(const StatType<MemAccumulator>& stat, size_t num_periods = std::numeric_limits<size_t>::max());
|
||||
F64Kilobytes getPeriodMin(const MemStatHandle& stat, size_t num_periods = std::numeric_limits<size_t>::max());
|
||||
|
||||
template <typename T>
|
||||
typename RelatedTypes<typename T::value_t>::fractional_t getPeriodMinPerSec(const StatType<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
||||
typename RelatedTypes<typename T::value_t>::fractional_t min_val(std::numeric_limits<F64>::max());
|
||||
|
|
@ -440,7 +416,7 @@ namespace LLTrace
|
|||
template<typename T>
|
||||
typename RelatedTypes<T>::fractional_t getPeriodMinPerSec(const CountStatHandle<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
return typename RelatedTypes<T>::fractional_t(getPeriodMinPerSec(static_cast<const StatType<CountAccumulator>&>(stat), num_periods));
|
||||
}
|
||||
|
||||
|
|
@ -452,7 +428,7 @@ namespace LLTrace
|
|||
template <typename T>
|
||||
typename T::value_t getPeriodMax(const StatType<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
||||
bool has_value = false;
|
||||
|
|
@ -467,15 +443,15 @@ namespace LLTrace
|
|||
}
|
||||
}
|
||||
|
||||
return has_value
|
||||
? max_val
|
||||
return has_value
|
||||
? max_val
|
||||
: T::getDefaultValue();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T getPeriodMax(const CountStatHandle<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
return T(getPeriodMax(static_cast<const StatType<CountAccumulator>&>(stat), num_periods));
|
||||
}
|
||||
|
||||
|
|
@ -483,7 +459,7 @@ namespace LLTrace
|
|||
template<typename T>
|
||||
T getPeriodMax(const SampleStatHandle<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
return T(getPeriodMax(static_cast<const StatType<SampleAccumulator>&>(stat), num_periods));
|
||||
}
|
||||
|
||||
|
|
@ -491,17 +467,14 @@ namespace LLTrace
|
|||
template<typename T>
|
||||
T getPeriodMax(const EventStatHandle<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
return T(getPeriodMax(static_cast<const StatType<EventAccumulator>&>(stat), num_periods));
|
||||
}
|
||||
|
||||
F64Kilobytes getPeriodMax(const StatType<MemAccumulator>& stat, size_t num_periods = std::numeric_limits<size_t>::max());
|
||||
F64Kilobytes getPeriodMax(const MemStatHandle& stat, size_t num_periods = std::numeric_limits<size_t>::max());
|
||||
|
||||
template <typename T>
|
||||
typename RelatedTypes<typename T::value_t>::fractional_t getPeriodMaxPerSec(const StatType<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
||||
F64 max_val = std::numeric_limits<F64>::min();
|
||||
|
|
@ -516,7 +489,7 @@ namespace LLTrace
|
|||
template<typename T>
|
||||
typename RelatedTypes<T>::fractional_t getPeriodMaxPerSec(const CountStatHandle<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
return typename RelatedTypes<T>::fractional_t(getPeriodMaxPerSec(static_cast<const StatType<CountAccumulator>&>(stat), num_periods));
|
||||
}
|
||||
|
||||
|
|
@ -528,7 +501,7 @@ namespace LLTrace
|
|||
template <typename T>
|
||||
typename RelatedTypes<typename T::value_t>::fractional_t getPeriodMean(const StatType<T >& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
||||
typename RelatedTypes<typename T::value_t>::fractional_t mean(0);
|
||||
|
|
@ -549,14 +522,14 @@ namespace LLTrace
|
|||
template<typename T>
|
||||
typename RelatedTypes<T>::fractional_t getPeriodMean(const CountStatHandle<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
return typename RelatedTypes<T>::fractional_t(getPeriodMean(static_cast<const StatType<CountAccumulator>&>(stat), num_periods));
|
||||
}
|
||||
F64 getPeriodMean(const StatType<SampleAccumulator>& stat, size_t num_periods = std::numeric_limits<size_t>::max());
|
||||
template<typename T>
|
||||
template<typename T>
|
||||
typename RelatedTypes<T>::fractional_t getPeriodMean(const SampleStatHandle<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
return typename RelatedTypes<T>::fractional_t(getPeriodMean(static_cast<const StatType<SampleAccumulator>&>(stat), num_periods));
|
||||
}
|
||||
|
||||
|
|
@ -564,17 +537,14 @@ namespace LLTrace
|
|||
template<typename T>
|
||||
typename RelatedTypes<T>::fractional_t getPeriodMean(const EventStatHandle<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
return typename RelatedTypes<T>::fractional_t(getPeriodMean(static_cast<const StatType<EventAccumulator>&>(stat), num_periods));
|
||||
}
|
||||
|
||||
F64Kilobytes getPeriodMean(const StatType<MemAccumulator>& stat, size_t num_periods = std::numeric_limits<size_t>::max());
|
||||
F64Kilobytes getPeriodMean(const MemStatHandle& stat, size_t num_periods = std::numeric_limits<size_t>::max());
|
||||
|
||||
template <typename T>
|
||||
typename RelatedTypes<typename T::value_t>::fractional_t getPeriodMeanPerSec(const StatType<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
||||
typename RelatedTypes<typename T::value_t>::fractional_t mean = 0;
|
||||
|
|
@ -596,7 +566,7 @@ namespace LLTrace
|
|||
template<typename T>
|
||||
typename RelatedTypes<T>::fractional_t getPeriodMeanPerSec(const CountStatHandle<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
return typename RelatedTypes<T>::fractional_t(getPeriodMeanPerSec(static_cast<const StatType<CountAccumulator>&>(stat), num_periods));
|
||||
}
|
||||
|
||||
|
|
@ -635,10 +605,10 @@ namespace LLTrace
|
|||
|
||||
F64 getPeriodStandardDeviation(const StatType<SampleAccumulator>& stat, size_t num_periods = std::numeric_limits<size_t>::max());
|
||||
|
||||
template<typename T>
|
||||
template<typename T>
|
||||
typename RelatedTypes<T>::fractional_t getPeriodStandardDeviation(const SampleStatHandle<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
return typename RelatedTypes<T>::fractional_t(getPeriodStandardDeviation(static_cast<const StatType<SampleAccumulator>&>(stat), num_periods));
|
||||
}
|
||||
|
||||
|
|
@ -646,13 +616,10 @@ namespace LLTrace
|
|||
template<typename T>
|
||||
typename RelatedTypes<T>::fractional_t getPeriodStandardDeviation(const EventStatHandle<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
return typename RelatedTypes<T>::fractional_t(getPeriodStandardDeviation(static_cast<const StatType<EventAccumulator>&>(stat), num_periods));
|
||||
}
|
||||
|
||||
F64Kilobytes getPeriodStandardDeviation(const StatType<MemAccumulator>& stat, size_t num_periods = std::numeric_limits<size_t>::max());
|
||||
F64Kilobytes getPeriodStandardDeviation(const MemStatHandle& stat, size_t num_periods = std::numeric_limits<size_t>::max());
|
||||
|
||||
private:
|
||||
// implementation for LLStopWatchControlsMixin
|
||||
/*virtual*/ void handleStart();
|
||||
|
|
@ -731,7 +698,7 @@ namespace LLTrace
|
|||
|
||||
PeriodicRecording& getResults() { return mAcceptedRecording; }
|
||||
const PeriodicRecording& getResults() const {return mAcceptedRecording;}
|
||||
|
||||
|
||||
void nextPeriod() { mPotentialRecording.nextPeriod(); }
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@
|
|||
|
||||
namespace LLTrace
|
||||
{
|
||||
extern MemStatHandle gTraceMemStat;
|
||||
//extern MemStatHandle gTraceMemStat;
|
||||
|
||||
static ThreadRecorder* sMasterThreadRecorder = NULL;
|
||||
|
||||
|
|
@ -81,9 +81,9 @@ void ThreadRecorder::init()
|
|||
|
||||
BlockTimer::getRootTimeBlock().getCurrentAccumulator().mActiveCount = 1;
|
||||
|
||||
claim_alloc(gTraceMemStat, this);
|
||||
claim_alloc(gTraceMemStat, mRootTimer);
|
||||
claim_alloc(gTraceMemStat, sizeof(TimeBlockTreeNode) * mNumTimeBlockTreeNodes);
|
||||
//claim_alloc(gTraceMemStat, this);
|
||||
//claim_alloc(gTraceMemStat, mRootTimer);
|
||||
//claim_alloc(gTraceMemStat, sizeof(TimeBlockTreeNode) * mNumTimeBlockTreeNodes);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -101,9 +101,9 @@ ThreadRecorder::~ThreadRecorder()
|
|||
#if LL_TRACE_ENABLED
|
||||
LLThreadLocalSingletonPointer<BlockTimerStackRecord>::setInstance(NULL);
|
||||
|
||||
disclaim_alloc(gTraceMemStat, this);
|
||||
disclaim_alloc(gTraceMemStat, sizeof(BlockTimer));
|
||||
disclaim_alloc(gTraceMemStat, sizeof(TimeBlockTreeNode) * mNumTimeBlockTreeNodes);
|
||||
//disclaim_alloc(gTraceMemStat, this);
|
||||
//disclaim_alloc(gTraceMemStat, sizeof(BlockTimer));
|
||||
//disclaim_alloc(gTraceMemStat, sizeof(TimeBlockTreeNode) * mNumTimeBlockTreeNodes);
|
||||
|
||||
deactivate(&mThreadRecordingBuffers);
|
||||
|
||||
|
|
|
|||
|
|
@ -46,11 +46,12 @@ namespace tut
|
|||
// the real time required for each push() call. Explicitly increment
|
||||
// the timestamp for each one -- but since we're passing explicit
|
||||
// timestamps, make the queue reorder them.
|
||||
queue.push(Queue::TimeTuple(Queue::Clock::now() + 200ms, "ghi"));
|
||||
auto now{ Queue::Clock::now() };
|
||||
queue.push(Queue::TimeTuple(now + 200ms, "ghi"));
|
||||
// Given the various push() overloads, you have to match the type
|
||||
// exactly: conversions are ambiguous.
|
||||
queue.push("abc"s);
|
||||
queue.push(Queue::Clock::now() + 100ms, "def");
|
||||
queue.push(now + 100ms, "def");
|
||||
queue.close();
|
||||
auto entry = queue.pop();
|
||||
ensure_equals("failed to pop first", std::get<0>(entry), "abc"s);
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ bool LLImageDimensionsInfo::load(const std::string& src_filename,U32 codec)
|
|||
|
||||
if (file_size == 0)
|
||||
{
|
||||
mWarning = "texture_load_empty_file";
|
||||
setLastError("File is empty",src_filename);
|
||||
return false;
|
||||
}
|
||||
|
|
@ -90,6 +91,7 @@ bool LLImageDimensionsInfo::getImageDimensionsBmp()
|
|||
if (signature[0] != 'B' || signature[1] != 'M')
|
||||
{
|
||||
LL_WARNS() << "Not a BMP" << LL_ENDL;
|
||||
mWarning = "texture_load_format_error";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -140,6 +142,7 @@ bool LLImageDimensionsInfo::getImageDimensionsPng()
|
|||
if (memcmp(signature, png_magic, PNG_MAGIC_SIZE) != 0)
|
||||
{
|
||||
LL_WARNS() << "Not a PNG" << LL_ENDL;
|
||||
mWarning = "texture_load_format_error";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -183,6 +186,7 @@ bool LLImageDimensionsInfo::getImageDimensionsJpeg()
|
|||
if (memcmp(signature, jpeg_magic, JPEG_MAGIC_SIZE) != 0)
|
||||
{
|
||||
LL_WARNS() << "Not a JPEG" << LL_ENDL;
|
||||
mWarning = "texture_load_format_error";
|
||||
return false;
|
||||
}
|
||||
fseek(fp, 0, SEEK_SET); // go back to start of the file
|
||||
|
|
|
|||
|
|
@ -55,6 +55,12 @@ public:
|
|||
{
|
||||
return mLastError;
|
||||
}
|
||||
|
||||
const std::string& getWarningName()
|
||||
{
|
||||
return mWarning;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
void clean()
|
||||
|
|
@ -129,6 +135,7 @@ protected:
|
|||
std::string mSrcFilename;
|
||||
|
||||
std::string mLastError;
|
||||
std::string mWarning;
|
||||
|
||||
U8* mData;
|
||||
|
||||
|
|
|
|||
|
|
@ -1040,7 +1040,12 @@ LLModel::weight_list& LLModel::getJointInfluences(const LLVector3& pos)
|
|||
weight_map::iterator iterPos = mSkinWeights.begin();
|
||||
weight_map::iterator iterEnd = mSkinWeights.end();
|
||||
|
||||
llassert(!mSkinWeights.empty());
|
||||
if (mSkinWeights.empty())
|
||||
{
|
||||
// function calls iter->second on all return paths
|
||||
// everything that calls this function should precheck that there is data.
|
||||
LL_ERRS() << "called getJointInfluences with empty weights list" << LL_ENDL;
|
||||
}
|
||||
|
||||
for ( ; iterPos!=iterEnd; ++iterPos )
|
||||
{
|
||||
|
|
@ -1067,11 +1072,16 @@ LLModel::weight_list& LLModel::getJointInfluences(const LLVector3& pos)
|
|||
const F32 epsilon = 1e-5f;
|
||||
weight_map::iterator iter_up = mSkinWeights.lower_bound(pos);
|
||||
weight_map::iterator iter_down = iter_up;
|
||||
if (iter_up != mSkinWeights.end())
|
||||
{
|
||||
iter_down = ++iter_up;
|
||||
}
|
||||
weight_map::iterator best = iter_up;
|
||||
weight_map::iterator best = iter_up;
|
||||
if (iter_up != mSkinWeights.end())
|
||||
{
|
||||
iter_down = ++iter_up;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Assumes that there is at least one element
|
||||
--best;
|
||||
}
|
||||
|
||||
F32 min_dist = (iter->first - pos).magVec();
|
||||
|
||||
|
|
|
|||
|
|
@ -126,12 +126,12 @@ public:
|
|||
|
||||
void setSelected(bool is_selected);
|
||||
|
||||
bool getCollapsible() {return mCollapsible;};
|
||||
bool getCollapsible() { return mCollapsible; };
|
||||
|
||||
void setCollapsible(bool collapsible) {mCollapsible = collapsible;};
|
||||
void setCollapsible(bool collapsible) { mCollapsible = collapsible; };
|
||||
void changeOpenClose(bool is_open);
|
||||
|
||||
void canOpenClose(bool can_open_close) { mCanOpenClose = can_open_close;};
|
||||
void canOpenClose(bool can_open_close) { mCanOpenClose = can_open_close; };
|
||||
bool canOpenClose() const { return mCanOpenClose; };
|
||||
|
||||
virtual BOOL postBuild();
|
||||
|
|
@ -142,8 +142,8 @@ public:
|
|||
|
||||
void draw();
|
||||
|
||||
void storeOpenCloseState ();
|
||||
void restoreOpenCloseState ();
|
||||
void storeOpenCloseState();
|
||||
void restoreOpenCloseState();
|
||||
|
||||
protected:
|
||||
LLAccordionCtrlTab(const LLAccordionCtrlTab::Params&);
|
||||
|
|
|
|||
|
|
@ -288,7 +288,7 @@ void LLContainerView::setLabel(const std::string& label)
|
|||
mLabel = label;
|
||||
}
|
||||
|
||||
void LLContainerView::setDisplayChildren(const BOOL displayChildren)
|
||||
void LLContainerView::setDisplayChildren(BOOL displayChildren)
|
||||
{
|
||||
mDisplayChildren = displayChildren;
|
||||
for (child_list_const_iter_t child_iter = getChildList()->begin();
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ public:
|
|||
|
||||
void setLabel(const std::string& label);
|
||||
void showLabel(BOOL show) { mShowLabel = show; }
|
||||
void setDisplayChildren(const BOOL displayChildren);
|
||||
void setDisplayChildren(BOOL displayChildren);
|
||||
BOOL getDisplayChildren() { return mDisplayChildren; }
|
||||
void setScrollContainer(LLScrollContainer* scroll) {mScrollContainer = scroll;}
|
||||
|
||||
|
|
|
|||
|
|
@ -1361,26 +1361,28 @@ void LLFlatListViewEx::setForceShowingUnmatchedItems(bool show)
|
|||
mForceShowingUnmatchedItems = show;
|
||||
}
|
||||
|
||||
void LLFlatListViewEx::setFilterSubString(const std::string& filter_str)
|
||||
void LLFlatListViewEx::setFilterSubString(const std::string& filter_str, bool notify_parent)
|
||||
{
|
||||
if (0 != LLStringUtil::compareInsensitive(filter_str, mFilterSubString))
|
||||
{
|
||||
mFilterSubString = filter_str;
|
||||
updateNoItemsMessage(mFilterSubString);
|
||||
filterItems();
|
||||
filterItems(false, notify_parent);
|
||||
}
|
||||
}
|
||||
|
||||
void LLFlatListViewEx::updateItemVisibility(LLPanel* item, const LLSD &action)
|
||||
bool LLFlatListViewEx::updateItemVisibility(LLPanel* item, const LLSD &action)
|
||||
{
|
||||
if (!item) return;
|
||||
if (!item)
|
||||
return false;
|
||||
|
||||
BOOL visible = TRUE;
|
||||
|
||||
// 0 signifies that filter is matched,
|
||||
// i.e. we don't hide items that don't support 'match_filter' action, separators etc.
|
||||
if (0 == item->notify(action))
|
||||
{
|
||||
mHasMatchedItems = true;
|
||||
item->setVisible(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1388,34 +1390,45 @@ void LLFlatListViewEx::updateItemVisibility(LLPanel* item, const LLSD &action)
|
|||
if (!mForceShowingUnmatchedItems)
|
||||
{
|
||||
selectItem(item, false);
|
||||
visible = FALSE;
|
||||
}
|
||||
item->setVisible(mForceShowingUnmatchedItems);
|
||||
}
|
||||
|
||||
if (item->getVisible() != visible)
|
||||
{
|
||||
item->setVisible(visible);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void LLFlatListViewEx::filterItems()
|
||||
void LLFlatListViewEx::filterItems(bool re_sort, bool notify_parent)
|
||||
{
|
||||
typedef std::vector <LLPanel*> item_panel_list_t;
|
||||
|
||||
std::string cur_filter = mFilterSubString;
|
||||
LLStringUtil::toUpper(cur_filter);
|
||||
|
||||
LLSD action;
|
||||
action.with("match_filter", cur_filter);
|
||||
|
||||
item_panel_list_t items;
|
||||
getItems(items);
|
||||
|
||||
mHasMatchedItems = false;
|
||||
item_panel_list_t::iterator iter = items.begin(), iter_end = items.end();
|
||||
while (iter < iter_end)
|
||||
bool visibility_changed = false;
|
||||
pairs_const_iterator_t iter = getItemPairs().begin(), iter_end = getItemPairs().end();
|
||||
while (iter != iter_end)
|
||||
{
|
||||
LLPanel* pItem = *(iter++);
|
||||
updateItemVisibility(pItem, action);
|
||||
LLPanel* pItem = (*(iter++))->first;
|
||||
visibility_changed |= updateItemVisibility(pItem, action);
|
||||
}
|
||||
|
||||
sort();
|
||||
notifyParentItemsRectChanged();
|
||||
if (re_sort)
|
||||
{
|
||||
sort();
|
||||
}
|
||||
|
||||
if (visibility_changed && notify_parent)
|
||||
{
|
||||
notifyParentItemsRectChanged();
|
||||
}
|
||||
}
|
||||
|
||||
bool LLFlatListViewEx::hasMatchedItems()
|
||||
|
|
|
|||
|
|
@ -300,6 +300,7 @@ public:
|
|||
virtual S32 notify(const LLSD& info) ;
|
||||
|
||||
virtual ~LLFlatListView();
|
||||
|
||||
protected:
|
||||
|
||||
/** Pairs LLpanel representing a single item LLPanel and LLSD associated with it */
|
||||
|
|
@ -375,7 +376,9 @@ protected:
|
|||
|
||||
LLRect getLastSelectedItemRect();
|
||||
|
||||
void ensureSelectedVisible();
|
||||
void ensureSelectedVisible();
|
||||
|
||||
const pairs_list_t& getItemPairs() { return mItemPairs; }
|
||||
|
||||
private:
|
||||
|
||||
|
|
@ -482,14 +485,14 @@ public:
|
|||
/**
|
||||
* Sets up new filter string and filters the list.
|
||||
*/
|
||||
void setFilterSubString(const std::string& filter_str);
|
||||
void setFilterSubString(const std::string& filter_str, bool notify_parent);
|
||||
std::string getFilterSubString() { return mFilterSubString; }
|
||||
|
||||
/**
|
||||
* Filters the list, rearranges and notifies parent about shape changes.
|
||||
* Derived classes may want to overload rearrangeItems() to exclude repeated separators after filtration.
|
||||
*/
|
||||
void filterItems();
|
||||
void filterItems(bool re_sort, bool notify_parent);
|
||||
|
||||
/**
|
||||
* Returns true if last call of filterItems() found at least one matching item
|
||||
|
|
@ -513,7 +516,7 @@ protected:
|
|||
* @param item - item we are changing
|
||||
* @param item - action - parameters to determin visibility from
|
||||
*/
|
||||
void updateItemVisibility(LLPanel* item, const LLSD &action);
|
||||
bool updateItemVisibility(LLPanel* item, const LLSD &action);
|
||||
|
||||
private:
|
||||
std::string mNoFilteredItemsMsg;
|
||||
|
|
|
|||
|
|
@ -187,14 +187,18 @@ LLFolderViewItem::~LLFolderViewItem()
|
|||
|
||||
BOOL LLFolderViewItem::postBuild()
|
||||
{
|
||||
LLFolderViewModelItem& vmi = *getViewModelItem();
|
||||
// getDisplayName() is expensive (due to internal getLabelSuffix() and name building)
|
||||
// it also sets search strings so it requires a filter reset
|
||||
mLabel = vmi.getDisplayName();
|
||||
setToolTip(vmi.getName());
|
||||
LLFolderViewModelItem* vmi = getViewModelItem();
|
||||
llassert(vmi); // not supposed to happen, if happens, find out why and fix
|
||||
if (vmi)
|
||||
{
|
||||
// getDisplayName() is expensive (due to internal getLabelSuffix() and name building)
|
||||
// it also sets search strings so it requires a filter reset
|
||||
mLabel = vmi->getDisplayName();
|
||||
setToolTip(vmi->getName());
|
||||
|
||||
// Dirty the filter flag of the model from the view (CHUI-849)
|
||||
vmi.dirtyFilter();
|
||||
// Dirty the filter flag of the model from the view (CHUI-849)
|
||||
vmi->dirtyFilter();
|
||||
}
|
||||
|
||||
// Don't do full refresh on constructor if it is possible to avoid
|
||||
// it significantly slows down bulk view creation.
|
||||
|
|
|
|||
|
|
@ -479,7 +479,7 @@ LLTrace::BlockTimerStatHandle FTM_SYNTAX_COLORING("Syntax Coloring");
|
|||
|
||||
// Walk through a string, applying the rules specified by the keyword token list and
|
||||
// create a list of color segments.
|
||||
void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLWString& wtext, const LLColor4 &defaultColor, LLTextEditor& editor)
|
||||
void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLWString& wtext, LLTextEditor& editor, LLStyleConstSP style)
|
||||
{
|
||||
LL_RECORD_BLOCK_TIME(FTM_SYNTAX_COLORING);
|
||||
seg_list->clear();
|
||||
|
|
@ -491,7 +491,7 @@ void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLW
|
|||
|
||||
S32 text_len = wtext.size() + 1;
|
||||
|
||||
seg_list->push_back( new LLNormalTextSegment( defaultColor, 0, text_len, editor ) );
|
||||
seg_list->push_back( new LLNormalTextSegment( style, 0, text_len, editor ) );
|
||||
|
||||
const llwchar* base = wtext.c_str();
|
||||
const llwchar* cur = base;
|
||||
|
|
@ -501,9 +501,9 @@ void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLW
|
|||
{
|
||||
if( *cur == '\n' )
|
||||
{
|
||||
LLTextSegmentPtr text_segment = new LLLineBreakTextSegment(cur-base);
|
||||
LLTextSegmentPtr text_segment = new LLLineBreakTextSegment(style, cur-base);
|
||||
text_segment->setToken( 0 );
|
||||
insertSegment( *seg_list, text_segment, text_len, defaultColor, editor);
|
||||
insertSegment( *seg_list, text_segment, text_len, style, editor);
|
||||
cur++;
|
||||
if( !*cur || *cur == '\n' )
|
||||
{
|
||||
|
|
@ -541,7 +541,7 @@ void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLW
|
|||
S32 seg_end = cur - base;
|
||||
|
||||
//create segments from seg_start to seg_end
|
||||
insertSegments(wtext, *seg_list,cur_token, text_len, seg_start, seg_end, defaultColor, editor);
|
||||
insertSegments(wtext, *seg_list,cur_token, text_len, seg_start, seg_end, style, editor);
|
||||
line_done = TRUE; // to break out of second loop.
|
||||
break;
|
||||
}
|
||||
|
|
@ -648,7 +648,7 @@ void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLW
|
|||
seg_end = seg_start + between_delimiters + cur_delimiter->getLengthHead();
|
||||
}
|
||||
|
||||
insertSegments(wtext, *seg_list,cur_delimiter, text_len, seg_start, seg_end, defaultColor, editor);
|
||||
insertSegments(wtext, *seg_list,cur_delimiter, text_len, seg_start, seg_end, style, editor);
|
||||
/*
|
||||
LLTextSegmentPtr text_segment = new LLNormalTextSegment( cur_delimiter->getColor(), seg_start, seg_end, editor );
|
||||
text_segment->setToken( cur_delimiter );
|
||||
|
|
@ -682,7 +682,7 @@ void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLW
|
|||
|
||||
// LL_INFOS("SyntaxLSL") << "Seg: [" << word.c_str() << "]" << LL_ENDL;
|
||||
|
||||
insertSegments(wtext, *seg_list,cur_token, text_len, seg_start, seg_end, defaultColor, editor);
|
||||
insertSegments(wtext, *seg_list,cur_token, text_len, seg_start, seg_end, style, editor);
|
||||
}
|
||||
cur += seg_len;
|
||||
continue;
|
||||
|
|
@ -697,30 +697,32 @@ void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLW
|
|||
}
|
||||
}
|
||||
|
||||
void LLKeywords::insertSegments(const LLWString& wtext, std::vector<LLTextSegmentPtr>& seg_list, LLKeywordToken* cur_token, S32 text_len, S32 seg_start, S32 seg_end, const LLColor4 &defaultColor, LLTextEditor& editor )
|
||||
void LLKeywords::insertSegments(const LLWString& wtext, std::vector<LLTextSegmentPtr>& seg_list, LLKeywordToken* cur_token, S32 text_len, S32 seg_start, S32 seg_end, LLStyleConstSP style, LLTextEditor& editor )
|
||||
{
|
||||
std::string::size_type pos = wtext.find('\n',seg_start);
|
||||
|
||||
LLStyleConstSP cur_token_style = new LLStyle(LLStyle::Params().font(style->getFont()).color(cur_token->getColor()));
|
||||
|
||||
while (pos!=-1 && pos < (std::string::size_type)seg_end)
|
||||
{
|
||||
if (pos!=seg_start)
|
||||
{
|
||||
LLTextSegmentPtr text_segment = new LLNormalTextSegment( cur_token->getColor(), seg_start, pos, editor );
|
||||
LLTextSegmentPtr text_segment = new LLNormalTextSegment(cur_token_style, seg_start, pos, editor);
|
||||
text_segment->setToken( cur_token );
|
||||
insertSegment( seg_list, text_segment, text_len, defaultColor, editor);
|
||||
insertSegment( seg_list, text_segment, text_len, style, editor);
|
||||
}
|
||||
|
||||
LLTextSegmentPtr text_segment = new LLLineBreakTextSegment(pos);
|
||||
LLTextSegmentPtr text_segment = new LLLineBreakTextSegment(style, pos);
|
||||
text_segment->setToken( cur_token );
|
||||
insertSegment( seg_list, text_segment, text_len, defaultColor, editor);
|
||||
insertSegment( seg_list, text_segment, text_len, style, editor);
|
||||
|
||||
seg_start = pos+1;
|
||||
pos = wtext.find('\n',seg_start);
|
||||
}
|
||||
|
||||
LLTextSegmentPtr text_segment = new LLNormalTextSegment( cur_token->getColor(), seg_start, seg_end, editor );
|
||||
LLTextSegmentPtr text_segment = new LLNormalTextSegment(cur_token_style, seg_start, seg_end, editor);
|
||||
text_segment->setToken( cur_token );
|
||||
insertSegment( seg_list, text_segment, text_len, defaultColor, editor);
|
||||
insertSegment( seg_list, text_segment, text_len, style, editor);
|
||||
}
|
||||
|
||||
void LLKeywords::insertSegment(std::vector<LLTextSegmentPtr>& seg_list, LLTextSegmentPtr new_segment, S32 text_len, const LLColor4 &defaultColor, LLTextEditor& editor )
|
||||
|
|
@ -744,6 +746,27 @@ void LLKeywords::insertSegment(std::vector<LLTextSegmentPtr>& seg_list, LLTextSe
|
|||
}
|
||||
}
|
||||
|
||||
void LLKeywords::insertSegment(std::vector<LLTextSegmentPtr>& seg_list, LLTextSegmentPtr new_segment, S32 text_len, LLStyleConstSP style, LLTextEditor& editor )
|
||||
{
|
||||
LLTextSegmentPtr last = seg_list.back();
|
||||
S32 new_seg_end = new_segment->getEnd();
|
||||
|
||||
if( new_segment->getStart() == last->getStart() )
|
||||
{
|
||||
seg_list.pop_back();
|
||||
}
|
||||
else
|
||||
{
|
||||
last->setEnd( new_segment->getStart() );
|
||||
}
|
||||
seg_list.push_back( new_segment );
|
||||
|
||||
if( new_seg_end < text_len )
|
||||
{
|
||||
seg_list.push_back( new LLNormalTextSegment( style, new_seg_end, text_len, editor ) );
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
void LLKeywords::dump()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
|
||||
#include "lldir.h"
|
||||
#include "llstyle.h"
|
||||
#include "llstring.h"
|
||||
#include "v3color.h"
|
||||
#include "v4color.h"
|
||||
|
|
@ -115,8 +116,8 @@ public:
|
|||
|
||||
void findSegments(std::vector<LLTextSegmentPtr> *seg_list,
|
||||
const LLWString& text,
|
||||
const LLColor4 &defaultColor,
|
||||
class LLTextEditor& editor);
|
||||
class LLTextEditor& editor,
|
||||
LLStyleConstSP style);
|
||||
void initialize(LLSD SyntaxXML);
|
||||
void processTokens();
|
||||
|
||||
|
|
@ -181,9 +182,11 @@ protected:
|
|||
S32 text_len,
|
||||
S32 seg_start,
|
||||
S32 seg_end,
|
||||
const LLColor4 &defaultColor,
|
||||
LLStyleConstSP style,
|
||||
LLTextEditor& editor);
|
||||
|
||||
void insertSegment(std::vector<LLTextSegmentPtr>& seg_list, LLTextSegmentPtr new_segment, S32 text_len, LLStyleConstSP style, LLTextEditor& editor );
|
||||
|
||||
bool mLoaded;
|
||||
LLSD mSyntax;
|
||||
word_token_map_t mWordTokenMap;
|
||||
|
|
|
|||
|
|
@ -1783,7 +1783,8 @@ LLMenuGL::LLMenuGL(const LLMenuGL::Params& p)
|
|||
mNeedsArrange(FALSE),
|
||||
mAlwaysShowMenu(FALSE),
|
||||
mResetScrollPositionOnShow(true),
|
||||
mShortcutPad(p.shortcut_pad)
|
||||
mShortcutPad(p.shortcut_pad),
|
||||
mFont(p.font)
|
||||
{
|
||||
typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
|
||||
boost::char_separator<char> sep("_");
|
||||
|
|
@ -3642,6 +3643,7 @@ BOOL LLMenuBarGL::appendMenu( LLMenuGL* menu )
|
|||
p.disabled_color=LLUIColorTable::instance().getColor("MenuItemDisabledColor");
|
||||
p.highlight_bg_color=LLUIColorTable::instance().getColor("MenuItemHighlightBgColor");
|
||||
p.highlight_fg_color=LLUIColorTable::instance().getColor("MenuItemHighlightFgColor");
|
||||
p.font = menu->getFont();
|
||||
|
||||
LLMenuItemBranchDownGL* branch = LLUICtrlFactory::create<LLMenuItemBranchDownGL>(p);
|
||||
success &= branch->addToAcceleratorList(&mAccelerators);
|
||||
|
|
|
|||
|
|
@ -562,7 +562,9 @@ public:
|
|||
// add a context menu branch
|
||||
BOOL appendContextSubMenu(LLMenuGL *menu);
|
||||
|
||||
protected:
|
||||
const LLFontGL *getFont() const { return mFont; }
|
||||
|
||||
protected:
|
||||
void createSpilloverBranch();
|
||||
void cleanupSpilloverBranch();
|
||||
// Add the menu item to this menu.
|
||||
|
|
@ -594,6 +596,9 @@ protected:
|
|||
BOOL mKeepFixedSize;
|
||||
BOOL mNeedsArrange;
|
||||
|
||||
// Font for top menu items only
|
||||
const LLFontGL* mFont;
|
||||
|
||||
private:
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -181,7 +181,7 @@ LLStatBar::LLStatBar(const Params& p)
|
|||
mTargetMinBar(llmin(p.bar_min, p.bar_max)),
|
||||
mTargetMaxBar(llmax(p.bar_max, p.bar_min)),
|
||||
mCurMaxBar(p.bar_max),
|
||||
mCurMinBar(0),
|
||||
mCurMinBar(0),
|
||||
mDecimalDigits(p.decimal_digits),
|
||||
mNumHistoryFrames(p.num_frames),
|
||||
mNumShortHistoryFrames(p.num_frames_short),
|
||||
|
|
@ -222,9 +222,6 @@ BOOL LLStatBar::handleHover(S32 x, S32 y, MASK mask)
|
|||
case STAT_SAMPLE:
|
||||
LLToolTipMgr::instance().show(LLToolTip::Params().message(mStat.sampleStatp->getDescription()).sticky_rect(calcScreenRect()));
|
||||
break;
|
||||
case STAT_MEM:
|
||||
LLToolTipMgr::instance().show(LLToolTip::Params().message(mStat.memStatp->getDescription()).sticky_rect(calcScreenRect()));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -373,18 +370,6 @@ void LLStatBar::draw()
|
|||
}
|
||||
}
|
||||
break;
|
||||
case STAT_MEM:
|
||||
{
|
||||
const LLTrace::StatType<LLTrace::MemAccumulator>& mem_stat = *mStat.memStatp;
|
||||
|
||||
unit_label = mUnitLabel.empty() ? mem_stat.getUnitLabel() : mUnitLabel;
|
||||
current = last_frame_recording.getLastValue(mem_stat).value();
|
||||
min = frame_recording.getPeriodMin(mem_stat, num_frames).value();
|
||||
max = frame_recording.getPeriodMax(mem_stat, num_frames).value();
|
||||
mean = frame_recording.getPeriodMean(mem_stat, num_frames).value();
|
||||
display_value = current;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -500,11 +485,6 @@ void LLStatBar::draw()
|
|||
max_value = recording.getMax(*mStat.sampleStatp);
|
||||
num_samples = recording.getSampleCount(*mStat.sampleStatp);
|
||||
break;
|
||||
case STAT_MEM:
|
||||
min_value = recording.getMin(*mStat.memStatp).value();
|
||||
max_value = recording.getMax(*mStat.memStatp).value();
|
||||
num_samples = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -583,14 +563,8 @@ void LLStatBar::setStat(const std::string& stat_name)
|
|||
mStat.sampleStatp = sample_stat.get();
|
||||
mStatType = STAT_SAMPLE;
|
||||
}
|
||||
else if (auto mem_stat = StatType<MemAccumulator>::getInstance(stat_name))
|
||||
{
|
||||
mStat.memStatp = mem_stat.get();
|
||||
mStatType = STAT_MEM;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LLStatBar::setRange(F32 bar_min, F32 bar_max)
|
||||
{
|
||||
mTargetMinBar = llmin(bar_min, bar_max);
|
||||
|
|
|
|||
|
|
@ -95,17 +95,15 @@ private:
|
|||
STAT_NONE,
|
||||
STAT_COUNT,
|
||||
STAT_EVENT,
|
||||
STAT_SAMPLE,
|
||||
STAT_MEM
|
||||
STAT_SAMPLE
|
||||
} mStatType;
|
||||
|
||||
union
|
||||
{
|
||||
void* valid;
|
||||
void* valid;
|
||||
const LLTrace::StatType<LLTrace::CountAccumulator>* countStatp;
|
||||
const LLTrace::StatType<LLTrace::EventAccumulator>* eventStatp;
|
||||
const LLTrace::StatType<LLTrace::SampleAccumulator>* sampleStatp;
|
||||
const LLTrace::StatType<LLTrace::MemAccumulator>* memStatp;
|
||||
const LLTrace::StatType<LLTrace::SampleAccumulator>* sampleStatp;
|
||||
} mStat;
|
||||
|
||||
LLUIString mLabel;
|
||||
|
|
|
|||
|
|
@ -58,10 +58,7 @@ LLStatView::~LLStatView()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
static StatViewRegistry::Register<LLStatBar> r1("stat_bar");
|
||||
static StatViewRegistry::Register<LLStatView> r2("stat_view");
|
||||
// stat_view can be a child of panels/etc.
|
||||
static LLDefaultChildRegistry::Register<LLStatView> r3("stat_view");
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ protected:
|
|||
friend class LLUICtrlFactory;
|
||||
|
||||
protected:
|
||||
std::string mSetting;
|
||||
|
||||
const std::string mSetting;
|
||||
};
|
||||
|
||||
#endif // LL_STATVIEW_
|
||||
|
|
|
|||
|
|
@ -1516,25 +1516,23 @@ BOOL LLTabContainer::selectTab(S32 which)
|
|||
|
||||
LLTabTuple* selected_tuple = getTab(which);
|
||||
if (!selected_tuple)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
LLSD cbdata;
|
||||
if (selected_tuple->mTabPanel)
|
||||
cbdata = selected_tuple->mTabPanel->getName();
|
||||
|
||||
BOOL res = FALSE;
|
||||
if( !mValidateSignal || (*mValidateSignal)( this, cbdata ) )
|
||||
BOOL result = FALSE;
|
||||
if (!mValidateSignal || (*mValidateSignal)(this, cbdata))
|
||||
{
|
||||
res = setTab(which);
|
||||
if (res && mCommitSignal)
|
||||
result = setTab(which);
|
||||
if (result && mCommitSignal)
|
||||
{
|
||||
(*mCommitSignal)(this, cbdata);
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// private
|
||||
|
|
|
|||
|
|
@ -1550,7 +1550,13 @@ S32 LLTextBase::getLeftOffset(S32 width)
|
|||
case LLFontGL::HCENTER:
|
||||
return mHPad + llmax(0, (mVisibleTextRect.getWidth() - width - mHPad) / 2);
|
||||
case LLFontGL::RIGHT:
|
||||
return mVisibleTextRect.getWidth() - width;
|
||||
{
|
||||
// Font's rendering rounds string size, if value gets rounded
|
||||
// down last symbol might not have enough space to render,
|
||||
// compensate by adding an extra pixel as padding
|
||||
const S32 right_padding = 1;
|
||||
return llmax(mHPad, mVisibleTextRect.getWidth() - width - right_padding);
|
||||
}
|
||||
default:
|
||||
return mHPad;
|
||||
}
|
||||
|
|
@ -3431,7 +3437,7 @@ BOOL LLNormalTextSegment::handleToolTip(S32 x, S32 y, MASK mask)
|
|||
if (mToken && !mToken->getToolTip().empty())
|
||||
{
|
||||
const LLWString& wmsg = mToken->getToolTip();
|
||||
LLToolTipMgr::instance().show(wstring_to_utf8str(wmsg));
|
||||
LLToolTipMgr::instance().show(wstring_to_utf8str(wmsg), (mToken->getType() == LLKeywordToken::TT_FUNCTION));
|
||||
return TRUE;
|
||||
}
|
||||
// or do we have an explicitly set tooltip (e.g., for Urls)
|
||||
|
|
|
|||
|
|
@ -1779,7 +1779,8 @@ BOOL LLTextEditor::handleKeyHere(KEY key, MASK mask )
|
|||
else
|
||||
{
|
||||
if (mEnableTooltipPaste &&
|
||||
LLToolTipMgr::instance().toolTipVisible() &&
|
||||
LLToolTipMgr::instance().toolTipVisible() &&
|
||||
LLToolTipMgr::instance().isTooltipPastable() &&
|
||||
KEY_TAB == key)
|
||||
{ // Paste the first line of a tooltip into the editor
|
||||
std::string message;
|
||||
|
|
|
|||
|
|
@ -154,7 +154,8 @@ LLToolTip::Params::Params()
|
|||
text_color("text_color"),
|
||||
time_based_media("time_based_media", false),
|
||||
web_based_media("web_based_media", false),
|
||||
media_playing("media_playing", false)
|
||||
media_playing("media_playing", false),
|
||||
allow_paste_tooltip("allow_paste_tooltip", false)
|
||||
{
|
||||
changeDefault(chrome, true);
|
||||
}
|
||||
|
|
@ -167,7 +168,8 @@ LLToolTip::LLToolTip(const LLToolTip::Params& p)
|
|||
mTextBox(NULL),
|
||||
mInfoButton(NULL),
|
||||
mPlayMediaButton(NULL),
|
||||
mHomePageButton(NULL)
|
||||
mHomePageButton(NULL),
|
||||
mIsTooltipPastable(p.allow_paste_tooltip)
|
||||
{
|
||||
LLTextBox::Params params;
|
||||
params.name = params.initial_value().asString();
|
||||
|
|
@ -289,6 +291,8 @@ void LLToolTip::initFromParams(const LLToolTip::Params& p)
|
|||
mTextBox->setText(p.message());
|
||||
}
|
||||
|
||||
mIsTooltipPastable = p.allow_paste_tooltip;
|
||||
|
||||
updateTextBox();
|
||||
snapToChildren();
|
||||
}
|
||||
|
|
@ -483,9 +487,9 @@ void LLToolTipMgr::createToolTip(const LLToolTip::Params& params)
|
|||
}
|
||||
|
||||
|
||||
void LLToolTipMgr::show(const std::string& msg)
|
||||
void LLToolTipMgr::show(const std::string& msg, bool allow_paste_tooltip)
|
||||
{
|
||||
show(LLToolTip::Params().message(msg));
|
||||
show(LLToolTip::Params().message(msg).allow_paste_tooltip(allow_paste_tooltip));
|
||||
}
|
||||
|
||||
void LLToolTipMgr::show(const LLToolTip::Params& params)
|
||||
|
|
@ -626,5 +630,13 @@ void LLToolTipMgr::getToolTipMessage(std::string & message)
|
|||
}
|
||||
}
|
||||
|
||||
bool LLToolTipMgr::isTooltipPastable()
|
||||
{
|
||||
if (toolTipVisible())
|
||||
{
|
||||
return mToolTip->isTooltipPastable();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// EOF
|
||||
|
|
|
|||
|
|
@ -94,6 +94,8 @@ public:
|
|||
padding;
|
||||
Optional<bool> wrap;
|
||||
|
||||
Optional<bool> allow_paste_tooltip;
|
||||
|
||||
Params();
|
||||
};
|
||||
/*virtual*/ void draw();
|
||||
|
|
@ -109,6 +111,7 @@ public:
|
|||
virtual void initFromParams(const LLToolTip::Params& params);
|
||||
|
||||
void getToolTipMessage(std::string & message);
|
||||
bool isTooltipPastable() { return mIsTooltipPastable; }
|
||||
|
||||
protected:
|
||||
void updateTextBox();
|
||||
|
|
@ -125,6 +128,8 @@ protected:
|
|||
bool mHasClickCallback;
|
||||
S32 mPadding; // pixels
|
||||
S32 mMaxWidth;
|
||||
|
||||
bool mIsTooltipPastable;
|
||||
};
|
||||
|
||||
// used for the inspector tooltips which need different background images etc.
|
||||
|
|
@ -142,7 +147,7 @@ class LLToolTipMgr : public LLSingleton<LLToolTipMgr>
|
|||
|
||||
public:
|
||||
void show(const LLToolTip::Params& params);
|
||||
void show(const std::string& message);
|
||||
void show(const std::string& message, bool allow_paste_tooltip = false);
|
||||
|
||||
void unblockToolTips();
|
||||
void blockToolTips();
|
||||
|
|
@ -154,6 +159,7 @@ public:
|
|||
void updateToolTipVisibility();
|
||||
|
||||
void getToolTipMessage(std::string & message);
|
||||
bool isTooltipPastable();
|
||||
|
||||
private:
|
||||
void createToolTip(const LLToolTip::Params& params);
|
||||
|
|
|
|||
|
|
@ -5420,6 +5420,17 @@
|
|||
<key>Value</key>
|
||||
<string>http://wiki.secondlife.com/wiki/[LSL_STRING]</string>
|
||||
</map>
|
||||
<key>LSLFontSizeName</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Text font size in LSL editor</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>String</string>
|
||||
<key>Value</key>
|
||||
<string>Monospace</string>
|
||||
</map>
|
||||
<key>GridStatusRSS</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -7496,10 +7507,21 @@
|
|||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>OpenDebugStatBasic</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Expand Basic performance stats display</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>OpenDebugStatAdvanced</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Expand advanced performance stats display</string>
|
||||
<string>Expand Advanced performance stats display</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
|
|
@ -7507,43 +7529,10 @@
|
|||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>OpenDebugStatBasic</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Expand basic performance stats display</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>OpenDebugStatNet</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Expand network stats display</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>OpenDebugStatRender</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Expand render stats display</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>OpenDebugStatSim</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Expand simulator performance stats display</string>
|
||||
<string>Expand Render performance stats display</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
|
|
@ -7562,6 +7551,39 @@
|
|||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>OpenDebugStatMemory</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Expand Memory Usage stats display</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>OpenDebugStatNet</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Expand Network performance stats display</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>OpenDebugStatSim</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Expand Simulator performance stats display</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>OpenDebugStatPhysicsDetails</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -7573,6 +7595,17 @@
|
|||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>OpenDebugStatPathfinding</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Expand Pathfinding performance stats display</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>OpenDebugStatSimTime</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
|
|||
|
|
@ -100,6 +100,12 @@ const F32 GROUND_TO_AIR_CAMERA_TRANSITION_START_TIME = 0.5f;
|
|||
|
||||
const F32 OBJECT_EXTENTS_PADDING = 0.5f;
|
||||
|
||||
static bool isDisableCameraConstraints()
|
||||
{
|
||||
static LLCachedControl<bool> sDisableCameraConstraints(gSavedSettings, "DisableCameraConstraints", false);
|
||||
return sDisableCameraConstraints;
|
||||
}
|
||||
|
||||
// The agent instance.
|
||||
LLAgentCamera gAgentCamera;
|
||||
|
||||
|
|
@ -570,9 +576,9 @@ BOOL LLAgentCamera::calcCameraMinDistance(F32 &obj_min_distance)
|
|||
{
|
||||
BOOL soft_limit = FALSE; // is the bounding box to be treated literally (volumes) or as an approximation (avatars)
|
||||
|
||||
if (!mFocusObject || mFocusObject->isDead() ||
|
||||
if (!mFocusObject || mFocusObject->isDead() ||
|
||||
mFocusObject->isMesh() ||
|
||||
gSavedSettings.getBOOL("DisableCameraConstraints"))
|
||||
isDisableCameraConstraints())
|
||||
{
|
||||
obj_min_distance = 0.f;
|
||||
return TRUE;
|
||||
|
|
@ -742,39 +748,44 @@ F32 LLAgentCamera::getCameraZoomFraction(bool get_third_person)
|
|||
// already [0,1]
|
||||
return mHUDTargetZoom;
|
||||
}
|
||||
else if (get_third_person || (mFocusOnAvatar && cameraThirdPerson()))
|
||||
|
||||
if (isDisableCameraConstraints())
|
||||
{
|
||||
return mCameraZoomFraction;
|
||||
}
|
||||
|
||||
if (get_third_person || (mFocusOnAvatar && cameraThirdPerson()))
|
||||
{
|
||||
return clamp_rescale(mCameraZoomFraction, MIN_ZOOM_FRACTION, MAX_ZOOM_FRACTION, 1.f, 0.f);
|
||||
}
|
||||
else if (cameraCustomizeAvatar())
|
||||
|
||||
if (cameraCustomizeAvatar())
|
||||
{
|
||||
F32 distance = (F32)mCameraFocusOffsetTarget.magVec();
|
||||
return clamp_rescale(distance, APPEARANCE_MIN_ZOOM, APPEARANCE_MAX_ZOOM, 1.f, 0.f );
|
||||
}
|
||||
else
|
||||
{
|
||||
F32 min_zoom;
|
||||
F32 max_zoom = getCameraMaxZoomDistance();
|
||||
|
||||
F32 distance = (F32)mCameraFocusOffsetTarget.magVec();
|
||||
if (mFocusObject.notNull())
|
||||
F32 min_zoom;
|
||||
F32 max_zoom = getCameraMaxZoomDistance();
|
||||
|
||||
F32 distance = (F32)mCameraFocusOffsetTarget.magVec();
|
||||
if (mFocusObject.notNull())
|
||||
{
|
||||
if (mFocusObject->isAvatar())
|
||||
{
|
||||
if (mFocusObject->isAvatar())
|
||||
{
|
||||
min_zoom = AVATAR_MIN_ZOOM;
|
||||
}
|
||||
else
|
||||
{
|
||||
min_zoom = OBJECT_MIN_ZOOM;
|
||||
}
|
||||
min_zoom = AVATAR_MIN_ZOOM;
|
||||
}
|
||||
else
|
||||
{
|
||||
min_zoom = LAND_MIN_ZOOM;
|
||||
min_zoom = OBJECT_MIN_ZOOM;
|
||||
}
|
||||
|
||||
return clamp_rescale(distance, min_zoom, max_zoom, 1.f, 0.f);
|
||||
}
|
||||
else
|
||||
{
|
||||
min_zoom = LAND_MIN_ZOOM;
|
||||
}
|
||||
|
||||
return clamp_rescale(distance, min_zoom, max_zoom, 1.f, 0.f);
|
||||
}
|
||||
|
||||
void LLAgentCamera::setCameraZoomFraction(F32 fraction)
|
||||
|
|
@ -787,6 +798,10 @@ void LLAgentCamera::setCameraZoomFraction(F32 fraction)
|
|||
{
|
||||
mHUDTargetZoom = fraction;
|
||||
}
|
||||
else if (isDisableCameraConstraints())
|
||||
{
|
||||
mCameraZoomFraction = fraction;
|
||||
}
|
||||
else if (mFocusOnAvatar && cameraThirdPerson())
|
||||
{
|
||||
mCameraZoomFraction = rescale(fraction, 0.f, 1.f, MAX_ZOOM_FRACTION, MIN_ZOOM_FRACTION);
|
||||
|
|
@ -821,6 +836,7 @@ void LLAgentCamera::setCameraZoomFraction(F32 fraction)
|
|||
camera_offset_dir.normalize();
|
||||
mCameraFocusOffsetTarget = camera_offset_dir * rescale(fraction, 0.f, 1.f, max_zoom, min_zoom);
|
||||
}
|
||||
|
||||
startCameraAnimation();
|
||||
}
|
||||
|
||||
|
|
@ -925,51 +941,42 @@ void LLAgentCamera::cameraZoomIn(const F32 fraction)
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
LLVector3d camera_offset_unit(mCameraFocusOffsetTarget);
|
||||
F32 min_zoom = LAND_MIN_ZOOM;
|
||||
LLVector3d camera_offset_unit(mCameraFocusOffsetTarget);
|
||||
F32 current_distance = (F32)camera_offset_unit.normalize();
|
||||
F32 new_distance = current_distance * fraction;
|
||||
|
||||
// Don't move through focus point
|
||||
if (mFocusObject)
|
||||
// Unless camera is unlocked
|
||||
if (!isDisableCameraConstraints())
|
||||
{
|
||||
LLVector3 camera_offset_dir((F32)camera_offset_unit.mdV[VX], (F32)camera_offset_unit.mdV[VY], (F32)camera_offset_unit.mdV[VZ]);
|
||||
F32 min_zoom = LAND_MIN_ZOOM;
|
||||
|
||||
if (mFocusObject->isAvatar())
|
||||
// Don't move through focus point
|
||||
if (mFocusObject)
|
||||
{
|
||||
calcCameraMinDistance(min_zoom);
|
||||
LLVector3 camera_offset_dir((F32)camera_offset_unit.mdV[VX], (F32)camera_offset_unit.mdV[VY], (F32)camera_offset_unit.mdV[VZ]);
|
||||
|
||||
if (mFocusObject->isAvatar())
|
||||
{
|
||||
calcCameraMinDistance(min_zoom);
|
||||
}
|
||||
else
|
||||
{
|
||||
min_zoom = OBJECT_MIN_ZOOM;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
new_distance = llmax(new_distance, min_zoom);
|
||||
|
||||
F32 max_distance = getCameraMaxZoomDistance();
|
||||
max_distance = llmin(max_distance, current_distance * 4.f); //Scaled max relative to current distance. MAINT-3154
|
||||
new_distance = llmin(new_distance, max_distance);
|
||||
|
||||
if (cameraCustomizeAvatar())
|
||||
{
|
||||
min_zoom = OBJECT_MIN_ZOOM;
|
||||
new_distance = llclamp(new_distance, APPEARANCE_MIN_ZOOM, APPEARANCE_MAX_ZOOM);
|
||||
}
|
||||
}
|
||||
|
||||
new_distance = llmax(new_distance, min_zoom);
|
||||
|
||||
F32 max_distance = getCameraMaxZoomDistance();
|
||||
|
||||
max_distance = llmin(max_distance, current_distance * 4.f); //Scaled max relative to current distance. MAINT-3154
|
||||
|
||||
if (new_distance > max_distance)
|
||||
{
|
||||
new_distance = max_distance;
|
||||
|
||||
/*
|
||||
// Unless camera is unlocked
|
||||
if (!LLViewerCamera::sDisableCameraConstraints)
|
||||
{
|
||||
return;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
if(cameraCustomizeAvatar())
|
||||
{
|
||||
new_distance = llclamp( new_distance, APPEARANCE_MIN_ZOOM, APPEARANCE_MAX_ZOOM );
|
||||
}
|
||||
|
||||
mCameraFocusOffsetTarget = new_distance * camera_offset_unit;
|
||||
}
|
||||
|
||||
|
|
@ -990,53 +997,52 @@ void LLAgentCamera::cameraOrbitIn(const F32 meters)
|
|||
changeCameraToMouselook(FALSE);
|
||||
}
|
||||
|
||||
mCameraZoomFraction = llclamp(mCameraZoomFraction, MIN_ZOOM_FRACTION, MAX_ZOOM_FRACTION);
|
||||
if (!isDisableCameraConstraints())
|
||||
{
|
||||
mCameraZoomFraction = llclamp(mCameraZoomFraction, MIN_ZOOM_FRACTION, MAX_ZOOM_FRACTION);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LLVector3d camera_offset_unit(mCameraFocusOffsetTarget);
|
||||
F32 current_distance = (F32)camera_offset_unit.normalize();
|
||||
F32 new_distance = current_distance - meters;
|
||||
F32 min_zoom = LAND_MIN_ZOOM;
|
||||
|
||||
// Don't move through focus point
|
||||
if (mFocusObject.notNull())
|
||||
|
||||
// Unless camera is unlocked
|
||||
if (!isDisableCameraConstraints())
|
||||
{
|
||||
if (mFocusObject->isAvatar())
|
||||
F32 min_zoom = LAND_MIN_ZOOM;
|
||||
|
||||
// Don't move through focus point
|
||||
if (mFocusObject.notNull())
|
||||
{
|
||||
min_zoom = AVATAR_MIN_ZOOM;
|
||||
if (mFocusObject->isAvatar())
|
||||
{
|
||||
min_zoom = AVATAR_MIN_ZOOM;
|
||||
}
|
||||
else
|
||||
{
|
||||
min_zoom = OBJECT_MIN_ZOOM;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
new_distance = llmax(new_distance, min_zoom);
|
||||
|
||||
F32 max_distance = getCameraMaxZoomDistance();
|
||||
new_distance = llmin(new_distance, max_distance);
|
||||
|
||||
if (CAMERA_MODE_CUSTOMIZE_AVATAR == getCameraMode())
|
||||
{
|
||||
min_zoom = OBJECT_MIN_ZOOM;
|
||||
new_distance = llclamp(new_distance, APPEARANCE_MIN_ZOOM, APPEARANCE_MAX_ZOOM);
|
||||
}
|
||||
}
|
||||
|
||||
new_distance = llmax(new_distance, min_zoom);
|
||||
|
||||
F32 max_distance = getCameraMaxZoomDistance();
|
||||
|
||||
if (new_distance > max_distance)
|
||||
{
|
||||
// Unless camera is unlocked
|
||||
if (!gSavedSettings.getBOOL("DisableCameraConstraints"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if( CAMERA_MODE_CUSTOMIZE_AVATAR == getCameraMode() )
|
||||
{
|
||||
new_distance = llclamp( new_distance, APPEARANCE_MIN_ZOOM, APPEARANCE_MAX_ZOOM );
|
||||
}
|
||||
|
||||
// Compute new camera offset
|
||||
mCameraFocusOffsetTarget = new_distance * camera_offset_unit;
|
||||
cameraZoomIn(1.f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// cameraPanIn()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -1841,7 +1847,8 @@ LLVector3d LLAgentCamera::calcCameraPositionTargetGlobal(BOOL *hit_limit)
|
|||
local_camera_offset = gAgent.getFrameAgent().rotateToAbsolute( local_camera_offset );
|
||||
}
|
||||
|
||||
if (!mCameraCollidePlane.isExactlyZero() && (!isAgentAvatarValid() || !gAgentAvatarp->isSitting()))
|
||||
if (!isDisableCameraConstraints() && !mCameraCollidePlane.isExactlyZero() &&
|
||||
(!isAgentAvatarValid() || !gAgentAvatarp->isSitting()))
|
||||
{
|
||||
LLVector3 plane_normal;
|
||||
plane_normal.setVec(mCameraCollidePlane.mV);
|
||||
|
|
@ -1960,7 +1967,7 @@ LLVector3d LLAgentCamera::calcCameraPositionTargetGlobal(BOOL *hit_limit)
|
|||
camera_position_global = focusPosGlobal + mCameraFocusOffset;
|
||||
}
|
||||
|
||||
if (!gSavedSettings.getBOOL("DisableCameraConstraints") && !gAgent.isGodlike())
|
||||
if (!isDisableCameraConstraints() && !gAgent.isGodlike())
|
||||
{
|
||||
LLViewerRegion* regionp = LLWorld::getInstance()->getRegionFromPosGlobal(camera_position_global);
|
||||
bool constrain = true;
|
||||
|
|
@ -2131,17 +2138,13 @@ F32 LLAgentCamera::getCameraMinOffGround()
|
|||
{
|
||||
return 0.f;
|
||||
}
|
||||
else
|
||||
|
||||
if (isDisableCameraConstraints())
|
||||
{
|
||||
if (gSavedSettings.getBOOL("DisableCameraConstraints"))
|
||||
{
|
||||
return -1000.f;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0.5f;
|
||||
}
|
||||
return -1000.f;
|
||||
}
|
||||
|
||||
return 0.5f;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -2943,13 +2943,14 @@ bool LLAppViewer::initConfiguration()
|
|||
|
||||
if (mSecondInstance)
|
||||
{
|
||||
// This is the second instance of SL. Turn off voice support,
|
||||
// This is the second instance of SL. Mute voice,
|
||||
// but make sure the setting is *not* persisted.
|
||||
LLControlVariable* disable_voice = gSavedSettings.getControl("CmdLineDisableVoice");
|
||||
if(disable_voice)
|
||||
// Also see LLVivoxVoiceClient::voiceEnabled()
|
||||
LLControlVariable* enable_voice = gSavedSettings.getControl("EnableVoiceChat");
|
||||
if(enable_voice)
|
||||
{
|
||||
const BOOL DO_NOT_PERSIST = FALSE;
|
||||
disable_voice->setValue(LLSD(TRUE), DO_NOT_PERSIST);
|
||||
enable_voice->setValue(LLSD(FALSE), DO_NOT_PERSIST);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -5420,9 +5421,18 @@ void LLAppViewer::forceErrorBadMemoryAccess()
|
|||
void LLAppViewer::forceErrorInfiniteLoop()
|
||||
{
|
||||
LL_WARNS() << "Forcing a deliberate infinite loop" << LL_ENDL;
|
||||
// Loop is intentionally complicated to fool basic loop detection
|
||||
LLTimer timer_total;
|
||||
LLTimer timer_expiry;
|
||||
const S32 report_frequency = 10;
|
||||
timer_expiry.setTimerExpirySec(report_frequency);
|
||||
while(true)
|
||||
{
|
||||
;
|
||||
if (timer_expiry.hasExpired())
|
||||
{
|
||||
LL_INFOS() << "Infinite loop time : " << timer_total.getElapsedSeconds() << LL_ENDL;
|
||||
timer_expiry.setTimerExpirySec(report_frequency);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -379,6 +379,7 @@ void LLControlAvatar::idleUpdate(LLAgent &agent, const F64 &time)
|
|||
|
||||
void LLControlAvatar::markDead()
|
||||
{
|
||||
mRootVolp = NULL;
|
||||
super::markDead();
|
||||
mControlAVBridge = NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -90,6 +90,8 @@ LLConversationItem::~LLConversationItem()
|
|||
{
|
||||
mAvatarNameCacheConnection.disconnect();
|
||||
}
|
||||
|
||||
clearChildren();
|
||||
}
|
||||
|
||||
//virtual
|
||||
|
|
@ -254,6 +256,11 @@ LLConversationItemSession::LLConversationItemSession(const LLUUID& uuid, LLFolde
|
|||
mConvType = CONV_SESSION_UNKNOWN;
|
||||
}
|
||||
|
||||
LLConversationItemSession::~LLConversationItemSession()
|
||||
{
|
||||
clearAndDeparentModels();
|
||||
}
|
||||
|
||||
bool LLConversationItemSession::hasChildren() const
|
||||
{
|
||||
return getChildrenCount() > 0;
|
||||
|
|
|
|||
|
|
@ -157,6 +157,7 @@ class LLConversationItemSession : public LLConversationItem
|
|||
public:
|
||||
LLConversationItemSession(std::string display_name, const LLUUID& uuid, LLFolderViewModelInterface& root_view_model);
|
||||
LLConversationItemSession(const LLUUID& uuid, LLFolderViewModelInterface& root_view_model);
|
||||
~LLConversationItemSession();
|
||||
|
||||
/*virtual*/ bool hasChildren() const;
|
||||
LLPointer<LLUIImage> getIcon() const { return NULL; }
|
||||
|
|
|
|||
|
|
@ -760,19 +760,6 @@ void LLDrawable::movePartition()
|
|||
if (part)
|
||||
{
|
||||
part->move(this, getSpatialGroup());
|
||||
|
||||
// SL-18251 "On-screen animesh characters using pelvis offset animations
|
||||
// disappear when root goes off-screen"
|
||||
//
|
||||
// Update extents of the root node when Control Avatar changes it's bounds
|
||||
if (mRenderType == LLPipeline::RENDER_TYPE_CONTROL_AV && isRoot())
|
||||
{
|
||||
LLControlAvatar* controlAvatar = dynamic_cast<LLControlAvatar*>(getVObj().get());
|
||||
if (controlAvatar && controlAvatar->mControlAVBridge)
|
||||
{
|
||||
((LLSpatialGroup*)controlAvatar->mControlAVBridge->mOctree->getListener(0))->setState(LLViewerOctreeGroup::DIRTY);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -320,6 +320,7 @@ public:
|
|||
|
||||
if (item)
|
||||
{
|
||||
LLFavoritesBarCtrl::sWaitingForCallabck = 0.f;
|
||||
LLFavoritesOrderStorage::instance().setSortIndex(item, mSortField);
|
||||
|
||||
item->setComplete(TRUE);
|
||||
|
|
@ -365,6 +366,9 @@ struct LLFavoritesSort
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
F64 LLFavoritesBarCtrl::sWaitingForCallabck = 0.f;
|
||||
|
||||
LLFavoritesBarCtrl::Params::Params()
|
||||
: image_drag_indication("image_drag_indication"),
|
||||
more_button("more_button"),
|
||||
|
|
@ -381,7 +385,7 @@ LLFavoritesBarCtrl::LLFavoritesBarCtrl(const LLFavoritesBarCtrl::Params& p)
|
|||
mShowDragMarker(FALSE),
|
||||
mLandingTab(NULL),
|
||||
mLastTab(NULL),
|
||||
mTabsHighlightEnabled(TRUE),
|
||||
mItemsListDirty(false),
|
||||
mUpdateDropDownItems(true),
|
||||
mRestoreOverflowMenu(false),
|
||||
mGetPrevItems(true),
|
||||
|
|
@ -618,6 +622,9 @@ void LLFavoritesBarCtrl::handleNewFavoriteDragAndDrop(LLInventoryItem *item, con
|
|||
int sortField = 0;
|
||||
LLPointer<LLItemCopiedCallback> cb;
|
||||
|
||||
const F64 CALLBACK_WAIT_TIME = 30.f;
|
||||
sWaitingForCallabck = LLTimer::getTotalSeconds() + CALLBACK_WAIT_TIME;
|
||||
|
||||
// current order is saved by setting incremental values (1, 2, 3, ...) for the sort field
|
||||
for (LLInventoryModel::item_array_t::iterator i = mItems.begin(); i != mItems.end(); ++i)
|
||||
{
|
||||
|
|
@ -691,16 +698,22 @@ void LLFavoritesBarCtrl::changed(U32 mask)
|
|||
LLFavoritesOrderStorage::instance().getSLURL((*i)->getAssetUUID());
|
||||
}
|
||||
|
||||
updateButtons();
|
||||
if (!mItemsChangedTimer.getStarted())
|
||||
{
|
||||
mItemsChangedTimer.start();
|
||||
}
|
||||
else
|
||||
{
|
||||
mItemsChangedTimer.reset();
|
||||
}
|
||||
|
||||
if (sWaitingForCallabck < LLTimer::getTotalSeconds())
|
||||
{
|
||||
updateButtons();
|
||||
if (!mItemsChangedTimer.getStarted())
|
||||
{
|
||||
mItemsChangedTimer.start();
|
||||
}
|
||||
else
|
||||
{
|
||||
mItemsChangedTimer.reset();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mItemsListDirty = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -754,6 +767,18 @@ void LLFavoritesBarCtrl::draw()
|
|||
mItemsChangedTimer.start();
|
||||
}
|
||||
|
||||
if (mItemsListDirty && sWaitingForCallabck < LLTimer::getTotalSeconds())
|
||||
{
|
||||
updateButtons();
|
||||
if (!mItemsChangedTimer.getStarted())
|
||||
{
|
||||
mItemsChangedTimer.start();
|
||||
}
|
||||
else
|
||||
{
|
||||
mItemsChangedTimer.reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const LLButton::Params& LLFavoritesBarCtrl::getButtonParams()
|
||||
|
|
@ -782,6 +807,7 @@ void LLFavoritesBarCtrl::updateButtons(bool force_update)
|
|||
return;
|
||||
}
|
||||
|
||||
mItemsListDirty = false;
|
||||
mItems.clear();
|
||||
|
||||
if (!collectFavoriteItems(mItems))
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ public:
|
|||
protected:
|
||||
LLFavoritesBarCtrl(const Params&);
|
||||
friend class LLUICtrlFactory;
|
||||
friend class LLItemCopiedCallback;
|
||||
public:
|
||||
virtual ~LLFavoritesBarCtrl();
|
||||
|
||||
|
|
@ -84,7 +85,6 @@ protected:
|
|||
void onButtonRightClick(LLUUID id,LLView* button,S32 x,S32 y,MASK mask);
|
||||
|
||||
void onButtonMouseDown(LLUUID id, LLUICtrl* button, S32 x, S32 y, MASK mask);
|
||||
void onOverflowMenuItemMouseDown(LLUUID id, LLUICtrl* item, S32 x, S32 y, MASK mask);
|
||||
void onButtonMouseUp(LLUUID id, LLUICtrl* button, S32 x, S32 y, MASK mask);
|
||||
|
||||
void onEndDrag();
|
||||
|
|
@ -164,7 +164,8 @@ private:
|
|||
BOOL mStartDrag;
|
||||
LLInventoryModel::item_array_t mItems;
|
||||
|
||||
BOOL mTabsHighlightEnabled;
|
||||
static F64 sWaitingForCallabck;
|
||||
bool mItemsListDirty;
|
||||
|
||||
S32 mMouseX;
|
||||
S32 mMouseY;
|
||||
|
|
|
|||
|
|
@ -522,6 +522,8 @@ void LLFloaterIMNearbyChatHandler::processChat(const LLChat& chat_msg,
|
|||
// errors in separate window.
|
||||
if (chat_msg.mChatType == CHAT_TYPE_DEBUG_MSG)
|
||||
{
|
||||
if (LLFloater::isQuitRequested()) return;
|
||||
|
||||
if(gSavedSettings.getBOOL("ShowScriptErrors") == FALSE)
|
||||
return;
|
||||
|
||||
|
|
|
|||
|
|
@ -113,6 +113,7 @@
|
|||
#include "llpresetsmanager.h"
|
||||
#include "llviewercontrol.h"
|
||||
#include "llpresetsmanager.h"
|
||||
#include "llinventoryfunctions.h"
|
||||
|
||||
#include "llsearchableui.h"
|
||||
#include "llperfstats.h"
|
||||
|
|
@ -1590,25 +1591,6 @@ void LLFloaterPreference::onChangeMaturity()
|
|||
getChild<LLIconCtrl>("rating_icon_adult")->setVisible(sim_access == SIM_ACCESS_ADULT);
|
||||
}
|
||||
|
||||
std::string get_category_path(LLUUID cat_id)
|
||||
{
|
||||
LLViewerInventoryCategory* cat = gInventory.getCategory(cat_id);
|
||||
std::string localized_cat_name;
|
||||
if (!LLTrans::findString(localized_cat_name, "InvFolder " + cat->getName()))
|
||||
{
|
||||
localized_cat_name = cat->getName();
|
||||
}
|
||||
|
||||
if (cat->getParentUUID().notNull())
|
||||
{
|
||||
return get_category_path(cat->getParentUUID()) + " > " + localized_cat_name;
|
||||
}
|
||||
else
|
||||
{
|
||||
return localized_cat_name;
|
||||
}
|
||||
}
|
||||
|
||||
std::string get_category_path(LLFolderType::EType cat_type)
|
||||
{
|
||||
LLUUID cat_id = gInventory.findUserDefinedCategoryUUIDForType(cat_type);
|
||||
|
|
|
|||
|
|
@ -144,7 +144,7 @@ public:
|
|||
const LLUUID& invoice,
|
||||
const sparam_t& strings);
|
||||
|
||||
LLSD getIDs( sparam_t::const_iterator it, sparam_t::const_iterator end, S32 count );
|
||||
static LLSD getIDs( sparam_t::const_iterator it, sparam_t::const_iterator end, S32 count );
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -2450,11 +2450,12 @@ bool LLDispatchSetEstateAccess::operator()(
|
|||
return true;
|
||||
}
|
||||
|
||||
// static
|
||||
LLSD LLDispatchSetEstateExperience::getIDs( sparam_t::const_iterator it, sparam_t::const_iterator end, S32 count )
|
||||
{
|
||||
LLSD idList = LLSD::emptyArray();
|
||||
LLUUID id;
|
||||
while(count--> 0)
|
||||
while (count-- > 0 && it < end)
|
||||
{
|
||||
memcpy(id.mData, (*(it++)).data(), UUID_BYTES);
|
||||
idList.append(id);
|
||||
|
|
@ -2468,7 +2469,7 @@ LLSD LLDispatchSetEstateExperience::getIDs( sparam_t::const_iterator it, sparam_
|
|||
// strings[2] = str(num blocked)
|
||||
// strings[3] = str(num trusted)
|
||||
// strings[4] = str(num allowed)
|
||||
// strings[8] = bin(uuid) ...
|
||||
// strings[5] = bin(uuid) ...
|
||||
// ...
|
||||
bool LLDispatchSetEstateExperience::operator()(
|
||||
const LLDispatcher* dispatcher,
|
||||
|
|
@ -2477,23 +2478,30 @@ bool LLDispatchSetEstateExperience::operator()(
|
|||
const sparam_t& strings)
|
||||
{
|
||||
LLPanelRegionExperiences* panel = LLFloaterRegionInfo::getPanelExperiences();
|
||||
if (!panel) return true;
|
||||
if (!panel)
|
||||
return true;
|
||||
|
||||
const sparam_t::size_type MIN_SIZE = 5;
|
||||
if (strings.size() < MIN_SIZE)
|
||||
return true;
|
||||
|
||||
// Skip 2 parameters
|
||||
sparam_t::const_iterator it = strings.begin();
|
||||
++it; // U32 estate_id = strtol((*it).c_str(), NULL, 10);
|
||||
++it; // U32 send_to_agent_only = strtoul((*(++it)).c_str(), NULL, 10);
|
||||
|
||||
// Read 3 parameters
|
||||
LLUUID id;
|
||||
S32 num_blocked = strtol((*(it++)).c_str(), NULL, 10);
|
||||
S32 num_trusted = strtol((*(it++)).c_str(), NULL, 10);
|
||||
S32 num_allowed = strtol((*(it++)).c_str(), NULL, 10);
|
||||
|
||||
LLSD ids = LLSD::emptyMap()
|
||||
.with("blocked", getIDs(it, strings.end(), num_blocked))
|
||||
.with("trusted", getIDs(it + (num_blocked), strings.end(), num_trusted))
|
||||
.with("allowed", getIDs(it + (num_blocked+num_trusted), strings.end(), num_allowed));
|
||||
.with("blocked", getIDs(it, strings.end(), num_blocked))
|
||||
.with("trusted", getIDs(it + num_blocked, strings.end(), num_trusted))
|
||||
.with("allowed", getIDs(it + num_blocked + num_trusted, strings.end(), num_allowed));
|
||||
|
||||
panel->processResponse(ids);
|
||||
panel->processResponse(ids);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,14 +67,14 @@ void LLFloaterSidePanelContainer::closeFloater(bool app_quitting)
|
|||
if (parent == this )
|
||||
{
|
||||
LLSidepanelAppearance* panel_appearance = dynamic_cast<LLSidepanelAppearance*>(getPanel("appearance"));
|
||||
if ( panel_appearance )
|
||||
if (panel_appearance)
|
||||
{
|
||||
LLPanelEditWearable *edit_wearable_ptr = panel_appearance->getWearable();
|
||||
if (edit_wearable_ptr)
|
||||
{
|
||||
edit_wearable_ptr->onClose();
|
||||
}
|
||||
if(!app_quitting)
|
||||
if (!app_quitting)
|
||||
{
|
||||
panel_appearance->showOutfitsInventoryPanel();
|
||||
}
|
||||
|
|
@ -116,11 +116,16 @@ LLFloater* LLFloaterSidePanelContainer::getTopmostInventoryFloater()
|
|||
LLPanel* LLFloaterSidePanelContainer::openChildPanel(const std::string& panel_name, const LLSD& params)
|
||||
{
|
||||
LLView* view = findChildView(panel_name, true);
|
||||
if (!view) return NULL;
|
||||
if (!view)
|
||||
return NULL;
|
||||
|
||||
if (!getVisible())
|
||||
{
|
||||
openFloater();
|
||||
openFloater();
|
||||
}
|
||||
else if (!hasFocus())
|
||||
{
|
||||
setFocus(TRUE);
|
||||
}
|
||||
|
||||
LLPanel* panel = NULL;
|
||||
|
|
|
|||
|
|
@ -897,6 +897,15 @@ void LLHUDNameTag::shift(const LLVector3& offset)
|
|||
mPositionAgent += offset;
|
||||
}
|
||||
|
||||
F32 LLHUDNameTag::getWorldHeight() const
|
||||
{
|
||||
const LLViewerCamera* camera = LLViewerCamera::getInstance();
|
||||
F32 height_meters = mLastDistance * (F32)tan(camera->getView() / 2.f);
|
||||
F32 height_pixels = camera->getViewHeightInPixels() / 2.f;
|
||||
F32 meters_per_pixel = height_meters / height_pixels;
|
||||
return mHeight * meters_per_pixel * gViewerWindow->getDisplayScale().mV[VY];
|
||||
}
|
||||
|
||||
//static
|
||||
void LLHUDNameTag::addPickable(std::set<LLViewerObject*> &pick_list)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -127,11 +127,12 @@ public:
|
|||
/*virtual*/ void markDead();
|
||||
friend class LLHUDObject;
|
||||
/*virtual*/ F32 getDistance() const { return mLastDistance; }
|
||||
S32 getLOD() { return mLOD; }
|
||||
BOOL getVisible() { return mVisible; }
|
||||
S32 getLOD() const { return mLOD; }
|
||||
BOOL getVisible() const { return mVisible; }
|
||||
BOOL getHidden() const { return mHidden; }
|
||||
void setHidden( BOOL hide ) { mHidden = hide; }
|
||||
void shift(const LLVector3& offset);
|
||||
F32 getWorldHeight() const;
|
||||
|
||||
BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, LLVector4a& intersection, BOOL debug_render = FALSE);
|
||||
|
||||
|
|
|
|||
|
|
@ -1778,7 +1778,7 @@ void LLItemBridge::performAction(LLInventoryModel* model, std::string action)
|
|||
}
|
||||
else if ("show_in_main_panel" == action)
|
||||
{
|
||||
LLInventoryPanel::openInventoryPanelAndSetSelection(TRUE, mUUID, TRUE);
|
||||
LLInventoryPanel::openInventoryPanelAndSetSelection(true, mUUID, true);
|
||||
return;
|
||||
}
|
||||
else if ("cut" == action)
|
||||
|
|
@ -3409,7 +3409,7 @@ void LLFolderBridge::performAction(LLInventoryModel* model, std::string action)
|
|||
}
|
||||
else if ("show_in_main_panel" == action)
|
||||
{
|
||||
LLInventoryPanel::openInventoryPanelAndSetSelection(TRUE, mUUID, TRUE);
|
||||
LLInventoryPanel::openInventoryPanelAndSetSelection(true, mUUID, true);
|
||||
return;
|
||||
}
|
||||
else if ("cut" == action)
|
||||
|
|
|
|||
|
|
@ -2151,6 +2151,24 @@ void move_items_to_new_subfolder(const uuid_vec_t& selected_uuids, const std::st
|
|||
gInventory.createNewCategory(first_item->getParentUUID(), LLFolderType::FT_NONE, folder_name, func);
|
||||
}
|
||||
|
||||
std::string get_category_path(LLUUID cat_id)
|
||||
{
|
||||
LLViewerInventoryCategory *cat = gInventory.getCategory(cat_id);
|
||||
std::string localized_cat_name;
|
||||
if (!LLTrans::findString(localized_cat_name, "InvFolder " + cat->getName()))
|
||||
{
|
||||
localized_cat_name = cat->getName();
|
||||
}
|
||||
|
||||
if (cat->getParentUUID().notNull())
|
||||
{
|
||||
return get_category_path(cat->getParentUUID()) + " > " + localized_cat_name;
|
||||
}
|
||||
else
|
||||
{
|
||||
return localized_cat_name;
|
||||
}
|
||||
}
|
||||
// Returns true if the item can be moved to Current Outfit or any outfit folder.
|
||||
bool can_move_to_outfit(LLInventoryItem* inv_item, BOOL move_is_into_current_outfit)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -106,6 +106,7 @@ void move_items_to_new_subfolder(const uuid_vec_t& selected_uuids, const std::st
|
|||
void move_items_to_folder(const LLUUID& new_cat_uuid, const uuid_vec_t& selected_uuids);
|
||||
bool is_only_cats_selected(const uuid_vec_t& selected_uuids);
|
||||
bool is_only_items_selected(const uuid_vec_t& selected_uuids);
|
||||
std::string get_category_path(LLUUID cat_id);
|
||||
|
||||
bool can_move_to_outfit(LLInventoryItem* inv_item, BOOL move_is_into_current_outfit);
|
||||
bool can_move_to_landmarks(LLInventoryItem* inv_item);
|
||||
|
|
|
|||
|
|
@ -240,7 +240,7 @@ void LLInventoryItemsList::refresh()
|
|||
case REFRESH_LIST_SORT:
|
||||
{
|
||||
// Filter, sort, rearrange and notify parent about shape changes
|
||||
filterItems();
|
||||
filterItems(true, true);
|
||||
|
||||
if (mAddedItems.size() == 0)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -51,20 +51,20 @@ public:
|
|||
/**
|
||||
* Let list know items need to be refreshed in next doIdle()
|
||||
*/
|
||||
void setNeedsRefresh(bool needs_refresh){ mRefreshState = needs_refresh ? REFRESH_ALL : REFRESH_COMPLETE; }
|
||||
void setNeedsRefresh(bool needs_refresh) { mRefreshState = needs_refresh ? REFRESH_ALL : REFRESH_COMPLETE; }
|
||||
|
||||
U32 getNeedsRefresh(){ return mRefreshState; }
|
||||
U32 getNeedsRefresh() { return mRefreshState; }
|
||||
|
||||
/**
|
||||
* Sets the flag indicating that the list needs to be refreshed even if it is
|
||||
* not currently visible.
|
||||
*/
|
||||
void setForceRefresh(bool force_refresh){ mForceRefresh = force_refresh; }
|
||||
void setForceRefresh(bool force_refresh) { mForceRefresh = force_refresh; }
|
||||
|
||||
/**
|
||||
* If refreshes when invisible.
|
||||
*/
|
||||
bool getForceRefresh(){ return mForceRefresh; }
|
||||
bool getForceRefresh() { return mForceRefresh; }
|
||||
|
||||
virtual bool selectItemByValue(const LLSD& value, bool select = true);
|
||||
|
||||
|
|
|
|||
|
|
@ -1887,46 +1887,52 @@ LLInventoryPanel* LLInventoryPanel::getActiveInventoryPanel(BOOL auto_open)
|
|||
}
|
||||
|
||||
//static
|
||||
void LLInventoryPanel::openInventoryPanelAndSetSelection(BOOL auto_open, const LLUUID& obj_id, BOOL use_main_panel, BOOL take_keyboard_focus, BOOL reset_filter)
|
||||
void LLInventoryPanel::openInventoryPanelAndSetSelection(bool auto_open, const LLUUID& obj_id,
|
||||
bool use_main_panel, bool take_keyboard_focus, bool reset_filter)
|
||||
{
|
||||
LLSidepanelInventory* sidepanel_inventory = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory");
|
||||
sidepanel_inventory->showInventoryPanel();
|
||||
|
||||
bool in_inbox = (gInventory.isObjectDescendentOf(obj_id, gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX)));
|
||||
|
||||
if (!in_inbox && (use_main_panel || !sidepanel_inventory->getMainInventoryPanel()->isRecentItemsPanelSelected()))
|
||||
LLUUID cat_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX);
|
||||
bool in_inbox = gInventory.isObjectDescendentOf(obj_id, cat_id);
|
||||
if (!in_inbox && use_main_panel)
|
||||
{
|
||||
sidepanel_inventory->selectAllItemsPanel();
|
||||
}
|
||||
|
||||
LLFloater* inventory_floater = LLFloaterSidePanelContainer::getTopmostInventoryFloater();
|
||||
if(!auto_open && inventory_floater && inventory_floater->getVisible())
|
||||
if (!auto_open)
|
||||
{
|
||||
LLSidepanelInventory *inventory_panel = inventory_floater->findChild<LLSidepanelInventory>("main_panel");
|
||||
LLPanelMainInventory* main_panel = inventory_panel->getMainInventoryPanel();
|
||||
if(main_panel->isSingleFolderMode() && main_panel->isGalleryViewMode())
|
||||
LLFloater* inventory_floater = LLFloaterSidePanelContainer::getTopmostInventoryFloater();
|
||||
if (inventory_floater && inventory_floater->getVisible())
|
||||
{
|
||||
LL_DEBUGS("Inventory") << "Opening gallery panel for item" << obj_id << LL_ENDL;
|
||||
main_panel->setGallerySelection(obj_id);
|
||||
return;
|
||||
LLSidepanelInventory *inventory_panel = inventory_floater->findChild<LLSidepanelInventory>("main_panel");
|
||||
LLPanelMainInventory* main_panel = inventory_panel->getMainInventoryPanel();
|
||||
if (main_panel->isSingleFolderMode() && main_panel->isGalleryViewMode())
|
||||
{
|
||||
LL_DEBUGS("Inventory") << "Opening gallery panel for item" << obj_id << LL_ENDL;
|
||||
main_panel->setGallerySelection(obj_id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LLPanelMainInventory* main_inventory = sidepanel_inventory->getMainInventoryPanel();
|
||||
if (main_inventory && main_inventory->isSingleFolderMode()
|
||||
&& use_main_panel)
|
||||
if (use_main_panel)
|
||||
{
|
||||
const LLInventoryObject *obj = gInventory.getObject(obj_id);
|
||||
if (obj)
|
||||
LLPanelMainInventory* main_inventory = sidepanel_inventory->getMainInventoryPanel();
|
||||
if (main_inventory && main_inventory->isSingleFolderMode())
|
||||
{
|
||||
LL_DEBUGS("Inventory") << "Opening main inventory panel for item" << obj_id << LL_ENDL;
|
||||
main_inventory->setSingleFolderViewRoot(obj->getParentUUID(), false);
|
||||
main_inventory->setGallerySelection(obj_id);
|
||||
return;
|
||||
const LLInventoryObject *obj = gInventory.getObject(obj_id);
|
||||
if (obj)
|
||||
{
|
||||
LL_DEBUGS("Inventory") << "Opening main inventory panel for item" << obj_id << LL_ENDL;
|
||||
main_inventory->setSingleFolderViewRoot(obj->getParentUUID(), false);
|
||||
main_inventory->setGallerySelection(obj_id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel(auto_open);
|
||||
|
||||
if (active_panel)
|
||||
{
|
||||
LL_DEBUGS("Messaging", "Inventory") << "Highlighting" << obj_id << LL_ENDL;
|
||||
|
|
@ -1938,11 +1944,8 @@ void LLInventoryPanel::openInventoryPanelAndSetSelection(BOOL auto_open, const L
|
|||
|
||||
if (in_inbox)
|
||||
{
|
||||
|
||||
LLInventoryPanel * inventory_panel = NULL;
|
||||
sidepanel_inventory->openInbox();
|
||||
inventory_panel = sidepanel_inventory->getInboxPanel();
|
||||
|
||||
LLInventoryPanel* inventory_panel = sidepanel_inventory->getInboxPanel();
|
||||
if (inventory_panel)
|
||||
{
|
||||
inventory_panel->setSelection(obj_id, take_keyboard_focus);
|
||||
|
|
@ -1967,7 +1970,6 @@ void LLInventoryPanel::openInventoryPanelAndSetSelection(BOOL auto_open, const L
|
|||
|
||||
void LLInventoryPanel::setSFViewAndOpenFolder(const LLInventoryPanel* panel, const LLUUID& folder_id)
|
||||
{
|
||||
|
||||
LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("inventory");
|
||||
for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin(); iter != inst_list.end(); ++iter)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -244,12 +244,12 @@ public:
|
|||
// "Auto_open" determines if we open an inventory panel if none are open.
|
||||
static LLInventoryPanel *getActiveInventoryPanel(BOOL auto_open = TRUE);
|
||||
|
||||
static void openInventoryPanelAndSetSelection(BOOL auto_open,
|
||||
static void openInventoryPanelAndSetSelection(bool auto_open,
|
||||
const LLUUID& obj_id,
|
||||
BOOL use_main_panel = FALSE,
|
||||
BOOL take_keyboard_focus = TAKE_FOCUS_YES,
|
||||
BOOL reset_filter = FALSE);
|
||||
static void setSFViewAndOpenFolder(const LLInventoryPanel* panel, const LLUUID& folder_id);
|
||||
bool use_main_panel = false,
|
||||
bool take_keyboard_focus = true,
|
||||
bool reset_filter = false);
|
||||
static void setSFViewAndOpenFolder(const LLInventoryPanel* panel, const LLUUID& folder_id);
|
||||
void addItemID(const LLUUID& id, LLFolderViewItem* itemp);
|
||||
void removeItemID(const LLUUID& id);
|
||||
LLFolderViewItem* getItemByID(const LLUUID& id);
|
||||
|
|
|
|||
|
|
@ -1081,6 +1081,13 @@ bool LLLocalBitmapMgr::checkTextureDimensions(std::string filename)
|
|||
LLImageDimensionsInfo image_info;
|
||||
if (!image_info.load(filename,codec))
|
||||
{
|
||||
LLSD args;
|
||||
args["NAME"] = gDirUtilp->getBaseFileName(filename);
|
||||
if (!image_info.getWarningName().empty())
|
||||
{
|
||||
args["REASON"] = LLTrans::getString(image_info.getWarningName());
|
||||
}
|
||||
LLNotificationsUtil::add("CannotUploadTexture", args);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -1096,6 +1103,7 @@ bool LLLocalBitmapMgr::checkTextureDimensions(std::string filename)
|
|||
|
||||
LLSD notif_args;
|
||||
notif_args["REASON"] = mImageLoadError;
|
||||
notif_args["NAME"] = gDirUtilp->getBaseFileName(filename);
|
||||
LLNotificationsUtil::add("CannotUploadTexture", notif_args);
|
||||
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -5503,7 +5503,7 @@ void on_new_single_inventory_upload_complete(
|
|||
}
|
||||
else
|
||||
{
|
||||
LLInventoryPanel::openInventoryPanelAndSetSelection(TRUE, server_response["new_inventory_item"].asUUID(), TRUE, TAKE_FOCUS_NO, TRUE);
|
||||
LLInventoryPanel::openInventoryPanelAndSetSelection(true, server_response["new_inventory_item"].asUUID(), true, false, true);
|
||||
}
|
||||
|
||||
// restore keyboard focus
|
||||
|
|
|
|||
|
|
@ -249,7 +249,7 @@ void LLModelPreview::updateDimentionsAndOffsets()
|
|||
{
|
||||
accounted.insert(instance.mModel);
|
||||
|
||||
//update instance skin info for each lods pelvisZoffset
|
||||
// update instance skin info for each lods pelvisZoffset
|
||||
for (int j = 0; j<LLModel::NUM_LODS; ++j)
|
||||
{
|
||||
if (instance.mLOD[j])
|
||||
|
|
@ -271,6 +271,7 @@ void LLModelPreview::rebuildUploadData()
|
|||
{
|
||||
assert_main_thread();
|
||||
|
||||
mDefaultPhysicsShapeP = NULL;
|
||||
mUploadData.clear();
|
||||
mTextureSet.clear();
|
||||
|
||||
|
|
@ -310,7 +311,7 @@ void LLModelPreview::rebuildUploadData()
|
|||
mat *= scale_mat;
|
||||
|
||||
for (LLModelLoader::model_instance_list::iterator model_iter = iter->second.begin(); model_iter != iter->second.end();)
|
||||
{ //for each instance with said transform applied
|
||||
{ // for each instance with said transform applied
|
||||
LLModelInstance instance = *model_iter++;
|
||||
|
||||
LLModel* base_model = instance.mModel;
|
||||
|
|
@ -573,7 +574,7 @@ void LLModelPreview::rebuildUploadData()
|
|||
else if (getLoadState() == LLModelLoader::ERROR_MATERIALS
|
||||
|| getLoadState() == LLModelLoader::WARNING_BIND_SHAPE_ORIENTATION)
|
||||
{
|
||||
// This is only valid for these two error types because they are
|
||||
// This is only valid for these two error types because they are
|
||||
// only used inside rebuildUploadData() and updateStatusMessages()
|
||||
// updateStatusMessages() is called after rebuildUploadData()
|
||||
setLoadState(LLModelLoader::DONE);
|
||||
|
|
@ -798,7 +799,7 @@ void LLModelPreview::loadModel(std::string filename, S32 lod, bool force_disable
|
|||
// it tends to force the UI into strange checkbox options
|
||||
// which cannot be altered.
|
||||
|
||||
//only try to load from slm if viewer is configured to do so and this is the
|
||||
//only try to load from slm if viewer is configured to do so and this is the
|
||||
//initial model load (not an LoD or physics shape)
|
||||
mModelLoader->mTrySLM = gSavedSettings.getBOOL("MeshImportUseSLM") && mUploadData.empty();
|
||||
}
|
||||
|
|
@ -884,12 +885,13 @@ void LLModelPreview::clearIncompatible(S32 lod)
|
|||
|
||||
// Check if already started
|
||||
bool subscribe_for_generation = mLodsQuery.empty();
|
||||
|
||||
|
||||
// Remove previously scheduled work
|
||||
mLodsQuery.clear();
|
||||
|
||||
LLFloaterModelPreview* fmp = LLFloaterModelPreview::sInstance;
|
||||
if (!fmp) return;
|
||||
if (!fmp)
|
||||
return;
|
||||
|
||||
// Schedule new work
|
||||
for (S32 i = LLModel::LOD_HIGH; i >= 0; --i)
|
||||
|
|
@ -1719,7 +1721,7 @@ F32 LLModelPreview::genMeshOptimizerPerFace(LLModel *base_model, LLModel *target
|
|||
|
||||
ll_aligned_free_16(output_indices);
|
||||
ll_aligned_free_16(shadow_indices);
|
||||
|
||||
|
||||
if (size_new_indices < 3)
|
||||
{
|
||||
// At least one triangle is needed
|
||||
|
|
@ -1912,7 +1914,7 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d
|
|||
{
|
||||
precise_ratio = genMeshOptimizerPerModel(base, target_model, indices_decimator, lod_error_threshold, MESH_OPTIMIZER_NO_UVS);
|
||||
}
|
||||
|
||||
|
||||
if (precise_ratio < 0 || (precise_ratio * allowed_ratio_drift < indices_decimator))
|
||||
{
|
||||
// Try sloppy variant if normal one failed to simplify model enough.
|
||||
|
|
|
|||
|
|
@ -433,8 +433,7 @@ bool compareGalleryItem(LLOutfitGalleryItem* item1, LLOutfitGalleryItem* item2)
|
|||
}
|
||||
|
||||
void LLOutfitGallery::reArrangeRows(S32 row_diff)
|
||||
{
|
||||
|
||||
{
|
||||
std::vector<LLOutfitGalleryItem*> buf_items = mItems;
|
||||
for (std::vector<LLOutfitGalleryItem*>::const_reverse_iterator it = buf_items.rbegin(); it != buf_items.rend(); ++it)
|
||||
{
|
||||
|
|
@ -446,16 +445,24 @@ void LLOutfitGallery::reArrangeRows(S32 row_diff)
|
|||
}
|
||||
mHiddenItems.clear();
|
||||
|
||||
mItemsInRow+= row_diff;
|
||||
mItemsInRow += row_diff;
|
||||
updateGalleryWidth();
|
||||
std::sort(buf_items.begin(), buf_items.end(), compareGalleryItem);
|
||||
|
||||
|
||||
std::string cur_filter = getFilterSubString();
|
||||
LLStringUtil::toUpper(cur_filter);
|
||||
|
||||
for (std::vector<LLOutfitGalleryItem*>::const_iterator it = buf_items.begin(); it != buf_items.end(); ++it)
|
||||
{
|
||||
(*it)->setHidden(false);
|
||||
applyFilter(*it,sFilterSubString);
|
||||
std::string outfit_name = (*it)->getItemName();
|
||||
LLStringUtil::toUpper(outfit_name);
|
||||
|
||||
bool hidden = (std::string::npos == outfit_name.find(cur_filter));
|
||||
(*it)->setHidden(hidden);
|
||||
|
||||
addToGallery(*it);
|
||||
}
|
||||
|
||||
updateMessageVisibility();
|
||||
}
|
||||
|
||||
|
|
@ -725,9 +732,9 @@ LLOutfitGallery::~LLOutfitGallery()
|
|||
}
|
||||
}
|
||||
|
||||
void LLOutfitGallery::setFilterSubString(const std::string& string)
|
||||
// virtual
|
||||
void LLOutfitGallery::onFilterSubStringChanged(const std::string& new_string, const std::string& old_string)
|
||||
{
|
||||
sFilterSubString = string;
|
||||
reArrangeRows();
|
||||
}
|
||||
|
||||
|
|
@ -743,20 +750,6 @@ void LLOutfitGallery::onHighlightBaseOutfit(LLUUID base_id, LLUUID prev_id)
|
|||
}
|
||||
}
|
||||
|
||||
void LLOutfitGallery::applyFilter(LLOutfitGalleryItem* item, const std::string& filter_substring)
|
||||
{
|
||||
if (!item) return;
|
||||
|
||||
std::string outfit_name = item->getItemName();
|
||||
LLStringUtil::toUpper(outfit_name);
|
||||
|
||||
std::string cur_filter = filter_substring;
|
||||
LLStringUtil::toUpper(cur_filter);
|
||||
|
||||
bool hidden = (std::string::npos == outfit_name.find(cur_filter));
|
||||
item->setHidden(hidden);
|
||||
}
|
||||
|
||||
void LLOutfitGallery::onSetSelectedOutfitByUUID(const LLUUID& outfit_uuid)
|
||||
{
|
||||
}
|
||||
|
|
@ -904,11 +897,11 @@ bool LLOutfitGallery::hasDefaultImage(const LLUUID& outfit_cat_id)
|
|||
|
||||
void LLOutfitGallery::updateMessageVisibility()
|
||||
{
|
||||
if(mItems.empty())
|
||||
if (mItems.empty())
|
||||
{
|
||||
mMessageTextBox->setVisible(TRUE);
|
||||
mScrollPanel->setVisible(FALSE);
|
||||
std::string message = sFilterSubString.empty()? getString("no_outfits_msg") : getString("no_matched_outfits_msg");
|
||||
std::string message = getString(getFilterSubString().empty() ? "no_outfits_msg" : "no_matched_outfits_msg");
|
||||
mMessageTextBox->setValue(message);
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ public:
|
|||
void wearSelectedOutfit();
|
||||
|
||||
|
||||
/*virtual*/ void setFilterSubString(const std::string& string);
|
||||
/*virtual*/ void onFilterSubStringChanged(const std::string& new_string, const std::string& old_string);
|
||||
|
||||
/*virtual*/ void getCurrentCategories(uuid_vec_t& vcur);
|
||||
/*virtual*/ void updateAddedCategory(LLUUID cat_id);
|
||||
|
|
@ -117,8 +117,6 @@ protected:
|
|||
/*virtual*/ void onExpandAllFolders() {}
|
||||
/*virtual*/ LLOutfitListGearMenuBase* createGearMenu();
|
||||
|
||||
void applyFilter(LLOutfitGalleryItem* item, const std::string& filter_substring);
|
||||
|
||||
private:
|
||||
LLUUID getPhotoAssetId(const LLUUID& outfit_id);
|
||||
LLUUID getDefaultPhoto();
|
||||
|
|
|
|||
|
|
@ -188,7 +188,7 @@ void LLOutfitsList::updateAddedCategory(LLUUID cat_id)
|
|||
list->setCommitCallback(boost::bind(&LLOutfitsList::onListSelectionChange, this, _1));
|
||||
|
||||
// Setting list refresh callback to apply filter on list change.
|
||||
list->setRefreshCompleteCallback(boost::bind(&LLOutfitsList::onFilteredWearableItemsListRefresh, this, _1));
|
||||
list->setRefreshCompleteCallback(boost::bind(&LLOutfitsList::onRefreshComplete, this, _1));
|
||||
|
||||
list->setRightMouseDownCallback(boost::bind(&LLOutfitsList::onWearableItemsListRightClick, this, _1, _2, _3));
|
||||
|
||||
|
|
@ -199,19 +199,17 @@ void LLOutfitsList::updateAddedCategory(LLUUID cat_id)
|
|||
// Further list updates will be triggered by the category observer.
|
||||
list->updateList(cat_id);
|
||||
|
||||
// If filter is currently applied we store the initial tab state and
|
||||
// open it to show matched items if any.
|
||||
if (!sFilterSubString.empty())
|
||||
// If filter is currently applied we store the initial tab state.
|
||||
if (!getFilterSubString().empty())
|
||||
{
|
||||
tab->notifyChildren(LLSD().with("action", "store_state"));
|
||||
tab->setDisplayChildren(true);
|
||||
|
||||
// Setting mForceRefresh flag will make the list refresh its contents
|
||||
// even if it is not currently visible. This is required to apply the
|
||||
// filter to the newly added list.
|
||||
list->setForceRefresh(true);
|
||||
|
||||
list->setFilterSubString(sFilterSubString);
|
||||
list->setFilterSubString(getFilterSubString(), false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -313,14 +311,6 @@ void LLOutfitsList::onSetSelectedOutfitByUUID(const LLUUID& outfit_uuid)
|
|||
}
|
||||
}
|
||||
|
||||
// virtual
|
||||
void LLOutfitsList::setFilterSubString(const std::string& string)
|
||||
{
|
||||
applyFilter(string);
|
||||
|
||||
sFilterSubString = string;
|
||||
}
|
||||
|
||||
// virtual
|
||||
bool LLOutfitListBase::isActionEnabled(const LLSD& userdata)
|
||||
{
|
||||
|
|
@ -494,9 +484,9 @@ void LLOutfitsList::restoreOutfitSelection(LLAccordionCtrlTab* tab, const LLUUID
|
|||
}
|
||||
}
|
||||
|
||||
void LLOutfitsList::onFilteredWearableItemsListRefresh(LLUICtrl* ctrl)
|
||||
void LLOutfitsList::onRefreshComplete(LLUICtrl* ctrl)
|
||||
{
|
||||
if (!ctrl || sFilterSubString.empty())
|
||||
if (!ctrl || getFilterSubString().empty())
|
||||
return;
|
||||
|
||||
for (outfits_map_t::iterator
|
||||
|
|
@ -510,57 +500,50 @@ void LLOutfitsList::onFilteredWearableItemsListRefresh(LLUICtrl* ctrl)
|
|||
LLWearableItemsList* list = dynamic_cast<LLWearableItemsList*>(tab->getAccordionView());
|
||||
if (list != ctrl) continue;
|
||||
|
||||
applyFilterToTab(iter->first, tab, sFilterSubString);
|
||||
applyFilterToTab(iter->first, tab, getFilterSubString());
|
||||
}
|
||||
}
|
||||
|
||||
void LLOutfitsList::applyFilter(const std::string& new_filter_substring)
|
||||
// virtual
|
||||
void LLOutfitsList::onFilterSubStringChanged(const std::string& new_string, const std::string& old_string)
|
||||
{
|
||||
mAccordion->setFilterSubString(new_filter_substring);
|
||||
mAccordion->setFilterSubString(new_string);
|
||||
|
||||
for (outfits_map_t::iterator
|
||||
iter = mOutfitsMap.begin(),
|
||||
iter_end = mOutfitsMap.end();
|
||||
iter != iter_end; ++iter)
|
||||
outfits_map_t::iterator iter = mOutfitsMap.begin(), iter_end = mOutfitsMap.end();
|
||||
while (iter != iter_end)
|
||||
{
|
||||
LLAccordionCtrlTab* tab = iter->second;
|
||||
const LLUUID& category_id = iter->first;
|
||||
LLAccordionCtrlTab* tab = iter++->second;
|
||||
if (!tab) continue;
|
||||
|
||||
bool more_restrictive = sFilterSubString.size() < new_filter_substring.size() && !new_filter_substring.substr(0, sFilterSubString.size()).compare(sFilterSubString);
|
||||
|
||||
// Restore tab visibility in case of less restrictive filter
|
||||
// to compare it with updated string if it was previously hidden.
|
||||
if (!more_restrictive)
|
||||
{
|
||||
tab->setVisible(TRUE);
|
||||
}
|
||||
|
||||
LLWearableItemsList* list = dynamic_cast<LLWearableItemsList*>(tab->getAccordionView());
|
||||
if (list)
|
||||
{
|
||||
list->setFilterSubString(new_filter_substring);
|
||||
list->setFilterSubString(new_string, tab->getDisplayChildren());
|
||||
}
|
||||
|
||||
if(sFilterSubString.empty() && !new_filter_substring.empty())
|
||||
if (old_string.empty())
|
||||
{
|
||||
//store accordion tab state when filter is not empty
|
||||
tab->notifyChildren(LLSD().with("action","store_state"));
|
||||
// Store accordion tab state when filter is not empty
|
||||
tab->notifyChildren(LLSD().with("action", "store_state"));
|
||||
}
|
||||
|
||||
if (!new_filter_substring.empty())
|
||||
if (!new_string.empty())
|
||||
{
|
||||
applyFilterToTab(iter->first, tab, new_filter_substring);
|
||||
applyFilterToTab(category_id, tab, new_string);
|
||||
}
|
||||
else
|
||||
{
|
||||
// restore tab title when filter is empty
|
||||
tab->setVisible(TRUE);
|
||||
|
||||
// Restore tab title when filter is empty
|
||||
tab->setTitle(tab->getTitle());
|
||||
|
||||
//restore accordion state after all those accodrion tab manipulations
|
||||
tab->notifyChildren(LLSD().with("action","restore_state"));
|
||||
// Restore accordion state after all those accodrion tab manipulations
|
||||
tab->notifyChildren(LLSD().with("action", "restore_state"));
|
||||
|
||||
// Try restoring the tab selection.
|
||||
restoreOutfitSelection(tab, iter->first);
|
||||
restoreOutfitSelection(tab, category_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -586,11 +569,11 @@ void LLOutfitsList::applyFilterToTab(
|
|||
|
||||
if (std::string::npos == title.find(cur_filter))
|
||||
{
|
||||
// hide tab if its title doesn't pass filter
|
||||
// and it has no visible items
|
||||
// Hide tab if its title doesn't pass filter
|
||||
// and it has no matched items
|
||||
tab->setVisible(list->hasMatchedItems());
|
||||
|
||||
// remove title highlighting because it might
|
||||
// Remove title highlighting because it might
|
||||
// have been previously highlighted by less restrictive filter
|
||||
tab->setTitle(tab->getTitle());
|
||||
|
||||
|
|
@ -602,18 +585,6 @@ void LLOutfitsList::applyFilterToTab(
|
|||
// Try restoring the tab selection.
|
||||
restoreOutfitSelection(tab, category_id);
|
||||
}
|
||||
|
||||
if (tab->getVisible())
|
||||
{
|
||||
// Open tab if it has passed the filter.
|
||||
tab->setDisplayChildren(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Set force refresh flag to refresh not visible list
|
||||
// when some changes occur in it.
|
||||
list->setForceRefresh(true);
|
||||
}
|
||||
}
|
||||
|
||||
bool LLOutfitsList::canWearSelected()
|
||||
|
|
@ -698,11 +669,10 @@ void LLOutfitsList::onCOFChanged()
|
|||
// These links UUIDs are not the same UUIDs that we have in each wearable items list.
|
||||
// So we collect base items' UUIDs to find them or links that point to them in wearable
|
||||
// items lists and update their worn state there.
|
||||
for (LLInventoryModel::item_array_t::const_iterator iter = item_array.begin();
|
||||
iter != item_array.end();
|
||||
++iter)
|
||||
LLInventoryModel::item_array_t::const_iterator array_iter = item_array.begin(), array_end = item_array.end();
|
||||
while (array_iter < array_end)
|
||||
{
|
||||
vnew.push_back((*iter)->getLinkedUUID());
|
||||
vnew.push_back((*(array_iter++))->getLinkedUUID());
|
||||
}
|
||||
|
||||
// We need to update only items that were added or removed from COF.
|
||||
|
|
@ -711,20 +681,20 @@ void LLOutfitsList::onCOFChanged()
|
|||
// Store the ids of items currently linked from COF.
|
||||
mCOFLinkedItems = vnew;
|
||||
|
||||
for (outfits_map_t::iterator iter = mOutfitsMap.begin();
|
||||
iter != mOutfitsMap.end();
|
||||
++iter)
|
||||
// Append removed ids to added ids because we should update all of them.
|
||||
vadded.reserve(vadded.size() + vremoved.size());
|
||||
vadded.insert(vadded.end(), vremoved.begin(), vremoved.end());
|
||||
vremoved.clear();
|
||||
|
||||
outfits_map_t::iterator map_iter = mOutfitsMap.begin(), map_end = mOutfitsMap.end();
|
||||
while (map_iter != map_end)
|
||||
{
|
||||
LLAccordionCtrlTab* tab = iter->second;
|
||||
LLAccordionCtrlTab* tab = (map_iter++)->second;
|
||||
if (!tab) continue;
|
||||
|
||||
LLWearableItemsList* list = dynamic_cast<LLWearableItemsList*>(tab->getAccordionView());
|
||||
if (!list) continue;
|
||||
|
||||
// Append removed ids to added ids because we should update all of them.
|
||||
vadded.reserve(vadded.size() + vremoved.size());
|
||||
vadded.insert(vadded.end(), vremoved.begin(), vremoved.end());
|
||||
|
||||
// Every list updates the labels of changed items or
|
||||
// the links that point to these items.
|
||||
list->updateChangedItems(vadded);
|
||||
|
|
@ -835,7 +805,6 @@ void LLOutfitListBase::onOpen(const LLSD& info)
|
|||
// arrive.
|
||||
category->fetch();
|
||||
refreshList(outfits);
|
||||
highlightBaseOutfit();
|
||||
|
||||
mIsInitialized = true;
|
||||
}
|
||||
|
|
@ -843,6 +812,9 @@ void LLOutfitListBase::onOpen(const LLSD& info)
|
|||
|
||||
void LLOutfitListBase::refreshList(const LLUUID& category_id)
|
||||
{
|
||||
bool wasNull = mRefreshListState.CategoryUUID.isNull();
|
||||
mRefreshListState.CategoryUUID.setNull();
|
||||
|
||||
LLInventoryModel::cat_array_t cat_array;
|
||||
LLInventoryModel::item_array_t item_array;
|
||||
|
||||
|
|
@ -855,27 +827,81 @@ void LLOutfitListBase::refreshList(const LLUUID& category_id)
|
|||
LLInventoryModel::EXCLUDE_TRASH,
|
||||
is_category);
|
||||
|
||||
uuid_vec_t vadded;
|
||||
uuid_vec_t vremoved;
|
||||
// Memorize item names for each UUID
|
||||
std::map<LLUUID, std::string> names;
|
||||
for (const LLPointer<LLViewerInventoryCategory>& cat : cat_array)
|
||||
{
|
||||
names.emplace(std::make_pair(cat->getUUID(), cat->getName()));
|
||||
}
|
||||
|
||||
// Create added and removed items vectors.
|
||||
computeDifference(cat_array, vadded, vremoved);
|
||||
// Fill added and removed items vectors.
|
||||
mRefreshListState.Added.clear();
|
||||
mRefreshListState.Removed.clear();
|
||||
computeDifference(cat_array, mRefreshListState.Added, mRefreshListState.Removed);
|
||||
// Sort added items vector by item name.
|
||||
std::sort(mRefreshListState.Added.begin(), mRefreshListState.Added.end(),
|
||||
[names](const LLUUID& a, const LLUUID& b)
|
||||
{
|
||||
return LLStringUtil::compareDict(names.at(a), names.at(b)) < 0;
|
||||
});
|
||||
// Initialize iterators for added and removed items vectors.
|
||||
mRefreshListState.AddedIterator = mRefreshListState.Added.begin();
|
||||
mRefreshListState.RemovedIterator = mRefreshListState.Removed.begin();
|
||||
|
||||
LL_INFOS() << "added: " << mRefreshListState.Added.size() <<
|
||||
", removed: " << mRefreshListState.Removed.size() <<
|
||||
", changed: " << gInventory.getChangedIDs().size() <<
|
||||
LL_ENDL;
|
||||
|
||||
mRefreshListState.CategoryUUID = category_id;
|
||||
if (wasNull)
|
||||
{
|
||||
gIdleCallbacks.addFunction(onIdle, this);
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void LLOutfitListBase::onIdle(void* userdata)
|
||||
{
|
||||
LLOutfitListBase* self = (LLOutfitListBase*)userdata;
|
||||
|
||||
self->onIdleRefreshList();
|
||||
}
|
||||
|
||||
void LLOutfitListBase::onIdleRefreshList()
|
||||
{
|
||||
if (mRefreshListState.CategoryUUID.isNull())
|
||||
return;
|
||||
|
||||
const F64 MAX_TIME = 0.05f;
|
||||
F64 curent_time = LLTimer::getTotalSeconds();
|
||||
const F64 end_time = curent_time + MAX_TIME;
|
||||
|
||||
// Handle added tabs.
|
||||
for (uuid_vec_t::const_iterator iter = vadded.begin();
|
||||
iter != vadded.end();
|
||||
++iter)
|
||||
while (mRefreshListState.AddedIterator < mRefreshListState.Added.end())
|
||||
{
|
||||
const LLUUID cat_id = (*iter);
|
||||
const LLUUID cat_id = (*mRefreshListState.AddedIterator++);
|
||||
updateAddedCategory(cat_id);
|
||||
|
||||
curent_time = LLTimer::getTotalSeconds();
|
||||
if (curent_time >= end_time)
|
||||
return;
|
||||
}
|
||||
mRefreshListState.Added.clear();
|
||||
mRefreshListState.AddedIterator = mRefreshListState.Added.end();
|
||||
|
||||
// Handle removed tabs.
|
||||
for (uuid_vec_t::const_iterator iter = vremoved.begin(); iter != vremoved.end(); ++iter)
|
||||
while (mRefreshListState.RemovedIterator < mRefreshListState.Removed.end())
|
||||
{
|
||||
const LLUUID cat_id = (*iter);
|
||||
const LLUUID cat_id = (*mRefreshListState.RemovedIterator++);
|
||||
updateRemovedCategory(cat_id);
|
||||
|
||||
curent_time = LLTimer::getTotalSeconds();
|
||||
if (curent_time >= end_time)
|
||||
return;
|
||||
}
|
||||
mRefreshListState.Removed.clear();
|
||||
mRefreshListState.RemovedIterator = mRefreshListState.Removed.end();
|
||||
|
||||
// Get changed items from inventory model and update outfit tabs
|
||||
// which might have been renamed.
|
||||
|
|
@ -888,9 +914,9 @@ void LLOutfitListBase::refreshList(const LLUUID& category_id)
|
|||
if (!cat)
|
||||
{
|
||||
LLInventoryObject* obj = gInventory.getObject(*items_iter);
|
||||
if(!obj || (obj->getType() != LLAssetType::AT_CATEGORY))
|
||||
if (!obj || (obj->getType() != LLAssetType::AT_CATEGORY))
|
||||
{
|
||||
return;
|
||||
break;
|
||||
}
|
||||
cat = (LLViewerInventoryCategory*)obj;
|
||||
}
|
||||
|
|
@ -900,6 +926,12 @@ void LLOutfitListBase::refreshList(const LLUUID& category_id)
|
|||
}
|
||||
|
||||
sortOutfits();
|
||||
highlightBaseOutfit();
|
||||
|
||||
gIdleCallbacks.deleteFunction(onIdle, this);
|
||||
mRefreshListState.CategoryUUID.setNull();
|
||||
|
||||
LL_INFOS() << "done" << LL_ENDL;
|
||||
}
|
||||
|
||||
void LLOutfitListBase::computeDifference(
|
||||
|
|
@ -936,7 +968,6 @@ void LLOutfitListBase::highlightBaseOutfit()
|
|||
mHighlightedOutfitUUID = base_id;
|
||||
onHighlightBaseOutfit(base_id, prev_id);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void LLOutfitListBase::removeSelected()
|
||||
|
|
|
|||
|
|
@ -116,8 +116,20 @@ protected:
|
|||
void onOutfitsRemovalConfirmation(const LLSD& notification, const LLSD& response);
|
||||
virtual void onChangeOutfitSelection(LLWearableItemsList* list, const LLUUID& category_id) = 0;
|
||||
|
||||
static void onIdle(void* userdata);
|
||||
void onIdleRefreshList();
|
||||
|
||||
struct
|
||||
{
|
||||
LLUUID CategoryUUID;
|
||||
uuid_vec_t Added;
|
||||
uuid_vec_t Removed;
|
||||
uuid_vec_t::const_iterator AddedIterator;
|
||||
uuid_vec_t::const_iterator RemovedIterator;
|
||||
} mRefreshListState;
|
||||
|
||||
bool mIsInitialized;
|
||||
LLInventoryCategoriesObserver* mCategoriesObserver;
|
||||
LLInventoryCategoriesObserver* mCategoriesObserver;
|
||||
LLUUID mSelectedOutfitUUID;
|
||||
// id of currently highlited outfit
|
||||
LLUUID mHighlightedOutfitUUID;
|
||||
|
|
@ -225,7 +237,7 @@ public:
|
|||
//void performAction(std::string action);
|
||||
|
||||
|
||||
/*virtual*/ void setFilterSubString(const std::string& string);
|
||||
/*virtual*/ void onFilterSubStringChanged(const std::string& new_string, const std::string& old_string);
|
||||
|
||||
/*virtual*/ void getSelectedItemsUUIDs(uuid_vec_t& selected_uuids) const;
|
||||
|
||||
|
|
@ -295,12 +307,7 @@ private:
|
|||
* Called upon list refresh event to update tab visibility depending on
|
||||
* the results of applying filter to the title and list items of the tab.
|
||||
*/
|
||||
void onFilteredWearableItemsListRefresh(LLUICtrl* ctrl);
|
||||
|
||||
/**
|
||||
* Highlights filtered items and hides tabs which haven't passed filter.
|
||||
*/
|
||||
void applyFilter(const std::string& new_filter_substring);
|
||||
void onRefreshComplete(LLUICtrl* ctrl);
|
||||
|
||||
/**
|
||||
* Applies filter to the given tab
|
||||
|
|
|
|||
|
|
@ -28,12 +28,35 @@
|
|||
|
||||
#include "llpanelappearancetab.h"
|
||||
|
||||
|
||||
#include "llinventoryfunctions.h"
|
||||
#include "llinventorymodel.h"
|
||||
#include "llviewerinventory.h"
|
||||
|
||||
//virtual
|
||||
std::string LLPanelAppearanceTab::sRecentFilterSubString;
|
||||
|
||||
void LLPanelAppearanceTab::setFilterSubString(const std::string& new_string)
|
||||
{
|
||||
if (new_string != mFilterSubString)
|
||||
{
|
||||
std::string old_string = mFilterSubString;
|
||||
mFilterSubString = new_string;
|
||||
onFilterSubStringChanged(mFilterSubString, old_string);
|
||||
}
|
||||
|
||||
sRecentFilterSubString = new_string;
|
||||
}
|
||||
|
||||
void LLPanelAppearanceTab::checkFilterSubString()
|
||||
{
|
||||
if (sRecentFilterSubString != mFilterSubString)
|
||||
{
|
||||
std::string old_string = mFilterSubString;
|
||||
mFilterSubString = sRecentFilterSubString;
|
||||
onFilterSubStringChanged(mFilterSubString, old_string);
|
||||
}
|
||||
}
|
||||
|
||||
// virtual
|
||||
bool LLPanelAppearanceTab::canTakeOffSelected()
|
||||
{
|
||||
uuid_vec_t selected_uuids;
|
||||
|
|
|
|||
|
|
@ -35,13 +35,17 @@ public:
|
|||
LLPanelAppearanceTab() : LLPanel() {}
|
||||
virtual ~LLPanelAppearanceTab() {}
|
||||
|
||||
virtual void setFilterSubString(const std::string& string) = 0;
|
||||
void setFilterSubString(const std::string& new_string);
|
||||
|
||||
void checkFilterSubString();
|
||||
|
||||
virtual void onFilterSubStringChanged(const std::string& new_string, const std::string& old_string) = 0;
|
||||
|
||||
virtual bool isActionEnabled(const LLSD& userdata) = 0;
|
||||
|
||||
virtual void getSelectedItemsUUIDs(uuid_vec_t& selected_uuids) const {}
|
||||
|
||||
static const std::string& getFilterSubString() { return sFilterSubString; }
|
||||
const std::string& getFilterSubString() { return mFilterSubString; }
|
||||
|
||||
protected:
|
||||
|
||||
|
|
@ -50,7 +54,10 @@ protected:
|
|||
*/
|
||||
bool canTakeOffSelected();
|
||||
|
||||
static std::string sFilterSubString;
|
||||
private:
|
||||
std::string mFilterSubString;
|
||||
|
||||
static std::string sRecentFilterSubString;
|
||||
};
|
||||
|
||||
#endif //LL_LLPANELAPPEARANCETAB_H
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ enum ESubpart {
|
|||
SUBPART_SKIRT,
|
||||
SUBPART_ALPHA,
|
||||
SUBPART_TATTOO,
|
||||
SUBPART_UNIVERSAL,
|
||||
SUBPART_UNIVERSAL,
|
||||
SUBPART_PHYSICS_BREASTS_UPDOWN,
|
||||
SUBPART_PHYSICS_BREASTS_INOUT,
|
||||
SUBPART_PHYSICS_BREASTS_LEFTRIGHT,
|
||||
|
|
@ -120,7 +120,7 @@ class LLEditWearableDictionary : public LLSingleton<LLEditWearableDictionary>
|
|||
//--------------------------------------------------------------------
|
||||
LLSINGLETON(LLEditWearableDictionary);
|
||||
virtual ~LLEditWearableDictionary();
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Wearable Types
|
||||
//--------------------------------------------------------------------
|
||||
|
|
@ -214,7 +214,6 @@ public:
|
|||
|
||||
LLEditWearableDictionary::LLEditWearableDictionary()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//virtual
|
||||
|
|
@ -227,23 +226,23 @@ LLEditWearableDictionary::Wearables::Wearables()
|
|||
// note the subpart that is listed first is treated as "default", regardless of what order is in enum.
|
||||
// Please match the order presented in XUI. -Nyx
|
||||
// this will affect what camera angle is shown when first editing a wearable
|
||||
addEntry(LLWearableType::WT_SHAPE, new WearableEntry(LLWearableType::WT_SHAPE,"edit_shape_title","shape_desc_text", texture_vec_t(), texture_vec_t(), subpart_vec_t{SUBPART_SHAPE_WHOLE, SUBPART_SHAPE_HEAD, SUBPART_SHAPE_EYES, SUBPART_SHAPE_EARS, SUBPART_SHAPE_NOSE, SUBPART_SHAPE_MOUTH, SUBPART_SHAPE_CHIN, SUBPART_SHAPE_TORSO, SUBPART_SHAPE_LEGS}));
|
||||
addEntry(LLWearableType::WT_SKIN, new WearableEntry(LLWearableType::WT_SKIN,"edit_skin_title","skin_desc_text", texture_vec_t(), texture_vec_t{TEX_HEAD_BODYPAINT, TEX_UPPER_BODYPAINT, TEX_LOWER_BODYPAINT}, subpart_vec_t{SUBPART_SKIN_COLOR, SUBPART_SKIN_FACEDETAIL, SUBPART_SKIN_MAKEUP, SUBPART_SKIN_BODYDETAIL}));
|
||||
addEntry(LLWearableType::WT_HAIR, new WearableEntry(LLWearableType::WT_HAIR,"edit_hair_title","hair_desc_text", texture_vec_t(), texture_vec_t{TEX_HAIR}, subpart_vec_t{SUBPART_HAIR_COLOR, SUBPART_HAIR_STYLE, SUBPART_HAIR_EYEBROWS, SUBPART_HAIR_FACIAL}));
|
||||
addEntry(LLWearableType::WT_EYES, new WearableEntry(LLWearableType::WT_EYES,"edit_eyes_title","eyes_desc_text", texture_vec_t(), texture_vec_t{TEX_EYES_IRIS}, subpart_vec_t{SUBPART_EYES}));
|
||||
addEntry(LLWearableType::WT_SHIRT, new WearableEntry(LLWearableType::WT_SHIRT,"edit_shirt_title","shirt_desc_text", texture_vec_t{TEX_UPPER_SHIRT}, texture_vec_t{TEX_UPPER_SHIRT}, subpart_vec_t{SUBPART_SHIRT}));
|
||||
addEntry(LLWearableType::WT_PANTS, new WearableEntry(LLWearableType::WT_PANTS,"edit_pants_title","pants_desc_text", texture_vec_t{TEX_LOWER_PANTS}, texture_vec_t{TEX_LOWER_PANTS}, subpart_vec_t{SUBPART_PANTS}));
|
||||
addEntry(LLWearableType::WT_SHOES, new WearableEntry(LLWearableType::WT_SHOES,"edit_shoes_title","shoes_desc_text", texture_vec_t{TEX_LOWER_SHOES}, texture_vec_t{TEX_LOWER_SHOES}, subpart_vec_t{SUBPART_SHOES}));
|
||||
addEntry(LLWearableType::WT_SOCKS, new WearableEntry(LLWearableType::WT_SOCKS,"edit_socks_title","socks_desc_text", texture_vec_t{TEX_LOWER_SOCKS}, texture_vec_t{TEX_LOWER_SOCKS}, subpart_vec_t{SUBPART_SOCKS}));
|
||||
addEntry(LLWearableType::WT_SHAPE, new WearableEntry(LLWearableType::WT_SHAPE,"edit_shape_title","shape_desc_text", texture_vec_t(), texture_vec_t(), subpart_vec_t{SUBPART_SHAPE_WHOLE, SUBPART_SHAPE_HEAD, SUBPART_SHAPE_EYES, SUBPART_SHAPE_EARS, SUBPART_SHAPE_NOSE, SUBPART_SHAPE_MOUTH, SUBPART_SHAPE_CHIN, SUBPART_SHAPE_TORSO, SUBPART_SHAPE_LEGS}));
|
||||
addEntry(LLWearableType::WT_SKIN, new WearableEntry(LLWearableType::WT_SKIN,"edit_skin_title","skin_desc_text", texture_vec_t(), texture_vec_t{TEX_HEAD_BODYPAINT, TEX_UPPER_BODYPAINT, TEX_LOWER_BODYPAINT}, subpart_vec_t{SUBPART_SKIN_COLOR, SUBPART_SKIN_FACEDETAIL, SUBPART_SKIN_MAKEUP, SUBPART_SKIN_BODYDETAIL}));
|
||||
addEntry(LLWearableType::WT_HAIR, new WearableEntry(LLWearableType::WT_HAIR,"edit_hair_title","hair_desc_text", texture_vec_t(), texture_vec_t{TEX_HAIR}, subpart_vec_t{SUBPART_HAIR_COLOR, SUBPART_HAIR_STYLE, SUBPART_HAIR_EYEBROWS, SUBPART_HAIR_FACIAL}));
|
||||
addEntry(LLWearableType::WT_EYES, new WearableEntry(LLWearableType::WT_EYES,"edit_eyes_title","eyes_desc_text", texture_vec_t(), texture_vec_t{TEX_EYES_IRIS}, subpart_vec_t{SUBPART_EYES}));
|
||||
addEntry(LLWearableType::WT_SHIRT, new WearableEntry(LLWearableType::WT_SHIRT,"edit_shirt_title","shirt_desc_text", texture_vec_t{TEX_UPPER_SHIRT}, texture_vec_t{TEX_UPPER_SHIRT}, subpart_vec_t{SUBPART_SHIRT}));
|
||||
addEntry(LLWearableType::WT_PANTS, new WearableEntry(LLWearableType::WT_PANTS,"edit_pants_title","pants_desc_text", texture_vec_t{TEX_LOWER_PANTS}, texture_vec_t{TEX_LOWER_PANTS}, subpart_vec_t{SUBPART_PANTS}));
|
||||
addEntry(LLWearableType::WT_SHOES, new WearableEntry(LLWearableType::WT_SHOES,"edit_shoes_title","shoes_desc_text", texture_vec_t{TEX_LOWER_SHOES}, texture_vec_t{TEX_LOWER_SHOES}, subpart_vec_t{SUBPART_SHOES}));
|
||||
addEntry(LLWearableType::WT_SOCKS, new WearableEntry(LLWearableType::WT_SOCKS,"edit_socks_title","socks_desc_text", texture_vec_t{TEX_LOWER_SOCKS}, texture_vec_t{TEX_LOWER_SOCKS}, subpart_vec_t{SUBPART_SOCKS}));
|
||||
addEntry(LLWearableType::WT_JACKET, new WearableEntry(LLWearableType::WT_JACKET,"edit_jacket_title","jacket_desc_text", texture_vec_t{TEX_UPPER_JACKET}, texture_vec_t{TEX_UPPER_JACKET, TEX_LOWER_JACKET}, subpart_vec_t{SUBPART_JACKET}));
|
||||
addEntry(LLWearableType::WT_GLOVES, new WearableEntry(LLWearableType::WT_GLOVES,"edit_gloves_title","gloves_desc_text", texture_vec_t{TEX_UPPER_GLOVES}, texture_vec_t{TEX_UPPER_GLOVES}, subpart_vec_t{SUBPART_GLOVES}));
|
||||
addEntry(LLWearableType::WT_UNDERSHIRT, new WearableEntry(LLWearableType::WT_UNDERSHIRT,"edit_undershirt_title","undershirt_desc_text", texture_vec_t{TEX_UPPER_UNDERSHIRT}, texture_vec_t{TEX_UPPER_UNDERSHIRT}, subpart_vec_t{SUBPART_UNDERSHIRT}));
|
||||
addEntry(LLWearableType::WT_UNDERPANTS, new WearableEntry(LLWearableType::WT_UNDERPANTS,"edit_underpants_title","underpants_desc_text", texture_vec_t{TEX_LOWER_UNDERPANTS}, texture_vec_t{TEX_LOWER_UNDERPANTS}, subpart_vec_t{SUBPART_UNDERPANTS}));
|
||||
addEntry(LLWearableType::WT_SKIRT, new WearableEntry(LLWearableType::WT_SKIRT,"edit_skirt_title","skirt_desc_text", texture_vec_t{TEX_SKIRT}, texture_vec_t{TEX_SKIRT}, subpart_vec_t{SUBPART_SKIRT}));
|
||||
addEntry(LLWearableType::WT_ALPHA, new WearableEntry(LLWearableType::WT_ALPHA,"edit_alpha_title","alpha_desc_text", texture_vec_t(), texture_vec_t{TEX_LOWER_ALPHA, TEX_UPPER_ALPHA, TEX_HEAD_ALPHA, TEX_EYES_ALPHA, TEX_HAIR_ALPHA}, subpart_vec_t{SUBPART_ALPHA}));
|
||||
addEntry(LLWearableType::WT_SKIRT, new WearableEntry(LLWearableType::WT_SKIRT,"edit_skirt_title","skirt_desc_text", texture_vec_t{TEX_SKIRT}, texture_vec_t{TEX_SKIRT}, subpart_vec_t{SUBPART_SKIRT}));
|
||||
addEntry(LLWearableType::WT_ALPHA, new WearableEntry(LLWearableType::WT_ALPHA,"edit_alpha_title","alpha_desc_text", texture_vec_t(), texture_vec_t{TEX_LOWER_ALPHA, TEX_UPPER_ALPHA, TEX_HEAD_ALPHA, TEX_EYES_ALPHA, TEX_HAIR_ALPHA}, subpart_vec_t{SUBPART_ALPHA}));
|
||||
addEntry(LLWearableType::WT_TATTOO, new WearableEntry(LLWearableType::WT_TATTOO,"edit_tattoo_title","tattoo_desc_text", texture_vec_t{TEX_HEAD_TATTOO}, texture_vec_t{TEX_LOWER_TATTOO, TEX_UPPER_TATTOO, TEX_HEAD_TATTOO}, subpart_vec_t{SUBPART_TATTOO}));
|
||||
addEntry(LLWearableType::WT_UNIVERSAL, new WearableEntry(LLWearableType::WT_UNIVERSAL, "edit_universal_title", "universal_desc_text", texture_vec_t{ TEX_HEAD_UNIVERSAL_TATTOO }, texture_vec_t{ TEX_HEAD_UNIVERSAL_TATTOO, TEX_UPPER_UNIVERSAL_TATTOO, TEX_LOWER_UNIVERSAL_TATTOO, TEX_SKIRT_TATTOO, TEX_HAIR_TATTOO, TEX_EYES_TATTOO, TEX_LEFT_ARM_TATTOO, TEX_LEFT_LEG_TATTOO, TEX_AUX1_TATTOO, TEX_AUX2_TATTOO, TEX_AUX3_TATTOO }, subpart_vec_t{ SUBPART_UNIVERSAL }));
|
||||
addEntry(LLWearableType::WT_PHYSICS, new WearableEntry(LLWearableType::WT_PHYSICS,"edit_physics_title","physics_desc_text", texture_vec_t(), texture_vec_t(), subpart_vec_t{SUBPART_PHYSICS_BREASTS_UPDOWN, SUBPART_PHYSICS_BREASTS_INOUT, SUBPART_PHYSICS_BREASTS_LEFTRIGHT, SUBPART_PHYSICS_BELLY_UPDOWN, SUBPART_PHYSICS_BUTT_UPDOWN, SUBPART_PHYSICS_BUTT_LEFTRIGHT, SUBPART_PHYSICS_ADVANCED}));
|
||||
addEntry(LLWearableType::WT_UNIVERSAL, new WearableEntry(LLWearableType::WT_UNIVERSAL, "edit_universal_title", "universal_desc_text", texture_vec_t{ TEX_HEAD_UNIVERSAL_TATTOO }, texture_vec_t{ TEX_HEAD_UNIVERSAL_TATTOO, TEX_UPPER_UNIVERSAL_TATTOO, TEX_LOWER_UNIVERSAL_TATTOO, TEX_SKIRT_TATTOO, TEX_HAIR_TATTOO, TEX_EYES_TATTOO, TEX_LEFT_ARM_TATTOO, TEX_LEFT_LEG_TATTOO, TEX_AUX1_TATTOO, TEX_AUX2_TATTOO, TEX_AUX3_TATTOO }, subpart_vec_t{ SUBPART_UNIVERSAL }));
|
||||
addEntry(LLWearableType::WT_PHYSICS, new WearableEntry(LLWearableType::WT_PHYSICS, "edit_physics_title", "physics_desc_text", texture_vec_t(), texture_vec_t(), subpart_vec_t{ SUBPART_PHYSICS_BREASTS_UPDOWN, SUBPART_PHYSICS_BREASTS_INOUT, SUBPART_PHYSICS_BREASTS_LEFTRIGHT, SUBPART_PHYSICS_BELLY_UPDOWN, SUBPART_PHYSICS_BUTT_UPDOWN, SUBPART_PHYSICS_BUTT_LEFTRIGHT, SUBPART_PHYSICS_ADVANCED }));
|
||||
}
|
||||
|
||||
LLEditWearableDictionary::WearableEntry::WearableEntry(LLWearableType::EType type,
|
||||
|
|
@ -259,52 +258,59 @@ LLEditWearableDictionary::WearableEntry::WearableEntry(LLWearableType::EType typ
|
|||
mSubparts(subparts),
|
||||
mColorSwatchCtrls(color_swatches),
|
||||
mTextureCtrls(texture_pickers)
|
||||
{}
|
||||
{
|
||||
}
|
||||
|
||||
LLEditWearableDictionary::Subparts::Subparts()
|
||||
{
|
||||
addEntry(SUBPART_SHAPE_WHOLE, new SubpartEntry(SUBPART_SHAPE_WHOLE, "mPelvis", "shape_body","shape_body_param_list", "shape_body_tab", LLVector3d(0.f, 0.f, 0.1f), LLVector3d(-2.5f, 0.5f, 0.8f),SEX_BOTH));
|
||||
addEntry(SUBPART_SHAPE_HEAD, new SubpartEntry(SUBPART_SHAPE_HEAD, "mHead", "shape_head", "shape_head_param_list", "shape_head_tab", LLVector3d(0.f, 0.f, 0.05f), LLVector3d(-0.5f, 0.05f, 0.07f),SEX_BOTH));
|
||||
addEntry(SUBPART_SHAPE_EYES, new SubpartEntry(SUBPART_SHAPE_EYES, "mHead", "shape_eyes", "shape_eyes_param_list", "shape_eyes_tab", LLVector3d(0.f, 0.f, 0.05f), LLVector3d(-0.5f, 0.05f, 0.07f),SEX_BOTH));
|
||||
addEntry(SUBPART_SHAPE_EARS, new SubpartEntry(SUBPART_SHAPE_EARS, "mHead", "shape_ears", "shape_ears_param_list", "shape_ears_tab", LLVector3d(0.f, 0.f, 0.05f), LLVector3d(-0.5f, 0.05f, 0.07f),SEX_BOTH));
|
||||
addEntry(SUBPART_SHAPE_NOSE, new SubpartEntry(SUBPART_SHAPE_NOSE, "mHead", "shape_nose", "shape_nose_param_list", "shape_nose_tab", LLVector3d(0.f, 0.f, 0.05f), LLVector3d(-0.5f, 0.05f, 0.07f),SEX_BOTH));
|
||||
addEntry(SUBPART_SHAPE_MOUTH, new SubpartEntry(SUBPART_SHAPE_MOUTH, "mHead", "shape_mouth", "shape_mouth_param_list", "shape_mouth_tab", LLVector3d(0.f, 0.f, 0.05f), LLVector3d(-0.5f, 0.05f, 0.07f),SEX_BOTH));
|
||||
addEntry(SUBPART_SHAPE_CHIN, new SubpartEntry(SUBPART_SHAPE_CHIN, "mHead", "shape_chin", "shape_chin_param_list", "shape_chin_tab", LLVector3d(0.f, 0.f, 0.05f), LLVector3d(-0.5f, 0.05f, 0.07f),SEX_BOTH));
|
||||
addEntry(SUBPART_SHAPE_TORSO, new SubpartEntry(SUBPART_SHAPE_TORSO, "mTorso", "shape_torso", "shape_torso_param_list", "shape_torso_tab", LLVector3d(0.f, 0.f, 0.3f), LLVector3d(-1.f, 0.15f, 0.3f),SEX_BOTH));
|
||||
addEntry(SUBPART_SHAPE_LEGS, new SubpartEntry(SUBPART_SHAPE_LEGS, "mPelvis", "shape_legs", "shape_legs_param_list", "shape_legs_tab", LLVector3d(0.f, 0.f, -0.5f), LLVector3d(-1.6f, 0.15f, -0.5f),SEX_BOTH));
|
||||
// WT_SHAPE
|
||||
addEntry(SUBPART_SHAPE_WHOLE, new SubpartEntry(SUBPART_SHAPE_WHOLE, "mPelvis", "shape_body","shape_body_param_list", "shape_body_tab", LLVector3d(0.f, 0.f, 0.1f), LLVector3d(-2.5f, 0.5f, 0.8f),SEX_BOTH));
|
||||
addEntry(SUBPART_SHAPE_HEAD, new SubpartEntry(SUBPART_SHAPE_HEAD, "mHead", "shape_head", "shape_head_param_list", "shape_head_tab", LLVector3d(0.f, 0.f, 0.05f), LLVector3d(-0.5f, 0.05f, 0.07f),SEX_BOTH));
|
||||
addEntry(SUBPART_SHAPE_EYES, new SubpartEntry(SUBPART_SHAPE_EYES, "mHead", "shape_eyes", "shape_eyes_param_list", "shape_eyes_tab", LLVector3d(0.f, 0.f, 0.05f), LLVector3d(-0.5f, 0.05f, 0.07f),SEX_BOTH));
|
||||
addEntry(SUBPART_SHAPE_EARS, new SubpartEntry(SUBPART_SHAPE_EARS, "mHead", "shape_ears", "shape_ears_param_list", "shape_ears_tab", LLVector3d(0.f, 0.f, 0.05f), LLVector3d(-0.5f, 0.05f, 0.07f),SEX_BOTH));
|
||||
addEntry(SUBPART_SHAPE_NOSE, new SubpartEntry(SUBPART_SHAPE_NOSE, "mHead", "shape_nose", "shape_nose_param_list", "shape_nose_tab", LLVector3d(0.f, 0.f, 0.05f), LLVector3d(-0.5f, 0.05f, 0.07f),SEX_BOTH));
|
||||
addEntry(SUBPART_SHAPE_MOUTH, new SubpartEntry(SUBPART_SHAPE_MOUTH, "mHead", "shape_mouth", "shape_mouth_param_list", "shape_mouth_tab", LLVector3d(0.f, 0.f, 0.05f), LLVector3d(-0.5f, 0.05f, 0.07f),SEX_BOTH));
|
||||
addEntry(SUBPART_SHAPE_CHIN, new SubpartEntry(SUBPART_SHAPE_CHIN, "mHead", "shape_chin", "shape_chin_param_list", "shape_chin_tab", LLVector3d(0.f, 0.f, 0.05f), LLVector3d(-0.5f, 0.05f, 0.07f),SEX_BOTH));
|
||||
addEntry(SUBPART_SHAPE_TORSO, new SubpartEntry(SUBPART_SHAPE_TORSO, "mTorso", "shape_torso", "shape_torso_param_list", "shape_torso_tab", LLVector3d(0.f, 0.f, 0.3f), LLVector3d(-1.f, 0.15f, 0.3f),SEX_BOTH));
|
||||
addEntry(SUBPART_SHAPE_LEGS, new SubpartEntry(SUBPART_SHAPE_LEGS, "mPelvis", "shape_legs", "shape_legs_param_list", "shape_legs_tab", LLVector3d(0.f, 0.f, -0.5f), LLVector3d(-1.6f, 0.15f, -0.5f),SEX_BOTH));
|
||||
|
||||
addEntry(SUBPART_SKIN_COLOR, new SubpartEntry(SUBPART_SKIN_COLOR, "mHead", "skin_color", "skin_color_param_list", "skin_color_tab", LLVector3d(0.f, 0.f, 0.05f), LLVector3d(-0.5f, 0.05f, 0.07f),SEX_BOTH));
|
||||
// WT_SKIN
|
||||
addEntry(SUBPART_SKIN_COLOR, new SubpartEntry(SUBPART_SKIN_COLOR, "mHead", "skin_color", "skin_color_param_list", "skin_color_tab", LLVector3d(0.f, 0.f, 0.05f), LLVector3d(-0.5f, 0.05f, 0.07f),SEX_BOTH));
|
||||
addEntry(SUBPART_SKIN_FACEDETAIL, new SubpartEntry(SUBPART_SKIN_FACEDETAIL, "mHead", "skin_facedetail", "skin_face_param_list", "skin_face_tab", LLVector3d(0.f, 0.f, 0.05f), LLVector3d(-0.5f, 0.05f, 0.07f),SEX_BOTH));
|
||||
addEntry(SUBPART_SKIN_MAKEUP, new SubpartEntry(SUBPART_SKIN_MAKEUP, "mHead", "skin_makeup", "skin_makeup_param_list", "skin_makeup_tab", LLVector3d(0.f, 0.f, 0.05f), LLVector3d(-0.5f, 0.05f, 0.07f),SEX_BOTH));
|
||||
addEntry(SUBPART_SKIN_MAKEUP, new SubpartEntry(SUBPART_SKIN_MAKEUP, "mHead", "skin_makeup", "skin_makeup_param_list", "skin_makeup_tab", LLVector3d(0.f, 0.f, 0.05f), LLVector3d(-0.5f, 0.05f, 0.07f),SEX_BOTH));
|
||||
addEntry(SUBPART_SKIN_BODYDETAIL, new SubpartEntry(SUBPART_SKIN_BODYDETAIL, "mPelvis", "skin_bodydetail", "skin_body_param_list", "skin_body_tab", LLVector3d(0.f, 0.f, -0.2f), LLVector3d(-2.5f, 0.5f, 0.5f),SEX_BOTH));
|
||||
|
||||
addEntry(SUBPART_HAIR_COLOR, new SubpartEntry(SUBPART_HAIR_COLOR, "mHead", "hair_color", "hair_color_param_list", "hair_color_tab", LLVector3d(0.f, 0.f, 0.10f), LLVector3d(-0.4f, 0.05f, 0.10f),SEX_BOTH));
|
||||
addEntry(SUBPART_HAIR_STYLE, new SubpartEntry(SUBPART_HAIR_STYLE, "mHead", "hair_style", "hair_style_param_list", "hair_style_tab", LLVector3d(0.f, 0.f, 0.10f), LLVector3d(-0.4f, 0.05f, 0.10f),SEX_BOTH));
|
||||
addEntry(SUBPART_HAIR_EYEBROWS, new SubpartEntry(SUBPART_HAIR_EYEBROWS, "mHead", "hair_eyebrows", "hair_eyebrows_param_list", "hair_eyebrows_tab", LLVector3d(0.f, 0.f, 0.05f), LLVector3d(-0.5f, 0.05f, 0.07f),SEX_BOTH));
|
||||
addEntry(SUBPART_HAIR_FACIAL, new SubpartEntry(SUBPART_HAIR_FACIAL, "mHead", "hair_facial", "hair_facial_param_list", "hair_facial_tab", LLVector3d(0.f, 0.f, 0.05f), LLVector3d(-0.5f, 0.05f, 0.07f),SEX_MALE));
|
||||
// WT_HAIR
|
||||
addEntry(SUBPART_HAIR_COLOR, new SubpartEntry(SUBPART_HAIR_COLOR, "mHead", "hair_color", "hair_color_param_list", "hair_color_tab", LLVector3d(0.f, 0.f, 0.10f), LLVector3d(-0.4f, 0.05f, 0.10f),SEX_BOTH));
|
||||
addEntry(SUBPART_HAIR_STYLE, new SubpartEntry(SUBPART_HAIR_STYLE, "mHead", "hair_style", "hair_style_param_list", "hair_style_tab", LLVector3d(0.f, 0.f, 0.10f), LLVector3d(-0.4f, 0.05f, 0.10f), SEX_BOTH));
|
||||
addEntry(SUBPART_HAIR_EYEBROWS, new SubpartEntry(SUBPART_HAIR_EYEBROWS, "mHead", "hair_eyebrows", "hair_eyebrows_param_list", "hair_eyebrows_tab", LLVector3d(0.f, 0.f, 0.05f), LLVector3d(-0.5f, 0.05f, 0.07f),SEX_BOTH));
|
||||
addEntry(SUBPART_HAIR_FACIAL, new SubpartEntry(SUBPART_HAIR_FACIAL, "mHead", "hair_facial", "hair_facial_param_list", "hair_facial_tab", LLVector3d(0.f, 0.f, 0.05f), LLVector3d(-0.5f, 0.05f, 0.07f),SEX_MALE));
|
||||
|
||||
addEntry(SUBPART_EYES, new SubpartEntry(SUBPART_EYES, "mHead", "eyes", "eyes_main_param_list", "eyes_main_tab", LLVector3d(0.f, 0.f, 0.05f), LLVector3d(-0.5f, 0.05f, 0.07f),SEX_BOTH));
|
||||
// WT_EYES
|
||||
addEntry(SUBPART_EYES, new SubpartEntry(SUBPART_EYES, "mHead", "eyes", "eyes_main_param_list", "eyes_main_tab", LLVector3d(0.f, 0.f, 0.05f), LLVector3d(-0.5f, 0.05f, 0.07f),SEX_BOTH));
|
||||
|
||||
addEntry(SUBPART_SHIRT, new SubpartEntry(SUBPART_SHIRT, "mTorso", "shirt", "shirt_main_param_list", "shirt_main_tab", LLVector3d(0.f, 0.f, 0.3f), LLVector3d(-1.f, 0.15f, 0.3f),SEX_BOTH));
|
||||
addEntry(SUBPART_PANTS, new SubpartEntry(SUBPART_PANTS, "mPelvis", "pants", "pants_main_param_list", "pants_main_tab", LLVector3d(0.f, 0.f, -0.5f), LLVector3d(-1.6f, 0.15f, -0.5f),SEX_BOTH));
|
||||
addEntry(SUBPART_SHOES, new SubpartEntry(SUBPART_SHOES, "mPelvis", "shoes", "shoes_main_param_list", "shoes_main_tab", LLVector3d(0.f, 0.f, -0.5f), LLVector3d(-1.6f, 0.15f, -0.5f),SEX_BOTH));
|
||||
addEntry(SUBPART_SOCKS, new SubpartEntry(SUBPART_SOCKS, "mPelvis", "socks", "socks_main_param_list", "socks_main_tab", LLVector3d(0.f, 0.f, -0.5f), LLVector3d(-1.6f, 0.15f, -0.5f),SEX_BOTH));
|
||||
addEntry(SUBPART_JACKET, new SubpartEntry(SUBPART_JACKET, "mTorso", "jacket", "jacket_main_param_list", "jacket_main_tab", LLVector3d(0.f, 0.f, 0.f), LLVector3d(-2.f, 0.1f, 0.3f),SEX_BOTH));
|
||||
addEntry(SUBPART_SKIRT, new SubpartEntry(SUBPART_SKIRT, "mPelvis", "skirt", "skirt_main_param_list", "skirt_main_tab", LLVector3d(0.f, 0.f, -0.5f), LLVector3d(-1.6f, 0.15f, -0.5f),SEX_BOTH));
|
||||
addEntry(SUBPART_GLOVES, new SubpartEntry(SUBPART_GLOVES, "mTorso", "gloves", "gloves_main_param_list", "gloves_main_tab", LLVector3d(0.f, 0.f, 0.f), LLVector3d(-1.f, 0.15f, 0.f),SEX_BOTH));
|
||||
addEntry(SUBPART_UNDERSHIRT, new SubpartEntry(SUBPART_UNDERSHIRT, "mTorso", "undershirt", "undershirt_main_param_list", "undershirt_main_tab", LLVector3d(0.f, 0.f, 0.3f), LLVector3d(-1.f, 0.15f, 0.3f),SEX_BOTH));
|
||||
addEntry(SUBPART_UNDERPANTS, new SubpartEntry(SUBPART_UNDERPANTS, "mPelvis", "underpants", "underpants_main_param_list", "underpants_main_tab", LLVector3d(0.f, 0.f, -0.5f), LLVector3d(-1.6f, 0.15f, -0.5f),SEX_BOTH));
|
||||
addEntry(SUBPART_ALPHA, new SubpartEntry(SUBPART_ALPHA, "mPelvis", "alpha", "alpha_main_param_list", "alpha_main_tab", LLVector3d(0.f, 0.f, 0.1f), LLVector3d(-2.5f, 0.5f, 0.8f),SEX_BOTH));
|
||||
addEntry(SUBPART_TATTOO, new SubpartEntry(SUBPART_TATTOO, "mPelvis", "tattoo", "tattoo_main_param_list", "tattoo_main_tab", LLVector3d(0.f, 0.f, 0.1f), LLVector3d(-2.5f, 0.5f, 0.8f),SEX_BOTH));
|
||||
addEntry(SUBPART_UNIVERSAL, new SubpartEntry(SUBPART_UNIVERSAL, "mPelvis", "universal", "universal_main_param_list", "universal_main_tab", LLVector3d(0.f, 0.f, 0.1f), LLVector3d(-2.5f, 0.5f, 0.8f), SEX_BOTH));
|
||||
// WT_SHIRT, WT_PANTS, WT_SHOES, WT_SOCKS, WT_JACKET, WT_GLOVES, WT_UNDERSHIRT, WT_UNDERPANTS, WT_SKIRT, WT_ALPHA, WT_TATTOO, WT_UNIVERSAL
|
||||
addEntry(SUBPART_SHIRT, new SubpartEntry(SUBPART_SHIRT, "mTorso", "shirt", "shirt_main_param_list", "shirt_main_tab", LLVector3d(0.f, 0.f, 0.3f), LLVector3d(-1.f, 0.15f, 0.3f),SEX_BOTH));
|
||||
addEntry(SUBPART_PANTS, new SubpartEntry(SUBPART_PANTS, "mPelvis", "pants", "pants_main_param_list", "pants_main_tab", LLVector3d(0.f, 0.f, -0.5f), LLVector3d(-1.6f, 0.15f, -0.5f),SEX_BOTH));
|
||||
addEntry(SUBPART_SHOES, new SubpartEntry(SUBPART_SHOES, "mPelvis", "shoes", "shoes_main_param_list", "shoes_main_tab", LLVector3d(0.f, 0.f, -0.5f), LLVector3d(-1.6f, 0.15f, -0.5f),SEX_BOTH));
|
||||
addEntry(SUBPART_SOCKS, new SubpartEntry(SUBPART_SOCKS, "mPelvis", "socks", "socks_main_param_list", "socks_main_tab", LLVector3d(0.f, 0.f, -0.5f), LLVector3d(-1.6f, 0.15f, -0.5f),SEX_BOTH));
|
||||
addEntry(SUBPART_JACKET, new SubpartEntry(SUBPART_JACKET, "mTorso", "jacket", "jacket_main_param_list", "jacket_main_tab", LLVector3d(0.f, 0.f, 0.f), LLVector3d(-2.f, 0.1f, 0.3f),SEX_BOTH));
|
||||
addEntry(SUBPART_GLOVES, new SubpartEntry(SUBPART_GLOVES, "mTorso", "gloves", "gloves_main_param_list", "gloves_main_tab", LLVector3d(0.f, 0.f, 0.f), LLVector3d(-1.f, 0.15f, 0.f),SEX_BOTH));
|
||||
addEntry(SUBPART_UNDERSHIRT, new SubpartEntry(SUBPART_UNDERSHIRT, "mTorso", "undershirt", "undershirt_main_param_list", "undershirt_main_tab", LLVector3d(0.f, 0.f, 0.3f), LLVector3d(-1.f, 0.15f, 0.3f),SEX_BOTH));
|
||||
addEntry(SUBPART_UNDERPANTS, new SubpartEntry(SUBPART_UNDERPANTS, "mPelvis", "underpants", "underpants_main_param_list", "underpants_main_tab", LLVector3d(0.f, 0.f, -0.5f), LLVector3d(-1.6f, 0.15f, -0.5f),SEX_BOTH));
|
||||
addEntry(SUBPART_SKIRT, new SubpartEntry(SUBPART_SKIRT, "mPelvis", "skirt", "skirt_main_param_list", "skirt_main_tab", LLVector3d(0.f, 0.f, -0.5f), LLVector3d(-1.6f, 0.15f, -0.5f),SEX_BOTH));
|
||||
addEntry(SUBPART_ALPHA, new SubpartEntry(SUBPART_ALPHA, "mPelvis", "alpha", "alpha_main_param_list", "alpha_main_tab", LLVector3d(0.f, 0.f, 0.1f), LLVector3d(-2.5f, 0.5f, 0.8f),SEX_BOTH));
|
||||
addEntry(SUBPART_TATTOO, new SubpartEntry(SUBPART_TATTOO, "mPelvis", "tattoo", "tattoo_main_param_list", "tattoo_main_tab", LLVector3d(0.f, 0.f, 0.1f), LLVector3d(-2.5f, 0.5f, 0.8f),SEX_BOTH));
|
||||
addEntry(SUBPART_UNIVERSAL, new SubpartEntry(SUBPART_UNIVERSAL, "mPelvis", "universal", "universal_main_param_list", "universal_main_tab", LLVector3d(0.f, 0.f, 0.1f), LLVector3d(-2.5f, 0.5f, 0.8f), SEX_BOTH));
|
||||
|
||||
addEntry(SUBPART_PHYSICS_BREASTS_UPDOWN, new SubpartEntry(SUBPART_PHYSICS_BREASTS_UPDOWN, "mTorso", "physics_breasts_updown", "physics_breasts_updown_param_list", "physics_breasts_updown_tab", LLVector3d(0.f, 0.f, 0.3f), LLVector3d(0.f, 0.f, 0.f),SEX_FEMALE));
|
||||
addEntry(SUBPART_PHYSICS_BREASTS_INOUT, new SubpartEntry(SUBPART_PHYSICS_BREASTS_INOUT, "mTorso", "physics_breasts_inout", "physics_breasts_inout_param_list", "physics_breasts_inout_tab", LLVector3d(0.f, 0.f, 0.3f), LLVector3d(0.f, 0.f, 0.f),SEX_FEMALE));
|
||||
// WT_PHYSICS
|
||||
addEntry(SUBPART_PHYSICS_BREASTS_UPDOWN, new SubpartEntry(SUBPART_PHYSICS_BREASTS_UPDOWN, "mTorso", "physics_breasts_updown", "physics_breasts_updown_param_list", "physics_breasts_updown_tab", LLVector3d(0.f, 0.f, 0.3f), LLVector3d(0.f, 0.f, 0.f), SEX_FEMALE));
|
||||
addEntry(SUBPART_PHYSICS_BREASTS_INOUT, new SubpartEntry(SUBPART_PHYSICS_BREASTS_INOUT, "mTorso", "physics_breasts_inout", "physics_breasts_inout_param_list", "physics_breasts_inout_tab", LLVector3d(0.f, 0.f, 0.3f), LLVector3d(0.f, 0.f, 0.f),SEX_FEMALE));
|
||||
addEntry(SUBPART_PHYSICS_BREASTS_LEFTRIGHT, new SubpartEntry(SUBPART_PHYSICS_BREASTS_LEFTRIGHT, "mTorso", "physics_breasts_leftright", "physics_breasts_leftright_param_list", "physics_breasts_leftright_tab", LLVector3d(0.f, 0.f, 0.3f), LLVector3d(0.f, 0.f, 0.f),SEX_FEMALE));
|
||||
addEntry(SUBPART_PHYSICS_BELLY_UPDOWN, new SubpartEntry(SUBPART_PHYSICS_BELLY_UPDOWN, "mTorso", "physics_belly_updown", "physics_belly_updown_param_list", "physics_belly_updown_tab", LLVector3d(0.f, 0.f, 0.3f), LLVector3d(0.f, 0.f, 0.f),SEX_BOTH));
|
||||
addEntry(SUBPART_PHYSICS_BUTT_UPDOWN, new SubpartEntry(SUBPART_PHYSICS_BUTT_UPDOWN, "mTorso", "physics_butt_updown", "physics_butt_updown_param_list", "physics_butt_updown_tab", LLVector3d(0.f, 0.f, 0.3f), LLVector3d(0.f, 0.f, 0.f),SEX_BOTH));
|
||||
addEntry(SUBPART_PHYSICS_BUTT_LEFTRIGHT, new SubpartEntry(SUBPART_PHYSICS_BUTT_LEFTRIGHT, "mTorso", "physics_butt_leftright", "physics_butt_leftright_param_list", "physics_butt_leftright_tab", LLVector3d(0.f, 0.f, 0.f), LLVector3d(0.f, 0.f, 0.f),SEX_BOTH));
|
||||
addEntry(SUBPART_PHYSICS_ADVANCED, new SubpartEntry(SUBPART_PHYSICS_ADVANCED, "mTorso", "physics_advanced", "physics_advanced_param_list", "physics_advanced_tab", LLVector3d(0.f, 0.f, 0.f), LLVector3d(0.f, 0.f, 0.f),SEX_BOTH));
|
||||
addEntry(SUBPART_PHYSICS_BELLY_UPDOWN, new SubpartEntry(SUBPART_PHYSICS_BELLY_UPDOWN, "mTorso", "physics_belly_updown", "physics_belly_updown_param_list", "physics_belly_updown_tab", LLVector3d(0.f, 0.f, 0.3f), LLVector3d(0.f, 0.f, 0.f),SEX_BOTH));
|
||||
addEntry(SUBPART_PHYSICS_BUTT_UPDOWN, new SubpartEntry(SUBPART_PHYSICS_BUTT_UPDOWN, "mTorso", "physics_butt_updown", "physics_butt_updown_param_list", "physics_butt_updown_tab", LLVector3d(0.f, 0.f, 0.3f), LLVector3d(0.f, 0.f, 0.f),SEX_BOTH));
|
||||
addEntry(SUBPART_PHYSICS_BUTT_LEFTRIGHT, new SubpartEntry(SUBPART_PHYSICS_BUTT_LEFTRIGHT, "mTorso", "physics_butt_leftright", "physics_butt_leftright_param_list", "physics_butt_leftright_tab", LLVector3d(0.f, 0.f, 0.f), LLVector3d(0.f, 0.f, 0.f),SEX_BOTH));
|
||||
addEntry(SUBPART_PHYSICS_ADVANCED, new SubpartEntry(SUBPART_PHYSICS_ADVANCED, "mTorso", "physics_advanced", "physics_advanced_param_list", "physics_advanced_tab", LLVector3d(0.f, 0.f, 0.f), LLVector3d(0.f, 0.f, 0.f),SEX_BOTH));
|
||||
}
|
||||
|
||||
LLEditWearableDictionary::SubpartEntry::SubpartEntry(ESubpart part,
|
||||
|
|
@ -329,55 +335,55 @@ LLEditWearableDictionary::SubpartEntry::SubpartEntry(ESubpart part,
|
|||
|
||||
LLEditWearableDictionary::ColorSwatchCtrls::ColorSwatchCtrls()
|
||||
{
|
||||
addEntry ( TEX_UPPER_SHIRT, new PickerControlEntry (TEX_UPPER_SHIRT, "Color/Tint" ));
|
||||
addEntry ( TEX_LOWER_PANTS, new PickerControlEntry (TEX_LOWER_PANTS, "Color/Tint" ));
|
||||
addEntry ( TEX_LOWER_SHOES, new PickerControlEntry (TEX_LOWER_SHOES, "Color/Tint" ));
|
||||
addEntry ( TEX_LOWER_SOCKS, new PickerControlEntry (TEX_LOWER_SOCKS, "Color/Tint" ));
|
||||
addEntry ( TEX_UPPER_JACKET, new PickerControlEntry (TEX_UPPER_JACKET, "Color/Tint" ));
|
||||
addEntry ( TEX_SKIRT, new PickerControlEntry (TEX_SKIRT, "Color/Tint" ));
|
||||
addEntry ( TEX_UPPER_GLOVES, new PickerControlEntry (TEX_UPPER_GLOVES, "Color/Tint" ));
|
||||
addEntry ( TEX_UPPER_UNDERSHIRT, new PickerControlEntry (TEX_UPPER_UNDERSHIRT, "Color/Tint" ));
|
||||
addEntry ( TEX_LOWER_UNDERPANTS, new PickerControlEntry (TEX_LOWER_UNDERPANTS, "Color/Tint" ));
|
||||
addEntry ( TEX_HEAD_TATTOO, new PickerControlEntry(TEX_HEAD_TATTOO, "Color/Tint" ));
|
||||
addEntry (TEX_HEAD_UNIVERSAL_TATTOO, new PickerControlEntry(TEX_HEAD_UNIVERSAL_TATTOO, "Color/Tint"));
|
||||
addEntry(TEX_UPPER_SHIRT, new PickerControlEntry(TEX_UPPER_SHIRT, "Color/Tint"));
|
||||
addEntry(TEX_LOWER_PANTS, new PickerControlEntry(TEX_LOWER_PANTS, "Color/Tint"));
|
||||
addEntry(TEX_LOWER_SHOES, new PickerControlEntry(TEX_LOWER_SHOES, "Color/Tint"));
|
||||
addEntry(TEX_LOWER_SOCKS, new PickerControlEntry(TEX_LOWER_SOCKS, "Color/Tint"));
|
||||
addEntry(TEX_UPPER_JACKET, new PickerControlEntry(TEX_UPPER_JACKET, "Color/Tint"));
|
||||
addEntry(TEX_SKIRT, new PickerControlEntry(TEX_SKIRT, "Color/Tint"));
|
||||
addEntry(TEX_UPPER_GLOVES, new PickerControlEntry(TEX_UPPER_GLOVES, "Color/Tint"));
|
||||
addEntry(TEX_UPPER_UNDERSHIRT, new PickerControlEntry(TEX_UPPER_UNDERSHIRT, "Color/Tint"));
|
||||
addEntry(TEX_LOWER_UNDERPANTS, new PickerControlEntry(TEX_LOWER_UNDERPANTS, "Color/Tint"));
|
||||
addEntry(TEX_HEAD_TATTOO, new PickerControlEntry(TEX_HEAD_TATTOO, "Color/Tint"));
|
||||
addEntry(TEX_HEAD_UNIVERSAL_TATTOO, new PickerControlEntry(TEX_HEAD_UNIVERSAL_TATTOO, "Color/Tint"));
|
||||
}
|
||||
|
||||
LLEditWearableDictionary::TextureCtrls::TextureCtrls()
|
||||
{
|
||||
addEntry ( TEX_HEAD_BODYPAINT, new PickerControlEntry (TEX_HEAD_BODYPAINT, "Head", LLUUID::null, TRUE ));
|
||||
addEntry ( TEX_UPPER_BODYPAINT, new PickerControlEntry (TEX_UPPER_BODYPAINT, "Upper Body", LLUUID::null, TRUE ));
|
||||
addEntry ( TEX_LOWER_BODYPAINT, new PickerControlEntry (TEX_LOWER_BODYPAINT, "Lower Body", LLUUID::null, TRUE ));
|
||||
addEntry ( TEX_HAIR, new PickerControlEntry (TEX_HAIR, "Texture", LLUUID( gSavedSettings.getString( "UIImgDefaultHairUUID" ) ), FALSE ));
|
||||
addEntry ( TEX_EYES_IRIS, new PickerControlEntry (TEX_EYES_IRIS, "Iris", LLUUID( gSavedSettings.getString( "UIImgDefaultEyesUUID" ) ), FALSE ));
|
||||
addEntry ( TEX_UPPER_SHIRT, new PickerControlEntry (TEX_UPPER_SHIRT, "Fabric", LLUUID( gSavedSettings.getString( "UIImgDefaultShirtUUID" ) ), FALSE ));
|
||||
addEntry ( TEX_LOWER_PANTS, new PickerControlEntry (TEX_LOWER_PANTS, "Fabric", LLUUID( gSavedSettings.getString( "UIImgDefaultPantsUUID" ) ), FALSE ));
|
||||
addEntry ( TEX_LOWER_SHOES, new PickerControlEntry (TEX_LOWER_SHOES, "Fabric", LLUUID( gSavedSettings.getString( "UIImgDefaultShoesUUID" ) ), FALSE ));
|
||||
addEntry ( TEX_LOWER_SOCKS, new PickerControlEntry (TEX_LOWER_SOCKS, "Fabric", LLUUID( gSavedSettings.getString( "UIImgDefaultSocksUUID" ) ), FALSE ));
|
||||
addEntry ( TEX_UPPER_JACKET, new PickerControlEntry (TEX_UPPER_JACKET, "Upper Fabric", LLUUID( gSavedSettings.getString( "UIImgDefaultJacketUUID" ) ), FALSE ));
|
||||
addEntry ( TEX_LOWER_JACKET, new PickerControlEntry (TEX_LOWER_JACKET, "Lower Fabric", LLUUID( gSavedSettings.getString( "UIImgDefaultJacketUUID" ) ), FALSE ));
|
||||
addEntry ( TEX_SKIRT, new PickerControlEntry (TEX_SKIRT, "Fabric", LLUUID( gSavedSettings.getString( "UIImgDefaultSkirtUUID" ) ), FALSE ));
|
||||
addEntry ( TEX_UPPER_GLOVES, new PickerControlEntry (TEX_UPPER_GLOVES, "Fabric", LLUUID( gSavedSettings.getString( "UIImgDefaultGlovesUUID" ) ), FALSE ));
|
||||
addEntry ( TEX_UPPER_UNDERSHIRT, new PickerControlEntry (TEX_UPPER_UNDERSHIRT, "Fabric", LLUUID( gSavedSettings.getString( "UIImgDefaultUnderwearUUID" ) ), FALSE ));
|
||||
addEntry ( TEX_LOWER_UNDERPANTS, new PickerControlEntry (TEX_LOWER_UNDERPANTS, "Fabric", LLUUID( gSavedSettings.getString( "UIImgDefaultUnderwearUUID" ) ), FALSE ));
|
||||
addEntry ( TEX_LOWER_ALPHA, new PickerControlEntry (TEX_LOWER_ALPHA, "Lower Alpha", LLUUID( gSavedSettings.getString( "UIImgDefaultAlphaUUID" ) ), TRUE ));
|
||||
addEntry ( TEX_UPPER_ALPHA, new PickerControlEntry (TEX_UPPER_ALPHA, "Upper Alpha", LLUUID( gSavedSettings.getString( "UIImgDefaultAlphaUUID" ) ), TRUE ));
|
||||
addEntry ( TEX_HEAD_ALPHA, new PickerControlEntry (TEX_HEAD_ALPHA, "Head Alpha", LLUUID( gSavedSettings.getString( "UIImgDefaultAlphaUUID" ) ), TRUE ));
|
||||
addEntry ( TEX_EYES_ALPHA, new PickerControlEntry (TEX_EYES_ALPHA, "Eye Alpha", LLUUID( gSavedSettings.getString( "UIImgDefaultAlphaUUID" ) ), TRUE ));
|
||||
addEntry ( TEX_HAIR_ALPHA, new PickerControlEntry (TEX_HAIR_ALPHA, "Hair Alpha", LLUUID( gSavedSettings.getString( "UIImgDefaultAlphaUUID" ) ), TRUE ));
|
||||
addEntry ( TEX_LOWER_TATTOO, new PickerControlEntry (TEX_LOWER_TATTOO, "Lower Tattoo", LLUUID::null, TRUE ));
|
||||
addEntry ( TEX_UPPER_TATTOO, new PickerControlEntry (TEX_UPPER_TATTOO, "Upper Tattoo", LLUUID::null, TRUE ));
|
||||
addEntry ( TEX_HEAD_TATTOO, new PickerControlEntry (TEX_HEAD_TATTOO, "Head Tattoo", LLUUID::null, TRUE ));
|
||||
addEntry ( TEX_LOWER_UNIVERSAL_TATTOO, new PickerControlEntry( TEX_LOWER_UNIVERSAL_TATTOO, "Lower Universal Tattoo", LLUUID::null, TRUE));
|
||||
addEntry ( TEX_UPPER_UNIVERSAL_TATTOO, new PickerControlEntry( TEX_UPPER_UNIVERSAL_TATTOO, "Upper Universal Tattoo", LLUUID::null, TRUE));
|
||||
addEntry ( TEX_HEAD_UNIVERSAL_TATTOO, new PickerControlEntry( TEX_HEAD_UNIVERSAL_TATTOO, "Head Universal Tattoo", LLUUID::null, TRUE));
|
||||
addEntry ( TEX_SKIRT_TATTOO, new PickerControlEntry(TEX_SKIRT_TATTOO, "Skirt Tattoo", LLUUID::null, TRUE));
|
||||
addEntry ( TEX_HAIR_TATTOO, new PickerControlEntry(TEX_HAIR_TATTOO, "Hair Tattoo", LLUUID::null, TRUE));
|
||||
addEntry ( TEX_EYES_TATTOO, new PickerControlEntry(TEX_EYES_TATTOO, "Eyes Tattoo", LLUUID::null, TRUE));
|
||||
addEntry (TEX_LEFT_ARM_TATTOO, new PickerControlEntry(TEX_LEFT_ARM_TATTOO, "Left Arm Tattoo", LLUUID::null, TRUE));
|
||||
addEntry (TEX_LEFT_LEG_TATTOO, new PickerControlEntry(TEX_LEFT_LEG_TATTOO, "Left Leg Tattoo", LLUUID::null, TRUE));
|
||||
addEntry (TEX_AUX1_TATTOO, new PickerControlEntry(TEX_AUX1_TATTOO, "Aux1 Tattoo", LLUUID::null, TRUE));
|
||||
addEntry (TEX_AUX2_TATTOO, new PickerControlEntry(TEX_AUX2_TATTOO, "Aux2 Tattoo", LLUUID::null, TRUE));
|
||||
addEntry (TEX_AUX3_TATTOO, new PickerControlEntry(TEX_AUX3_TATTOO, "Aux3 Tattoo", LLUUID::null, TRUE));
|
||||
addEntry(TEX_HEAD_BODYPAINT, new PickerControlEntry(TEX_HEAD_BODYPAINT, "Head", LLUUID::null, TRUE));
|
||||
addEntry(TEX_UPPER_BODYPAINT, new PickerControlEntry(TEX_UPPER_BODYPAINT, "Upper Body", LLUUID::null, TRUE));
|
||||
addEntry(TEX_LOWER_BODYPAINT, new PickerControlEntry(TEX_LOWER_BODYPAINT, "Lower Body", LLUUID::null, TRUE));
|
||||
addEntry(TEX_HAIR, new PickerControlEntry(TEX_HAIR, "Texture", LLUUID(gSavedSettings.getString("UIImgDefaultHairUUID")), FALSE));
|
||||
addEntry(TEX_EYES_IRIS, new PickerControlEntry(TEX_EYES_IRIS, "Iris", LLUUID(gSavedSettings.getString("UIImgDefaultEyesUUID")), FALSE));
|
||||
addEntry(TEX_UPPER_SHIRT, new PickerControlEntry(TEX_UPPER_SHIRT, "Fabric", LLUUID(gSavedSettings.getString("UIImgDefaultShirtUUID")), FALSE));
|
||||
addEntry(TEX_LOWER_PANTS, new PickerControlEntry(TEX_LOWER_PANTS, "Fabric", LLUUID(gSavedSettings.getString("UIImgDefaultPantsUUID")), FALSE));
|
||||
addEntry(TEX_LOWER_SHOES, new PickerControlEntry(TEX_LOWER_SHOES, "Fabric", LLUUID(gSavedSettings.getString("UIImgDefaultShoesUUID")), FALSE));
|
||||
addEntry(TEX_LOWER_SOCKS, new PickerControlEntry(TEX_LOWER_SOCKS, "Fabric", LLUUID(gSavedSettings.getString("UIImgDefaultSocksUUID")), FALSE));
|
||||
addEntry(TEX_UPPER_JACKET, new PickerControlEntry(TEX_UPPER_JACKET, "Upper Fabric", LLUUID(gSavedSettings.getString("UIImgDefaultJacketUUID")), FALSE));
|
||||
addEntry(TEX_LOWER_JACKET, new PickerControlEntry(TEX_LOWER_JACKET, "Lower Fabric", LLUUID(gSavedSettings.getString("UIImgDefaultJacketUUID")), FALSE));
|
||||
addEntry(TEX_SKIRT, new PickerControlEntry(TEX_SKIRT, "Fabric", LLUUID(gSavedSettings.getString("UIImgDefaultSkirtUUID")), FALSE));
|
||||
addEntry(TEX_UPPER_GLOVES, new PickerControlEntry(TEX_UPPER_GLOVES, "Fabric", LLUUID(gSavedSettings.getString("UIImgDefaultGlovesUUID")), FALSE));
|
||||
addEntry(TEX_UPPER_UNDERSHIRT, new PickerControlEntry(TEX_UPPER_UNDERSHIRT, "Fabric", LLUUID(gSavedSettings.getString("UIImgDefaultUnderwearUUID")), FALSE));
|
||||
addEntry(TEX_LOWER_UNDERPANTS, new PickerControlEntry(TEX_LOWER_UNDERPANTS, "Fabric", LLUUID(gSavedSettings.getString("UIImgDefaultUnderwearUUID")), FALSE));
|
||||
addEntry(TEX_LOWER_ALPHA, new PickerControlEntry(TEX_LOWER_ALPHA, "Lower Alpha", LLUUID(gSavedSettings.getString("UIImgDefaultAlphaUUID")), TRUE));
|
||||
addEntry(TEX_UPPER_ALPHA, new PickerControlEntry(TEX_UPPER_ALPHA, "Upper Alpha", LLUUID(gSavedSettings.getString("UIImgDefaultAlphaUUID")), TRUE));
|
||||
addEntry(TEX_HEAD_ALPHA, new PickerControlEntry(TEX_HEAD_ALPHA, "Head Alpha", LLUUID(gSavedSettings.getString("UIImgDefaultAlphaUUID")), TRUE));
|
||||
addEntry(TEX_EYES_ALPHA, new PickerControlEntry(TEX_EYES_ALPHA, "Eye Alpha", LLUUID(gSavedSettings.getString("UIImgDefaultAlphaUUID")), TRUE));
|
||||
addEntry(TEX_HAIR_ALPHA, new PickerControlEntry(TEX_HAIR_ALPHA, "Hair Alpha", LLUUID(gSavedSettings.getString("UIImgDefaultAlphaUUID")), TRUE));
|
||||
addEntry(TEX_LOWER_TATTOO, new PickerControlEntry(TEX_LOWER_TATTOO, "Lower Tattoo", LLUUID::null, TRUE));
|
||||
addEntry(TEX_UPPER_TATTOO, new PickerControlEntry(TEX_UPPER_TATTOO, "Upper Tattoo", LLUUID::null, TRUE));
|
||||
addEntry(TEX_HEAD_TATTOO, new PickerControlEntry(TEX_HEAD_TATTOO, "Head Tattoo", LLUUID::null, TRUE));
|
||||
addEntry(TEX_LOWER_UNIVERSAL_TATTOO, new PickerControlEntry(TEX_LOWER_UNIVERSAL_TATTOO, "Lower Universal Tattoo", LLUUID::null, TRUE));
|
||||
addEntry(TEX_UPPER_UNIVERSAL_TATTOO, new PickerControlEntry(TEX_UPPER_UNIVERSAL_TATTOO, "Upper Universal Tattoo", LLUUID::null, TRUE));
|
||||
addEntry(TEX_HEAD_UNIVERSAL_TATTOO, new PickerControlEntry(TEX_HEAD_UNIVERSAL_TATTOO, "Head Universal Tattoo", LLUUID::null, TRUE));
|
||||
addEntry(TEX_SKIRT_TATTOO, new PickerControlEntry(TEX_SKIRT_TATTOO, "Skirt Tattoo", LLUUID::null, TRUE));
|
||||
addEntry(TEX_HAIR_TATTOO, new PickerControlEntry(TEX_HAIR_TATTOO, "Hair Tattoo", LLUUID::null, TRUE));
|
||||
addEntry(TEX_EYES_TATTOO, new PickerControlEntry(TEX_EYES_TATTOO, "Eyes Tattoo", LLUUID::null, TRUE));
|
||||
addEntry(TEX_LEFT_ARM_TATTOO, new PickerControlEntry(TEX_LEFT_ARM_TATTOO, "Left Arm Tattoo", LLUUID::null, TRUE));
|
||||
addEntry(TEX_LEFT_LEG_TATTOO, new PickerControlEntry(TEX_LEFT_LEG_TATTOO, "Left Leg Tattoo", LLUUID::null, TRUE));
|
||||
addEntry(TEX_AUX1_TATTOO, new PickerControlEntry(TEX_AUX1_TATTOO, "Aux1 Tattoo", LLUUID::null, TRUE));
|
||||
addEntry(TEX_AUX2_TATTOO, new PickerControlEntry(TEX_AUX2_TATTOO, "Aux2 Tattoo", LLUUID::null, TRUE));
|
||||
addEntry(TEX_AUX3_TATTOO, new PickerControlEntry(TEX_AUX3_TATTOO, "Aux3 Tattoo", LLUUID::null, TRUE));
|
||||
}
|
||||
|
||||
LLEditWearableDictionary::PickerControlEntry::PickerControlEntry(ETextureIndex tex_index,
|
||||
|
|
@ -490,8 +496,8 @@ template <typename CtrlType, class Predicate>
|
|||
const LLEditWearableDictionary::PickerControlEntry*
|
||||
find_picker_ctrl_entry_if(LLWearableType::EType type, const Predicate pred)
|
||||
{
|
||||
const LLEditWearableDictionary::WearableEntry *wearable_entry
|
||||
= LLEditWearableDictionary::getInstance()->getWearable(type);
|
||||
const LLEditWearableDictionary::WearableEntry *wearable_entry =
|
||||
LLEditWearableDictionary::getInstance()->getWearable(type);
|
||||
if (!wearable_entry)
|
||||
{
|
||||
LL_WARNS() << "could not get wearable dictionary entry for wearable of type: " << type << LL_ENDL;
|
||||
|
|
@ -520,8 +526,7 @@ find_picker_ctrl_entry_if(LLWearableType::EType type, const Predicate pred)
|
|||
}
|
||||
|
||||
template <typename CtrlType>
|
||||
void
|
||||
for_each_picker_ctrl_entry(LLPanel* panel, LLWearableType::EType type, function_t fun)
|
||||
void for_each_picker_ctrl_entry(LLPanel* panel, LLWearableType::EType type, function_t fun)
|
||||
{
|
||||
if (!panel)
|
||||
{
|
||||
|
|
@ -542,14 +547,13 @@ for_each_picker_ctrl_entry(LLPanel* panel, LLWearableType::EType type, function_
|
|||
iter != iter_end; ++iter)
|
||||
{
|
||||
const ETextureIndex te = *iter;
|
||||
const LLEditWearableDictionary::PickerControlEntry* entry
|
||||
= get_picker_entry<CtrlType>(te);
|
||||
const LLEditWearableDictionary::PickerControlEntry* entry = get_picker_entry<CtrlType>(te);
|
||||
if (!entry)
|
||||
{
|
||||
LL_WARNS() << "could not get picker dictionary entry (" << te << ") for wearable of type: " << type << LL_ENDL;
|
||||
continue;
|
||||
}
|
||||
fun (panel, entry);
|
||||
fun(panel, entry);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -594,7 +598,7 @@ static void update_texture_ctrl(LLPanelEditWearable* self, LLPanel* panel, const
|
|||
{
|
||||
LLUUID new_id;
|
||||
LLLocalTextureObject *lto = self->getWearable()->getLocalTextureObject(entry->mTextureIndex);
|
||||
if( lto && (lto->getID() != IMG_DEFAULT_AVATAR) )
|
||||
if (lto && (lto->getID() != IMG_DEFAULT_AVATAR))
|
||||
{
|
||||
new_id = lto->getID();
|
||||
}
|
||||
|
|
@ -644,7 +648,6 @@ LLPanelEditWearable::LLPanelEditWearable()
|
|||
//virtual
|
||||
LLPanelEditWearable::~LLPanelEditWearable()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool LLPanelEditWearable::changeHeightUnits(const LLSD& new_value)
|
||||
|
|
@ -659,7 +662,7 @@ void LLPanelEditWearable::updateMetricLayout(BOOL new_value)
|
|||
LLUIString current_metric, replacment_metric;
|
||||
current_metric = new_value ? mMeters : mFeet;
|
||||
replacment_metric = new_value ? mFeet : mMeters;
|
||||
mHeigthValue.setArg( "[METRIC1]", current_metric.getString() );
|
||||
mHeightValue.setArg( "[METRIC1]", current_metric.getString() );
|
||||
mReplacementMetricUrl.setArg( "[URL_METRIC2]", std::string("[secondlife:///app/metricsystem ") + replacment_metric.getString() + std::string("]"));
|
||||
}
|
||||
|
||||
|
|
@ -667,11 +670,11 @@ void LLPanelEditWearable::updateAvatarHeightLabel()
|
|||
{
|
||||
mTxtAvatarHeight->setText(LLStringUtil::null);
|
||||
LLStyle::Params param;
|
||||
param.color = mAvatarHeigthLabelColor;
|
||||
mTxtAvatarHeight->appendText(mHeigth, false, param);
|
||||
param.color = mAvatarHeigthValueLabelColor;
|
||||
mTxtAvatarHeight->appendText(mHeigthValue, false, param);
|
||||
param.color = mAvatarHeigthLabelColor; // using mAvatarHeigthLabelColor for '/' separator
|
||||
param.color = mAvatarHeightLabelColor;
|
||||
mTxtAvatarHeight->appendText(mHeight, false, param);
|
||||
param.color = mAvatarHeightValueLabelColor;
|
||||
mTxtAvatarHeight->appendText(mHeightValue, false, param);
|
||||
param.color = mAvatarHeightLabelColor; // using mAvatarHeightLabelColor for '/' separator
|
||||
mTxtAvatarHeight->appendText(" / ", false, param);
|
||||
mTxtAvatarHeight->appendText(this->mReplacementMetricUrl, false, param);
|
||||
}
|
||||
|
|
@ -754,7 +757,7 @@ BOOL LLPanelEditWearable::postBuild()
|
|||
mPanelSkirt = getChild<LLPanel>("edit_skirt_panel");
|
||||
mPanelAlpha = getChild<LLPanel>("edit_alpha_panel");
|
||||
mPanelTattoo = getChild<LLPanel>("edit_tattoo_panel");
|
||||
mPanelUniversal = getChild<LLPanel>("edit_universal_panel");
|
||||
mPanelUniversal = getChild<LLPanel>("edit_universal_panel");
|
||||
mPanelPhysics = getChild<LLPanel>("edit_physics_panel");
|
||||
|
||||
mTxtAvatarHeight = mPanelShape->getChild<LLTextBox>("avatar_height");
|
||||
|
|
@ -778,29 +781,27 @@ BOOL LLPanelEditWearable::postBuild()
|
|||
continue;
|
||||
}
|
||||
U8 num_subparts = (U8)(wearable_entry->mSubparts.size());
|
||||
|
||||
|
||||
for (U8 index = 0; index < num_subparts; ++index)
|
||||
{
|
||||
// dive into data structures to get the panel we need
|
||||
ESubpart subpart_e = wearable_entry->mSubparts[index];
|
||||
const LLEditWearableDictionary::SubpartEntry *subpart_entry = LLEditWearableDictionary::getInstance()->getSubpart(subpart_e);
|
||||
|
||||
|
||||
if (!subpart_entry)
|
||||
{
|
||||
LL_WARNS() << "could not get wearable subpart dictionary entry for subpart: " << subpart_e << LL_ENDL;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
const std::string accordion_tab = subpart_entry->mAccordionTab;
|
||||
|
||||
LLAccordionCtrlTab *tab = getChild<LLAccordionCtrlTab>(accordion_tab);
|
||||
|
||||
if (!tab)
|
||||
{
|
||||
LL_WARNS() << "could not get llaccordionctrltab from UI with name: " << accordion_tab << LL_ENDL;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
// initialize callback to ensure camera view changes appropriately.
|
||||
tab->setDropDownStateChangedCallback(boost::bind(&LLPanelEditWearable::onTabExpandedCollapsed,this,_2,index));
|
||||
}
|
||||
|
|
@ -813,14 +814,14 @@ BOOL LLPanelEditWearable::postBuild()
|
|||
// init all strings
|
||||
mMeters = mPanelShape->getString("meters");
|
||||
mFeet = mPanelShape->getString("feet");
|
||||
mHeigth = mPanelShape->getString("height") + " ";
|
||||
mHeigthValue = "[HEIGHT] [METRIC1]";
|
||||
mHeight = mPanelShape->getString("height") + " ";
|
||||
mHeightValue = "[HEIGHT] [METRIC1]";
|
||||
mReplacementMetricUrl = "[URL_METRIC2]";
|
||||
|
||||
std::string color = mPanelShape->getString("heigth_label_color");
|
||||
mAvatarHeigthLabelColor = LLUIColorTable::instance().getColor(color, LLColor4::green);
|
||||
color = mPanelShape->getString("heigth_value_label_color");
|
||||
mAvatarHeigthValueLabelColor = LLUIColorTable::instance().getColor(color, LLColor4::green);
|
||||
std::string color = mPanelShape->getString("height_label_color");
|
||||
mAvatarHeightLabelColor = LLUIColorTable::instance().getColor(color, LLColor4::green);
|
||||
color = mPanelShape->getString("height_value_label_color");
|
||||
mAvatarHeightValueLabelColor = LLUIColorTable::instance().getColor(color, LLColor4::green);
|
||||
gSavedSettings.getControl("HeightUnits")->getSignal()->connect(boost::bind(&LLPanelEditWearable::changeHeightUnits, this, _2));
|
||||
updateMetricLayout(gSavedSettings.getBOOL("HeightUnits"));
|
||||
|
||||
|
|
@ -834,14 +835,16 @@ BOOL LLPanelEditWearable::isDirty() const
|
|||
BOOL isDirty = FALSE;
|
||||
if (mWearablePtr)
|
||||
{
|
||||
if (mWearablePtr->isDirty() ||
|
||||
( mWearableItem && mNameEditor && mWearableItem->getName().compare(mNameEditor->getText()) != 0 ))
|
||||
{
|
||||
isDirty = TRUE;
|
||||
}
|
||||
if (mWearablePtr->isDirty() ||
|
||||
(mWearableItem && mNameEditor && mWearableItem->getName().compare(mNameEditor->getText()) != 0))
|
||||
{
|
||||
isDirty = TRUE;
|
||||
}
|
||||
}
|
||||
return isDirty;
|
||||
}
|
||||
|
||||
|
||||
//virtual
|
||||
void LLPanelEditWearable::draw()
|
||||
{
|
||||
|
|
@ -857,8 +860,8 @@ void LLPanelEditWearable::draw()
|
|||
|
||||
void LLPanelEditWearable::onClose()
|
||||
{
|
||||
// any unsaved changes should be reverted at this point
|
||||
revertChanges();
|
||||
// any unsaved changes should be reverted at this point
|
||||
revertChanges();
|
||||
}
|
||||
|
||||
void LLPanelEditWearable::setVisible(BOOL visible)
|
||||
|
|
@ -880,11 +883,11 @@ void LLPanelEditWearable::setWearable(LLViewerWearable *wearable, BOOL disable_c
|
|||
//static
|
||||
void LLPanelEditWearable::onBackButtonClicked(void* userdata)
|
||||
{
|
||||
LLPanelEditWearable *panel = (LLPanelEditWearable*) userdata;
|
||||
if ( panel->isDirty() )
|
||||
{
|
||||
LLAppearanceMgr::instance().setOutfitDirty( true );
|
||||
}
|
||||
LLPanelEditWearable* panel = (LLPanelEditWearable*)userdata;
|
||||
if (panel->isDirty())
|
||||
{
|
||||
LLAppearanceMgr::instance().setOutfitDirty(true);
|
||||
}
|
||||
}
|
||||
|
||||
//static
|
||||
|
|
@ -909,7 +912,7 @@ void LLPanelEditWearable::saveAsCallback(const LLSD& notification, const LLSD& r
|
|||
{
|
||||
std::string wearable_name = response["message"].asString();
|
||||
LLStringUtil::trim(wearable_name);
|
||||
if( !wearable_name.empty() )
|
||||
if (!wearable_name.empty())
|
||||
{
|
||||
mNameEditor->setText(wearable_name);
|
||||
saveChanges(true);
|
||||
|
|
@ -919,24 +922,27 @@ void LLPanelEditWearable::saveAsCallback(const LLSD& notification, const LLSD& r
|
|||
|
||||
void LLPanelEditWearable::onCommitSexChange()
|
||||
{
|
||||
if (!isAgentAvatarValid()) return;
|
||||
if (!isAgentAvatarValid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
LLWearableType::EType type = mWearablePtr->getType();
|
||||
U32 index;
|
||||
if( !gAgentWearables.getWearableIndex(mWearablePtr, index) ||
|
||||
!gAgentWearables.isWearableModifiable(type, index))
|
||||
if (!gAgentWearables.getWearableIndex(mWearablePtr, index) ||
|
||||
!gAgentWearables.isWearableModifiable(type, index))
|
||||
{
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
LLViewerVisualParam* param = static_cast<LLViewerVisualParam*>(gAgentAvatarp->getVisualParam( "male" ));
|
||||
if( !param )
|
||||
if (!param)
|
||||
{
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
bool is_new_sex_male = (gSavedSettings.getU32("AvatarSex") ? SEX_MALE : SEX_FEMALE) == SEX_MALE;
|
||||
LLViewerWearable* wearable = gAgentWearables.getViewerWearable(type, index);
|
||||
LLViewerWearable* wearable = gAgentWearables.getViewerWearable(type, index);
|
||||
if (wearable)
|
||||
{
|
||||
wearable->setVisualParamWeight(param->getID(), is_new_sex_male);
|
||||
|
|
@ -969,23 +975,23 @@ void LLPanelEditWearable::onTexturePickerCommit(const LLUICtrl* ctrl)
|
|||
{
|
||||
// Set the new version
|
||||
LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTexture(texture_ctrl->getImageAssetID());
|
||||
if( image->getID() == IMG_DEFAULT )
|
||||
if (image->getID() == IMG_DEFAULT)
|
||||
{
|
||||
image = LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT_AVATAR);
|
||||
}
|
||||
if (getWearable())
|
||||
{
|
||||
U32 index;
|
||||
if (gAgentWearables.getWearableIndex(getWearable(), index))
|
||||
{
|
||||
gAgentAvatarp->setLocalTexture(entry->mTextureIndex, image, FALSE, index);
|
||||
LLVisualParamHint::requestHintUpdates();
|
||||
gAgentAvatarp->wearableUpdated(type);
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS() << "wearable not found in gAgentWearables" << LL_ENDL;
|
||||
}
|
||||
U32 index;
|
||||
if (gAgentWearables.getWearableIndex(getWearable(), index))
|
||||
{
|
||||
gAgentAvatarp->setLocalTexture(entry->mTextureIndex, image, FALSE, index);
|
||||
LLVisualParamHint::requestHintUpdates();
|
||||
gAgentAvatarp->wearableUpdated(type);
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS() << "wearable not found in gAgentWearables" << LL_ENDL;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -1001,13 +1007,13 @@ void LLPanelEditWearable::onColorSwatchCommit(const LLUICtrl* ctrl)
|
|||
{
|
||||
LLWearableType::EType type = getWearable()->getType();
|
||||
const PickerControlEntryNamePredicate name_pred(ctrl->getName());
|
||||
const LLEditWearableDictionary::PickerControlEntry* entry
|
||||
= find_picker_ctrl_entry_if<LLColorSwatchCtrl, PickerControlEntryNamePredicate>(type, name_pred);
|
||||
const LLEditWearableDictionary::PickerControlEntry* entry =
|
||||
find_picker_ctrl_entry_if<LLColorSwatchCtrl, PickerControlEntryNamePredicate>(type, name_pred);
|
||||
if (entry)
|
||||
{
|
||||
const LLColor4& old_color = getWearable()->getClothesColor(entry->mTextureIndex);
|
||||
const LLColor4& new_color = LLColor4(ctrl->getValue());
|
||||
if( old_color != new_color )
|
||||
if (old_color != new_color)
|
||||
{
|
||||
getWearable()->setClothesColor(entry->mTextureIndex, new_color);
|
||||
LLVisualParamHint::requestHintUpdates();
|
||||
|
|
@ -1025,11 +1031,13 @@ void LLPanelEditWearable::updatePanelPickerControls(LLWearableType::EType type)
|
|||
{
|
||||
LLPanel* panel = getPanel(type);
|
||||
if (!panel)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
bool is_modifiable = false;
|
||||
|
||||
if(mWearableItem)
|
||||
if (mWearableItem)
|
||||
{
|
||||
const LLPermissions& perm = mWearableItem->getPermissions();
|
||||
is_modifiable = perm.allowModifyBy(gAgent.getID(), gAgent.getGroupID());
|
||||
|
|
@ -1051,7 +1059,6 @@ void LLPanelEditWearable::updatePanelPickerControls(LLWearableType::EType type)
|
|||
|
||||
void LLPanelEditWearable::incrementCofVersionLegacy()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void LLPanelEditWearable::saveChanges(bool force_save_as)
|
||||
|
|
@ -1063,59 +1070,57 @@ void LLPanelEditWearable::saveChanges(bool force_save_as)
|
|||
}
|
||||
|
||||
U32 index;
|
||||
if (!gAgentWearables.getWearableIndex(mWearablePtr, index))
|
||||
{
|
||||
LL_WARNS() << "wearable not found" << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
if (!gAgentWearables.getWearableIndex(mWearablePtr, index))
|
||||
{
|
||||
LL_WARNS() << "wearable not found" << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
std::string new_name = mNameEditor->getText();
|
||||
|
||||
// Find an existing link to this wearable's inventory item, if any, and its description field.
|
||||
LLInventoryItem *link_item = NULL;
|
||||
std::string description;
|
||||
LLInventoryModel::item_array_t links =
|
||||
LLAppearanceMgr::instance().findCOFItemLinks(mWearablePtr->getItemID());
|
||||
if (links.size()>0)
|
||||
{
|
||||
link_item = links.at(0).get();
|
||||
if (link_item && link_item->getIsLinkType())
|
||||
{
|
||||
description = link_item->getActualDescription();
|
||||
}
|
||||
}
|
||||
// Find an existing link to this wearable's inventory item, if any, and its description field.
|
||||
LLInventoryItem* link_item = NULL;
|
||||
std::string description;
|
||||
LLInventoryModel::item_array_t links =
|
||||
LLAppearanceMgr::instance().findCOFItemLinks(mWearablePtr->getItemID());
|
||||
if (links.size() > 0)
|
||||
{
|
||||
link_item = links.at(0).get();
|
||||
if (link_item && link_item->getIsLinkType())
|
||||
{
|
||||
description = link_item->getActualDescription();
|
||||
}
|
||||
}
|
||||
|
||||
if (force_save_as)
|
||||
{
|
||||
// the name of the wearable has changed, re-save wearable with new name
|
||||
LLAppearanceMgr::instance().removeCOFItemLinks(mWearablePtr->getItemID(),gAgentAvatarp->mEndCustomizeCallback);
|
||||
gAgentWearables.saveWearableAs(mWearablePtr->getType(), index, new_name, description, FALSE);
|
||||
mNameEditor->setText(mWearableItem->getName());
|
||||
// the name of the wearable has changed, re-save wearable with new name
|
||||
LLAppearanceMgr::instance().removeCOFItemLinks(mWearablePtr->getItemID(), gAgentAvatarp->mEndCustomizeCallback);
|
||||
gAgentWearables.saveWearableAs(mWearablePtr->getType(), index, new_name, description, FALSE);
|
||||
mNameEditor->setText(mWearableItem->getName());
|
||||
}
|
||||
else
|
||||
{
|
||||
// Make another copy of this link, with the same
|
||||
// description. This is needed to bump the COF
|
||||
// version so texture baking service knows appearance has changed.
|
||||
if (link_item)
|
||||
{
|
||||
// Create new link
|
||||
LL_DEBUGS("Avatar") << "link refresh, creating new link to " << link_item->getLinkedUUID()
|
||||
<< " removing old link at " << link_item->getUUID()
|
||||
<< " wearable item id " << mWearablePtr->getItemID() << LL_ENDL;
|
||||
// Make another copy of this link, with the same
|
||||
// description. This is needed to bump the COF
|
||||
// version so texture baking service knows appearance has changed.
|
||||
if (link_item)
|
||||
{
|
||||
// Create new link
|
||||
LL_DEBUGS("Avatar") << "link refresh, creating new link to " << link_item->getLinkedUUID()
|
||||
<< " removing old link at " << link_item->getUUID()
|
||||
<< " wearable item id " << mWearablePtr->getItemID() << LL_ENDL;
|
||||
|
||||
LLInventoryObject::const_object_list_t obj_array;
|
||||
obj_array.push_back(LLConstPointer<LLInventoryObject>(link_item));
|
||||
link_inventory_array(LLAppearanceMgr::instance().getCOF(),
|
||||
obj_array,
|
||||
gAgentAvatarp->mEndCustomizeCallback);
|
||||
// Remove old link
|
||||
remove_inventory_item(link_item->getUUID(), gAgentAvatarp->mEndCustomizeCallback);
|
||||
}
|
||||
gAgentWearables.saveWearable(mWearablePtr->getType(), index, new_name);
|
||||
LLInventoryObject::const_object_list_t obj_array;
|
||||
obj_array.push_back(LLConstPointer<LLInventoryObject>(link_item));
|
||||
link_inventory_array(LLAppearanceMgr::instance().getCOF(),
|
||||
obj_array,
|
||||
gAgentAvatarp->mEndCustomizeCallback);
|
||||
// Remove old link
|
||||
remove_inventory_item(link_item->getUUID(), gAgentAvatarp->mEndCustomizeCallback);
|
||||
}
|
||||
gAgentWearables.saveWearable(mWearablePtr->getType(), index, new_name);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void LLPanelEditWearable::revertChanges()
|
||||
|
|
@ -1165,15 +1170,15 @@ void LLPanelEditWearable::showWearable(LLViewerWearable* wearable, BOOL show, BO
|
|||
|
||||
targetPanel->setVisible(show);
|
||||
toggleTypeSpecificControls(type);
|
||||
// Update type controls here
|
||||
updateTypeSpecificControls(type);
|
||||
// Update type controls here
|
||||
updateTypeSpecificControls(type);
|
||||
|
||||
if (show)
|
||||
{
|
||||
mPanelTitle->setText(title);
|
||||
mPanelTitle->setToolTip(title);
|
||||
mDescTitle->setText(description_title);
|
||||
|
||||
|
||||
// set name
|
||||
mNameEditor->setText(mWearableItem->getName());
|
||||
|
||||
|
|
@ -1181,51 +1186,51 @@ void LLPanelEditWearable::showWearable(LLViewerWearable* wearable, BOOL show, BO
|
|||
|
||||
// clear and rebuild visual param list
|
||||
U8 num_subparts = (U8)(wearable_entry->mSubparts.size());
|
||||
|
||||
|
||||
for (U8 index = 0; index < num_subparts; ++index)
|
||||
{
|
||||
// dive into data structures to get the panel we need
|
||||
ESubpart subpart_e = wearable_entry->mSubparts[index];
|
||||
const LLEditWearableDictionary::SubpartEntry *subpart_entry = LLEditWearableDictionary::getInstance()->getSubpart(subpart_e);
|
||||
|
||||
|
||||
if (!subpart_entry)
|
||||
{
|
||||
LL_WARNS() << "could not get wearable subpart dictionary entry for subpart: " << subpart_e << LL_ENDL;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
const std::string scrolling_panel = subpart_entry->mParamList;
|
||||
const std::string accordion_tab = subpart_entry->mAccordionTab;
|
||||
|
||||
|
||||
LLScrollingPanelList *panel_list = getChild<LLScrollingPanelList>(scrolling_panel);
|
||||
LLAccordionCtrlTab *tab = getChild<LLAccordionCtrlTab>(accordion_tab);
|
||||
|
||||
|
||||
if (!panel_list)
|
||||
{
|
||||
LL_WARNS() << "could not get scrolling panel list: " << scrolling_panel << LL_ENDL;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (!tab)
|
||||
{
|
||||
LL_WARNS() << "could not get llaccordionctrltab from UI with name: " << accordion_tab << LL_ENDL;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Don't show female subparts if you're not female, etc.
|
||||
if (!(gAgentAvatarp->getSex() & subpart_entry->mSex))
|
||||
{
|
||||
tab->setVisible(FALSE);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
tab->setVisible(TRUE);
|
||||
}
|
||||
|
||||
// Don't show female subparts if you're not female, etc.
|
||||
if (!(gAgentAvatarp->getSex() & subpart_entry->mSex))
|
||||
{
|
||||
tab->setVisible(FALSE);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
tab->setVisible(TRUE);
|
||||
}
|
||||
|
||||
// what edit group do we want to extract params for?
|
||||
const std::string edit_group = subpart_entry->mEditGroup;
|
||||
|
||||
|
||||
// storage for ordered list of visual params
|
||||
value_map_t sorted_params;
|
||||
getSortedParams(sorted_params, edit_group);
|
||||
|
|
@ -1237,9 +1242,10 @@ void LLPanelEditWearable::showWearable(LLViewerWearable* wearable, BOOL show, BO
|
|||
}
|
||||
|
||||
buildParamList(panel_list, sorted_params, tab, jointp);
|
||||
|
||||
|
||||
updateScrollingPanelUI();
|
||||
}
|
||||
|
||||
if (!disable_camera_switch)
|
||||
{
|
||||
showDefaultSubpart();
|
||||
|
|
@ -1268,17 +1274,17 @@ void LLPanelEditWearable::onTabExpandedCollapsed(const LLSD& param, U8 index)
|
|||
{
|
||||
changeCamera(index);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void LLPanelEditWearable::changeCamera(U8 subpart)
|
||||
{
|
||||
// Don't change the camera if this type doesn't have a camera switch.
|
||||
// Useful for wearables like physics that don't have an associated physical body part.
|
||||
if (LLWearableType::getInstance()->getDisableCameraSwitch(mWearablePtr->getType()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
// Don't change the camera if this type doesn't have a camera switch.
|
||||
// Useful for wearables like physics that don't have an associated physical body part.
|
||||
if (LLWearableType::getInstance()->getDisableCameraSwitch(mWearablePtr->getType()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const LLEditWearableDictionary::WearableEntry *wearable_entry = LLEditWearableDictionary::getInstance()->getWearable(mWearablePtr->getType());
|
||||
if (!wearable_entry)
|
||||
{
|
||||
|
|
@ -1307,9 +1313,9 @@ void LLPanelEditWearable::changeCamera(U8 subpart)
|
|||
gMorphView->setCameraOffset( subpart_entry->mCameraOffset );
|
||||
if (gSavedSettings.getBOOL("AppearanceCameraMovement"))
|
||||
{
|
||||
// Unlock focus from avatar but don't stop animation to not interrupt ANIM_AGENT_CUSTOMIZE
|
||||
gAgentCamera.setFocusOnAvatar(FALSE, gAgentCamera.getCameraAnimating());
|
||||
gMorphView->updateCamera();
|
||||
// Unlock focus from avatar but don't stop animation to not interrupt ANIM_AGENT_CUSTOMIZE
|
||||
gAgentCamera.setFocusOnAvatar(FALSE, gAgentCamera.getCameraAnimating());
|
||||
gMorphView->updateCamera();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1345,7 +1351,7 @@ void LLPanelEditWearable::updateTypeSpecificControls(LLWearableType::EType type)
|
|||
}
|
||||
|
||||
std::string avatar_height_str = llformat("%.2f", new_size);
|
||||
mHeigthValue.setArg("[HEIGHT]", avatar_height_str);
|
||||
mHeightValue.setArg("[HEIGHT]", avatar_height_str);
|
||||
updateAvatarHeightLabel();
|
||||
}
|
||||
|
||||
|
|
@ -1368,14 +1374,18 @@ void LLPanelEditWearable::updateScrollingPanelUI()
|
|||
LLWearableType::EType type = mWearablePtr->getType();
|
||||
LLPanel *panel = getPanel(type);
|
||||
|
||||
if(panel && (mWearablePtr->getItemID().notNull()))
|
||||
if (panel && (mWearablePtr->getItemID().notNull()))
|
||||
{
|
||||
const LLEditWearableDictionary::WearableEntry *wearable_entry = LLEditWearableDictionary::getInstance()->getWearable(type);
|
||||
llassert(wearable_entry);
|
||||
if (!wearable_entry) return;
|
||||
U8 num_subparts = (U8)(wearable_entry->mSubparts.size());
|
||||
if (!wearable_entry)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
LLScrollingPanelParam::sUpdateDelayFrames = 0;
|
||||
|
||||
U8 num_subparts = (U8)(wearable_entry->mSubparts.size());
|
||||
for (U8 index = 0; index < num_subparts; ++index)
|
||||
{
|
||||
// dive into data structures to get the panel we need
|
||||
|
|
@ -1385,13 +1395,13 @@ void LLPanelEditWearable::updateScrollingPanelUI()
|
|||
const std::string scrolling_panel = subpart_entry->mParamList;
|
||||
|
||||
LLScrollingPanelList *panel_list = getChild<LLScrollingPanelList>(scrolling_panel);
|
||||
|
||||
|
||||
if (!panel_list)
|
||||
{
|
||||
LL_WARNS() << "could not get scrolling panel list: " << scrolling_panel << LL_ENDL;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
panel_list->updatePanels(TRUE);
|
||||
}
|
||||
}
|
||||
|
|
@ -1403,76 +1413,58 @@ LLPanel* LLPanelEditWearable::getPanel(LLWearableType::EType type)
|
|||
{
|
||||
case LLWearableType::WT_SHAPE:
|
||||
return mPanelShape;
|
||||
break;
|
||||
|
||||
case LLWearableType::WT_SKIN:
|
||||
return mPanelSkin;
|
||||
break;
|
||||
|
||||
case LLWearableType::WT_HAIR:
|
||||
return mPanelHair;
|
||||
break;
|
||||
|
||||
case LLWearableType::WT_EYES:
|
||||
return mPanelEyes;
|
||||
break;
|
||||
|
||||
case LLWearableType::WT_SHIRT:
|
||||
return mPanelShirt;
|
||||
break;
|
||||
|
||||
case LLWearableType::WT_PANTS:
|
||||
return mPanelPants;
|
||||
break;
|
||||
|
||||
case LLWearableType::WT_SHOES:
|
||||
return mPanelShoes;
|
||||
break;
|
||||
|
||||
case LLWearableType::WT_SOCKS:
|
||||
return mPanelSocks;
|
||||
break;
|
||||
|
||||
case LLWearableType::WT_JACKET:
|
||||
return mPanelJacket;
|
||||
break;
|
||||
|
||||
case LLWearableType::WT_GLOVES:
|
||||
return mPanelGloves;
|
||||
break;
|
||||
|
||||
case LLWearableType::WT_UNDERSHIRT:
|
||||
return mPanelUndershirt;
|
||||
break;
|
||||
|
||||
case LLWearableType::WT_UNDERPANTS:
|
||||
return mPanelUnderpants;
|
||||
break;
|
||||
|
||||
case LLWearableType::WT_SKIRT:
|
||||
return mPanelSkirt;
|
||||
break;
|
||||
|
||||
case LLWearableType::WT_ALPHA:
|
||||
return mPanelAlpha;
|
||||
break;
|
||||
|
||||
case LLWearableType::WT_TATTOO:
|
||||
return mPanelTattoo;
|
||||
break;
|
||||
|
||||
case LLWearableType::WT_UNIVERSAL:
|
||||
return mPanelUniversal;
|
||||
break;
|
||||
|
||||
case LLWearableType::WT_UNIVERSAL:
|
||||
return mPanelUniversal;
|
||||
|
||||
case LLWearableType::WT_PHYSICS:
|
||||
return mPanelPhysics;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
return NULL;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void LLPanelEditWearable::getSortedParams(value_map_t &sorted_params, const std::string &edit_group)
|
||||
|
|
@ -1507,11 +1499,11 @@ void LLPanelEditWearable::buildParamList(LLScrollingPanelList *panel_list, value
|
|||
// sorted_params is sorted according to magnitude of effect from
|
||||
// least to greatest. Adding to the front of the child list
|
||||
// reverses that order.
|
||||
if( panel_list )
|
||||
if (panel_list)
|
||||
{
|
||||
panel_list->clearPanels();
|
||||
value_map_t::iterator end = sorted_params.end();
|
||||
for(value_map_t::iterator it = sorted_params.begin(); it != end; ++it)
|
||||
for (value_map_t::iterator it = sorted_params.begin(); it != end; ++it)
|
||||
{
|
||||
LLPanel::Params p;
|
||||
p.name("LLScrollingPanelParam");
|
||||
|
|
@ -1534,7 +1526,7 @@ void LLPanelEditWearable::updateVerbs()
|
|||
{
|
||||
bool can_copy = false;
|
||||
|
||||
if(mWearableItem)
|
||||
if (mWearableItem)
|
||||
{
|
||||
can_copy = mWearableItem->getPermissions().allowCopyBy(gAgentID);
|
||||
}
|
||||
|
|
@ -1544,7 +1536,7 @@ void LLPanelEditWearable::updateVerbs()
|
|||
mBtnRevert->setEnabled(is_dirty);
|
||||
getChildView("save_as_button")->setEnabled(is_dirty && can_copy);
|
||||
|
||||
if(isAgentAvatarValid())
|
||||
if (isAgentAvatarValid())
|
||||
{
|
||||
// Update viewer's radio buttons (of RadioGroup with control_name="AvatarSex") of Avatar's gender
|
||||
// with value from "AvatarSex" setting
|
||||
|
|
@ -1585,17 +1577,20 @@ void LLPanelEditWearable::configureAlphaCheckbox(LLAvatarAppearanceDefines::ETex
|
|||
|
||||
void LLPanelEditWearable::onInvisibilityCommit(LLCheckBoxCtrl* checkbox_ctrl, LLAvatarAppearanceDefines::ETextureIndex te)
|
||||
{
|
||||
if (!checkbox_ctrl) return;
|
||||
if (!getWearable()) return;
|
||||
if (!checkbox_ctrl || !getWearable())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
LL_INFOS() << "onInvisibilityCommit, self " << this << " checkbox_ctrl " << checkbox_ctrl << LL_ENDL;
|
||||
|
||||
U32 index;
|
||||
if (!gAgentWearables.getWearableIndex(getWearable(),index))
|
||||
{
|
||||
LL_WARNS() << "wearable not found" << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
U32 index;
|
||||
if (!gAgentWearables.getWearableIndex(getWearable(), index))
|
||||
{
|
||||
LL_WARNS() << "wearable not found" << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
bool new_invis_state = checkbox_ctrl->get();
|
||||
if (new_invis_state)
|
||||
{
|
||||
|
|
@ -1603,8 +1598,8 @@ void LLPanelEditWearable::onInvisibilityCommit(LLCheckBoxCtrl* checkbox_ctrl, LL
|
|||
mPreviousAlphaTexture[te] = lto->getID();
|
||||
|
||||
LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTexture( IMG_INVISIBLE );
|
||||
gAgentAvatarp->setLocalTexture(te, image, FALSE, index);
|
||||
gAgentAvatarp->wearableUpdated(getWearable()->getType());
|
||||
gAgentAvatarp->setLocalTexture(te, image, FALSE, index);
|
||||
gAgentAvatarp->wearableUpdated(getWearable()->getType());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1614,10 +1609,16 @@ void LLPanelEditWearable::onInvisibilityCommit(LLCheckBoxCtrl* checkbox_ctrl, LL
|
|||
{
|
||||
prev_id = LLUUID( gSavedSettings.getString( "UIImgDefaultAlphaUUID" ) );
|
||||
}
|
||||
if (prev_id.isNull()) return;
|
||||
|
||||
if (prev_id.isNull())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTexture(prev_id);
|
||||
if (!image) return;
|
||||
if (!image)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
gAgentAvatarp->setLocalTexture(te, image, FALSE, index);
|
||||
gAgentAvatarp->wearableUpdated(getWearable()->getType());
|
||||
|
|
@ -1628,7 +1629,7 @@ void LLPanelEditWearable::onInvisibilityCommit(LLCheckBoxCtrl* checkbox_ctrl, LL
|
|||
|
||||
void LLPanelEditWearable::updateAlphaCheckboxes()
|
||||
{
|
||||
for(string_texture_index_map_t::iterator iter = mAlphaCheckbox2Index.begin();
|
||||
for (string_texture_index_map_t::iterator iter = mAlphaCheckbox2Index.begin();
|
||||
iter != mAlphaCheckbox2Index.end(); ++iter )
|
||||
{
|
||||
LLAvatarAppearanceDefines::ETextureIndex te = (LLAvatarAppearanceDefines::ETextureIndex)iter->second;
|
||||
|
|
|
|||
|
|
@ -135,14 +135,14 @@ private:
|
|||
// localized and parameterized strings that used to build avatar_height_label
|
||||
std::string mMeters;
|
||||
std::string mFeet;
|
||||
std::string mHeigth;
|
||||
LLUIString mHeigthValue;
|
||||
std::string mHeight;
|
||||
LLUIString mHeightValue;
|
||||
LLUIString mReplacementMetricUrl;
|
||||
|
||||
// color for mHeigth string
|
||||
LLUIColor mAvatarHeigthLabelColor;
|
||||
// color for mHeigthValue string
|
||||
LLUIColor mAvatarHeigthValueLabelColor;
|
||||
// color for mHeight string
|
||||
LLUIColor mAvatarHeightLabelColor;
|
||||
// color for mHeightValue string
|
||||
LLUIColor mAvatarHeightValueLabelColor;
|
||||
|
||||
// This text editor reference will change each time we edit a new wearable -
|
||||
// it will be grabbed from the currently visible panel
|
||||
|
|
|
|||
|
|
@ -964,9 +964,15 @@ void LLTaskLSLBridge::openItem()
|
|||
LLSD floater_key;
|
||||
floater_key["taskid"] = mPanel->getTaskUUID();
|
||||
floater_key["itemid"] = mUUID;
|
||||
|
||||
LLLiveLSLEditor* preview = LLFloaterReg::showTypedInstance<LLLiveLSLEditor>("preview_scriptedit", floater_key, TAKE_FOCUS_YES);
|
||||
if (preview)
|
||||
{
|
||||
LLSelectNode *node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode(NULL, TRUE);
|
||||
if (node && node->mValid)
|
||||
{
|
||||
preview->setObjectName(node->mName);
|
||||
}
|
||||
preview->setObjectID(mPanel->getTaskUUID());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -733,7 +733,7 @@ void LLPanelOutfitEdit::onSearchEdit(const std::string& string)
|
|||
if (mSearchString == "")
|
||||
{
|
||||
mInventoryItemsPanel->setFilterSubString(LLStringUtil::null);
|
||||
mWearableItemsList->setFilterSubString(LLStringUtil::null);
|
||||
mWearableItemsList->setFilterSubString(LLStringUtil::null, true);
|
||||
// re-open folders that were initially open
|
||||
mSavedFolderState->setApply(TRUE);
|
||||
mInventoryItemsPanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState);
|
||||
|
|
@ -763,8 +763,7 @@ void LLPanelOutfitEdit::onSearchEdit(const std::string& string)
|
|||
|
||||
// set new filter string
|
||||
mInventoryItemsPanel->setFilterSubString(mSearchString);
|
||||
mWearableItemsList->setFilterSubString(mSearchString);
|
||||
|
||||
mWearableItemsList->setFilterSubString(mSearchString, true);
|
||||
}
|
||||
|
||||
void LLPanelOutfitEdit::onPlusBtnClicked(void)
|
||||
|
|
|
|||
|
|
@ -28,19 +28,19 @@
|
|||
|
||||
#include "llpaneloutfitsinventory.h"
|
||||
|
||||
#include "llnotificationsutil.h"
|
||||
#include "lltabcontainer.h"
|
||||
|
||||
#include "llagentwearables.h"
|
||||
#include "llappearancemgr.h"
|
||||
#include "llfloatersidepanelcontainer.h"
|
||||
#include "llinventoryfunctions.h"
|
||||
#include "llinventorymodelbackgroundfetch.h"
|
||||
#include "llagentwearables.h"
|
||||
#include "llappearancemgr.h"
|
||||
#include "lloutfitobserver.h"
|
||||
#include "llnotificationsutil.h"
|
||||
#include "lloutfitgallery.h"
|
||||
#include "lloutfitobserver.h"
|
||||
#include "lloutfitslist.h"
|
||||
#include "llpanelappearancetab.h"
|
||||
#include "llpanelwearing.h"
|
||||
#include "llsidepanelappearance.h"
|
||||
#include "lltabcontainer.h"
|
||||
#include "llviewercontrol.h"
|
||||
#include "llviewerfoldertype.h"
|
||||
|
||||
|
|
@ -159,25 +159,12 @@ void LLPanelOutfitsInventory::onSearchEdit(const std::string& string)
|
|||
{
|
||||
if (!mActivePanel) return;
|
||||
|
||||
mFilterSubString = string;
|
||||
|
||||
if (string == "")
|
||||
{
|
||||
mActivePanel->setFilterSubString(LLStringUtil::null);
|
||||
}
|
||||
|
||||
if (!LLInventoryModelBackgroundFetch::instance().inventoryFetchStarted())
|
||||
{
|
||||
llassert(false); // this should have been done on startup
|
||||
LLInventoryModelBackgroundFetch::instance().start();
|
||||
}
|
||||
|
||||
if (mActivePanel->getFilterSubString().empty() && string.empty())
|
||||
{
|
||||
// current filter and new filter empty, do nothing
|
||||
return;
|
||||
}
|
||||
|
||||
// set new filter string
|
||||
mActivePanel->setFilterSubString(string);
|
||||
}
|
||||
|
|
@ -302,6 +289,7 @@ bool LLPanelOutfitsInventory::isActionEnabled(const LLSD& userdata)
|
|||
{
|
||||
return mActivePanel && mActivePanel->isActionEnabled(userdata);
|
||||
}
|
||||
|
||||
// List Commands //
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
@ -330,7 +318,7 @@ void LLPanelOutfitsInventory::onTabChange()
|
|||
mActivePanel = dynamic_cast<LLPanelAppearanceTab*>(mAppearanceTabs->getCurrentPanel());
|
||||
if (!mActivePanel) return;
|
||||
|
||||
mActivePanel->setFilterSubString(mFilterSubString);
|
||||
mActivePanel->checkFilterSubString();
|
||||
mActivePanel->onOpen(LLSD());
|
||||
|
||||
updateVerbs();
|
||||
|
|
@ -357,8 +345,6 @@ bool LLPanelOutfitsInventory::isOutfitsGalleryPanelActive() const
|
|||
return mActivePanel->getName() == OUTFIT_GALLERY_TAB_NAME;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void LLPanelOutfitsInventory::setWearablesLoading(bool val)
|
||||
{
|
||||
updateVerbs();
|
||||
|
|
|
|||
|
|
@ -66,7 +66,6 @@ protected:
|
|||
|
||||
private:
|
||||
LLTabContainer* mAppearanceTabs;
|
||||
std::string mFilterSubString;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// tab panels //
|
||||
|
|
|
|||
|
|
@ -561,7 +561,6 @@ void LLPanelProfilePick::setAvatarId(const LLUUID& avatar_id)
|
|||
{
|
||||
mPickName->setEnabled(TRUE);
|
||||
mPickDescription->setEnabled(TRUE);
|
||||
mSetCurrentLocationButton->setVisible(TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -576,7 +575,6 @@ BOOL LLPanelProfilePick::postBuild()
|
|||
mSaveButton = getChild<LLButton>("save_changes_btn");
|
||||
mCreateButton = getChild<LLButton>("create_changes_btn");
|
||||
mCancelButton = getChild<LLButton>("cancel_changes_btn");
|
||||
mSetCurrentLocationButton = getChild<LLButton>("set_to_curr_location_btn");
|
||||
|
||||
mSnapshotCtrl = getChild<LLTextureCtrl>("pick_snapshot");
|
||||
mSnapshotCtrl->setCommitCallback(boost::bind(&LLPanelProfilePick::onSnapshotChanged, this));
|
||||
|
|
@ -587,7 +585,6 @@ BOOL LLPanelProfilePick::postBuild()
|
|||
mSaveButton->setCommitCallback(boost::bind(&LLPanelProfilePick::onClickSave, this));
|
||||
mCreateButton->setCommitCallback(boost::bind(&LLPanelProfilePick::onClickSave, this));
|
||||
mCancelButton->setCommitCallback(boost::bind(&LLPanelProfilePick::onClickCancel, this));
|
||||
mSetCurrentLocationButton->setCommitCallback(boost::bind(&LLPanelProfilePick::onClickSetLocation, this));
|
||||
|
||||
mPickName->setKeystrokeCallback(boost::bind(&LLPanelProfilePick::onPickChanged, this, _1), NULL);
|
||||
mPickName->setEnabled(FALSE);
|
||||
|
|
@ -749,32 +746,6 @@ BOOL LLPanelProfilePick::isDirty() const
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
void LLPanelProfilePick::onClickSetLocation()
|
||||
{
|
||||
// Save location for later use.
|
||||
setPosGlobal(gAgent.getPositionGlobal());
|
||||
|
||||
std::string parcel_name, region_name;
|
||||
|
||||
LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
|
||||
if (parcel)
|
||||
{
|
||||
mParcelId = parcel->getID();
|
||||
parcel_name = parcel->getName();
|
||||
}
|
||||
|
||||
LLViewerRegion* region = gAgent.getRegion();
|
||||
if (region)
|
||||
{
|
||||
region_name = region->getName();
|
||||
}
|
||||
|
||||
setPickLocation(createLocationText(getLocationNotice(), parcel_name, region_name, getPosGlobal()));
|
||||
|
||||
mLocationChanged = true;
|
||||
enableSaveButton(TRUE);
|
||||
}
|
||||
|
||||
void LLPanelProfilePick::onClickSave()
|
||||
{
|
||||
sendUpdate();
|
||||
|
|
|
|||
|
|
@ -201,11 +201,6 @@ protected:
|
|||
*/
|
||||
void resetDirty() override;
|
||||
|
||||
/**
|
||||
* Callback for "Set Location" button click
|
||||
*/
|
||||
void onClickSetLocation();
|
||||
|
||||
/**
|
||||
* Callback for "Save" and "Create" button click
|
||||
*/
|
||||
|
|
@ -228,7 +223,6 @@ protected:
|
|||
LLTextureCtrl* mSnapshotCtrl;
|
||||
LLLineEditor* mPickName;
|
||||
LLTextEditor* mPickDescription;
|
||||
LLButton* mSetCurrentLocationButton;
|
||||
LLButton* mSaveButton;
|
||||
LLButton* mCreateButton;
|
||||
LLButton* mCancelButton;
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
// Viewer includes
|
||||
#include "llcombobox.h"
|
||||
#include "llsliderctrl.h"
|
||||
#include "llstartup.h"
|
||||
#include "llviewercontrol.h"
|
||||
#include "llvoiceclient.h"
|
||||
#include "llvoicechannel.h"
|
||||
|
|
@ -70,11 +71,14 @@ BOOL LLPanelVoiceDeviceSettings::postBuild()
|
|||
|
||||
mCtrlInputDevices = getChild<LLComboBox>("voice_input_device");
|
||||
mCtrlOutputDevices = getChild<LLComboBox>("voice_output_device");
|
||||
mUnmuteBtn = getChild<LLButton>("unmute_btn");
|
||||
|
||||
mCtrlInputDevices->setCommitCallback(
|
||||
boost::bind(&LLPanelVoiceDeviceSettings::onCommitInputDevice, this));
|
||||
mCtrlOutputDevices->setCommitCallback(
|
||||
boost::bind(&LLPanelVoiceDeviceSettings::onCommitOutputDevice, this));
|
||||
mUnmuteBtn->setCommitCallback(
|
||||
boost::bind(&LLPanelVoiceDeviceSettings::onCommitUnmute, this));
|
||||
|
||||
mLocalizedDeviceNames[DEFAULT_DEVICE] = getString("default_text");
|
||||
mLocalizedDeviceNames["No Device"] = getString("name_no_device");
|
||||
|
|
@ -108,11 +112,27 @@ void LLPanelVoiceDeviceSettings::draw()
|
|||
|
||||
// let user know that volume indicator is not yet available
|
||||
bool is_in_tuning_mode = LLVoiceClient::getInstance()->inTuningMode();
|
||||
getChildView("wait_text")->setVisible( !is_in_tuning_mode && mUseTuningMode);
|
||||
bool voice_enabled = LLVoiceClient::getInstance()->voiceEnabled();
|
||||
if (voice_enabled)
|
||||
{
|
||||
getChildView("wait_text")->setVisible( !is_in_tuning_mode && mUseTuningMode);
|
||||
getChildView("disabled_text")->setVisible(FALSE);
|
||||
mUnmuteBtn->setVisible(FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
getChildView("wait_text")->setVisible(FALSE);
|
||||
|
||||
static LLCachedControl<bool> chat_enabled(gSavedSettings, "EnableVoiceChat");
|
||||
// If voice isn't enabled, it is either disabled or muted
|
||||
bool voice_disabled = chat_enabled() || LLStartUp::getStartupState() <= STATE_LOGIN_WAIT;
|
||||
getChildView("disabled_text")->setVisible(voice_disabled);
|
||||
mUnmuteBtn->setVisible(!voice_disabled);
|
||||
}
|
||||
|
||||
LLPanel::draw();
|
||||
|
||||
if (is_in_tuning_mode)
|
||||
if (is_in_tuning_mode && voice_enabled)
|
||||
{
|
||||
const S32 num_bars = 5;
|
||||
F32 voice_power = LLVoiceClient::getInstance()->tuningGetEnergy() / LLVoiceClient::OVERDRIVEN_POWER_LEVEL;
|
||||
|
|
@ -339,3 +359,8 @@ void LLPanelVoiceDeviceSettings::onInputDevicesClicked()
|
|||
{
|
||||
LLVoiceClient::getInstance()->refreshDeviceLists(false); // fill in the pop up menus again if needed.
|
||||
}
|
||||
|
||||
void LLPanelVoiceDeviceSettings::onCommitUnmute()
|
||||
{
|
||||
gSavedSettings.setBOOL("EnableVoiceChat", TRUE);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,12 +55,14 @@ protected:
|
|||
void onCommitOutputDevice();
|
||||
void onOutputDevicesClicked();
|
||||
void onInputDevicesClicked();
|
||||
void onCommitUnmute();
|
||||
|
||||
F32 mMicVolume;
|
||||
std::string mInputDevice;
|
||||
std::string mOutputDevice;
|
||||
class LLComboBox *mCtrlInputDevices;
|
||||
class LLComboBox *mCtrlOutputDevices;
|
||||
class LLButton *mUnmuteBtn;
|
||||
BOOL mDevicesUpdated;
|
||||
bool mUseTuningMode;
|
||||
std::map<std::string, std::string> mLocalizedDeviceNames;
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ LLPanelVolumePulldown::LLPanelVolumePulldown()
|
|||
{
|
||||
mCommitCallbackRegistrar.add("Vol.setControlFalse", boost::bind(&LLPanelVolumePulldown::setControlFalse, this, _2));
|
||||
mCommitCallbackRegistrar.add("Vol.SetSounds", boost::bind(&LLPanelVolumePulldown::onClickSetSounds, this));
|
||||
mCommitCallbackRegistrar.add("Vol.updateMediaAutoPlayCheckbox", boost::bind(&LLPanelVolumePulldown::updateMediaAutoPlayCheckbox, this, _1));
|
||||
mCommitCallbackRegistrar.add("Vol.updateCheckbox", boost::bind(&LLPanelVolumePulldown::updateCheckbox, this, _1, _2));
|
||||
mCommitCallbackRegistrar.add("Vol.GoAudioPrefs", boost::bind(&LLPanelVolumePulldown::onAdvancedButtonClick, this, _2));
|
||||
buildFromFile( "panel_volume_pulldown.xml");
|
||||
}
|
||||
|
|
@ -90,19 +90,23 @@ void LLPanelVolumePulldown::setControlFalse(const LLSD& user_data)
|
|||
control->set(LLSD(FALSE));
|
||||
}
|
||||
|
||||
void LLPanelVolumePulldown::updateMediaAutoPlayCheckbox(LLUICtrl* ctrl)
|
||||
void LLPanelVolumePulldown::updateCheckbox(LLUICtrl* ctrl, const LLSD& user_data)
|
||||
{
|
||||
std::string name = ctrl->getName();
|
||||
std::string control_name = user_data.asString();
|
||||
if (control_name == "MediaAutoPlay")
|
||||
{
|
||||
std::string name = ctrl->getName();
|
||||
|
||||
// Disable "Allow Media to auto play" only when both
|
||||
// "Streaming Music" and "Media" are unchecked. STORM-513.
|
||||
if ((name == "enable_music") || (name == "enable_media"))
|
||||
{
|
||||
bool music_enabled = getChild<LLCheckBoxCtrl>("enable_music")->get();
|
||||
bool media_enabled = getChild<LLCheckBoxCtrl>("enable_media")->get();
|
||||
// Disable "Allow Media to auto play" only when both
|
||||
// "Streaming Music" and "Media" are unchecked. STORM-513.
|
||||
if ((name == "enable_music") || (name == "enable_media"))
|
||||
{
|
||||
bool music_enabled = getChild<LLCheckBoxCtrl>("enable_music")->get();
|
||||
bool media_enabled = getChild<LLCheckBoxCtrl>("enable_media")->get();
|
||||
|
||||
getChild<LLCheckBoxCtrl>("media_auto_play_combo")->setEnabled(music_enabled || media_enabled);
|
||||
}
|
||||
getChild<LLCheckBoxCtrl>("media_auto_play_combo")->setEnabled(music_enabled || media_enabled);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelVolumePulldown::onClickSetSounds()
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ class LLPanelVolumePulldown : public LLPanelPulldown
|
|||
void onClickSetSounds();
|
||||
// Disables "Allow Media to auto play" check box only when both
|
||||
// "Streaming Music" and "Media" are unchecked. Otherwise enables it.
|
||||
void updateMediaAutoPlayCheckbox(LLUICtrl* ctrl);
|
||||
void updateCheckbox(LLUICtrl* ctrl, const LLSD& user_data);
|
||||
void onAdvancedButtonClick(const LLSD& user_data);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -209,8 +209,6 @@ protected:
|
|||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::string LLPanelAppearanceTab::sFilterSubString = LLStringUtil::null;
|
||||
|
||||
static LLPanelInjector<LLPanelWearing> t_panel_wearing("panel_wearing");
|
||||
|
||||
LLPanelWearing::LLPanelWearing()
|
||||
|
|
@ -328,10 +326,11 @@ void LLPanelWearing::startUpdateTimer()
|
|||
}
|
||||
|
||||
// virtual
|
||||
void LLPanelWearing::setFilterSubString(const std::string& string)
|
||||
void LLPanelWearing::onFilterSubStringChanged(const std::string& new_string, const std::string& old_string)
|
||||
{
|
||||
sFilterSubString = string;
|
||||
mCOFItemsList->setFilterSubString(sFilterSubString);
|
||||
mCOFItemsList->setFilterSubString(new_string, true);
|
||||
|
||||
mAccordionCtrl->arrange();
|
||||
}
|
||||
|
||||
// virtual
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ public:
|
|||
|
||||
/*virtual*/ void onOpen(const LLSD& info);
|
||||
|
||||
/*virtual*/ void setFilterSubString(const std::string& string);
|
||||
/*virtual*/ void onFilterSubStringChanged(const std::string& new_string, const std::string& old_string);
|
||||
|
||||
/*virtual*/ bool isActionEnabled(const LLSD& userdata);
|
||||
|
||||
|
|
|
|||
|
|
@ -87,6 +87,9 @@
|
|||
#include "llexperiencecache.h"
|
||||
#include "llfloaterexperienceprofile.h"
|
||||
#include "llviewerassetupload.h"
|
||||
#include "lltoggleablemenu.h"
|
||||
#include "llmenubutton.h"
|
||||
#include "llinventoryfunctions.h"
|
||||
|
||||
const std::string HELLO_LSL =
|
||||
"default\n"
|
||||
|
|
@ -322,6 +325,38 @@ void LLFloaterScriptSearch::onSearchBoxCommit()
|
|||
}
|
||||
}
|
||||
|
||||
/// ---------------------------------------------------------------------------
|
||||
|
||||
class LLScriptMovedObserver : public LLInventoryObserver
|
||||
{
|
||||
public:
|
||||
LLScriptMovedObserver(LLPreviewLSL *floater) : mPreview(floater) { gInventory.addObserver(this); }
|
||||
virtual ~LLScriptMovedObserver() { gInventory.removeObserver(this); }
|
||||
virtual void changed(U32 mask);
|
||||
|
||||
private:
|
||||
LLPreviewLSL *mPreview;
|
||||
};
|
||||
|
||||
void LLScriptMovedObserver::changed(U32 mask)
|
||||
{
|
||||
const std::set<LLUUID> &mChangedItemIDs = gInventory.getChangedIDs();
|
||||
std::set<LLUUID>::const_iterator it;
|
||||
|
||||
const LLUUID &item_id = mPreview->getScriptID();
|
||||
|
||||
for (it = mChangedItemIDs.begin(); it != mChangedItemIDs.end(); it++)
|
||||
{
|
||||
if (*it == item_id)
|
||||
{
|
||||
if ((mask & (LLInventoryObserver::STRUCTURE)) != 0)
|
||||
{
|
||||
mPreview->setDirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// ---------------------------------------------------------------------------
|
||||
/// LLScriptEdCore
|
||||
/// ---------------------------------------------------------------------------
|
||||
|
|
@ -460,6 +495,13 @@ BOOL LLScriptEdCore::postBuild()
|
|||
LLSyntaxIdLSL::getInstance()->initialize();
|
||||
processKeywords();
|
||||
|
||||
mCommitCallbackRegistrar.add("FontSize.Set", boost::bind(&LLScriptEdCore::onChangeFontSize, this, _2));
|
||||
mEnableCallbackRegistrar.add("FontSize.Check", boost::bind(&LLScriptEdCore::isFontSizeChecked, this, _2));
|
||||
|
||||
LLToggleableMenu *context_menu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>(
|
||||
"menu_lsl_font_size.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
|
||||
getChild<LLMenuButton>("font_btn")->setMenu(context_menu, LLMenuButton::MP_BOTTOM_LEFT, true);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
@ -788,7 +830,7 @@ void LLScriptEdCore::setHelpPage(const std::string& help_string)
|
|||
|
||||
LLUIString url_string = gSavedSettings.getString("LSLHelpURL");
|
||||
|
||||
url_string.setArg("[LSL_STRING]", help_string);
|
||||
url_string.setArg("[LSL_STRING]", help_string.empty() ? HELP_LSL_PORTAL_TOPIC : help_string);
|
||||
|
||||
addHelpItemToHistory(help_string);
|
||||
|
||||
|
|
@ -1288,7 +1330,21 @@ LLUUID LLScriptEdCore::getAssociatedExperience()const
|
|||
return mAssociatedExperience;
|
||||
}
|
||||
|
||||
void LLLiveLSLEditor::setExperienceIds( const LLSD& experience_ids )
|
||||
void LLScriptEdCore::onChangeFontSize(const LLSD &userdata)
|
||||
{
|
||||
const std::string font_name = userdata.asString();
|
||||
gSavedSettings.setString("LSLFontSizeName", font_name);
|
||||
}
|
||||
|
||||
bool LLScriptEdCore::isFontSizeChecked(const LLSD &userdata)
|
||||
{
|
||||
const std::string current_size_name = LLScriptEditor::getScriptFontSize();
|
||||
const std::string size_name = userdata.asString();
|
||||
|
||||
return (size_name == current_size_name);
|
||||
}
|
||||
|
||||
void LLLiveLSLEditor::setExperienceIds( const LLSD& experience_ids )
|
||||
{
|
||||
mExperienceIds=experience_ids;
|
||||
updateExperiencePanel();
|
||||
|
|
@ -1476,7 +1532,21 @@ bool LLScriptEdContainer::onExternalChange(const std::string& filename)
|
|||
return true;
|
||||
}
|
||||
|
||||
/// ---------------------------------------------------------------------------
|
||||
BOOL LLScriptEdContainer::handleKeyHere(KEY key, MASK mask)
|
||||
{
|
||||
if (('A' == key) && (MASK_CONTROL == (mask & MASK_MODIFIERS)))
|
||||
{
|
||||
mScriptEd->selectAll();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (!LLPreview::handleKeyHere(key, mask))
|
||||
{
|
||||
return mScriptEd->handleKeyHere(key, mask);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
/// ---------------------------------------------------------------------------
|
||||
/// LLPreviewLSL
|
||||
/// ---------------------------------------------------------------------------
|
||||
|
||||
|
|
@ -1517,6 +1587,14 @@ LLPreviewLSL::LLPreviewLSL(const LLSD& key )
|
|||
mPendingUploads(0)
|
||||
{
|
||||
mFactoryMap["script panel"] = LLCallbackMap(LLPreviewLSL::createScriptEdPanel, this);
|
||||
|
||||
mItemObserver = new LLScriptMovedObserver(this);
|
||||
}
|
||||
|
||||
LLPreviewLSL::~LLPreviewLSL()
|
||||
{
|
||||
delete mItemObserver;
|
||||
mItemObserver = NULL;
|
||||
}
|
||||
|
||||
// virtual
|
||||
|
|
@ -1528,10 +1606,14 @@ BOOL LLPreviewLSL::postBuild()
|
|||
if (item)
|
||||
{
|
||||
getChild<LLUICtrl>("desc")->setValue(item->getDescription());
|
||||
|
||||
std::string item_path = get_category_path(item->getParentUUID());
|
||||
getChild<LLUICtrl>("path_txt")->setValue(item_path);
|
||||
getChild<LLUICtrl>("path_txt")->setToolTip(item_path);
|
||||
}
|
||||
childSetCommitCallback("desc", LLPreview::onText, this);
|
||||
getChild<LLLineEditor>("desc")->setPrevalidate(&LLTextValidate::validateASCIIPrintableNoPipe);
|
||||
|
||||
|
||||
return LLPreview::postBuild();
|
||||
}
|
||||
|
||||
|
|
@ -1543,7 +1625,12 @@ void LLPreviewLSL::draw()
|
|||
setTitle(LLTrans::getString("ScriptWasDeleted"));
|
||||
mScriptEd->setItemRemoved(TRUE);
|
||||
}
|
||||
|
||||
else if (mDirty)
|
||||
{
|
||||
std::string item_path = get_category_path(item->getParentUUID());
|
||||
getChild<LLUICtrl>("path_txt")->setValue(item_path);
|
||||
getChild<LLUICtrl>("path_txt")->setToolTip(item_path);
|
||||
}
|
||||
LLPreview::draw();
|
||||
}
|
||||
// virtual
|
||||
|
|
@ -1856,7 +1943,8 @@ LLLiveLSLEditor::LLLiveLSLEditor(const LLSD& key) :
|
|||
mPendingUploads(0),
|
||||
mIsModifiable(FALSE),
|
||||
mIsNew(false),
|
||||
mIsSaving(FALSE)
|
||||
mIsSaving(FALSE),
|
||||
mObjectName("")
|
||||
{
|
||||
mFactoryMap["script ed panel"] = LLCallbackMap(LLLiveLSLEditor::createScriptEdPanel, this);
|
||||
}
|
||||
|
|
@ -1993,6 +2081,7 @@ void LLLiveLSLEditor::loadAsset()
|
|||
}
|
||||
|
||||
refreshFromItem();
|
||||
getChild<LLUICtrl>("obj_name")->setValue(mObjectName);
|
||||
// This is commented out, because we don't completely
|
||||
// handle script exports yet.
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@
|
|||
#include "llfloatergotoline.h"
|
||||
#include "lllivefile.h"
|
||||
#include "llsyntaxid.h"
|
||||
#include "llscripteditor.h"
|
||||
|
||||
class LLLiveLSLFile;
|
||||
class LLMessageSystem;
|
||||
|
|
@ -52,6 +53,7 @@ class LLViewerInventoryItem;
|
|||
class LLScriptEdContainer;
|
||||
class LLFloaterGotoLine;
|
||||
class LLFloaterExperienceProfile;
|
||||
class LLScriptMovedObserver;
|
||||
|
||||
class LLLiveLSLFile : public LLLiveFile
|
||||
{
|
||||
|
|
@ -145,7 +147,13 @@ public:
|
|||
void setAssetID( const LLUUID& asset_id){ mAssetID = asset_id; };
|
||||
LLUUID getAssetID() { return mAssetID; }
|
||||
|
||||
private:
|
||||
bool isFontSizeChecked(const LLSD &userdata);
|
||||
void onChangeFontSize(const LLSD &size_name);
|
||||
|
||||
virtual BOOL handleKeyHere(KEY key, MASK mask);
|
||||
void selectAll() { mEditor->selectAll(); }
|
||||
|
||||
private:
|
||||
void onBtnDynamicHelp();
|
||||
void onBtnUndoChanges();
|
||||
|
||||
|
|
@ -153,8 +161,6 @@ private:
|
|||
|
||||
void selectFirstError();
|
||||
|
||||
virtual BOOL handleKeyHere(KEY key, MASK mask);
|
||||
|
||||
void enableSave(BOOL b) {mEnableSave = b;}
|
||||
|
||||
protected:
|
||||
|
|
@ -207,6 +213,8 @@ public:
|
|||
LLScriptEdContainer(const LLSD& key);
|
||||
LLScriptEdContainer(const LLSD& key, const bool live);
|
||||
|
||||
BOOL handleKeyHere(KEY key, MASK mask);
|
||||
|
||||
protected:
|
||||
std::string getTmpFileName(const std::string& script_name);
|
||||
bool onExternalChange(const std::string& filename);
|
||||
|
|
@ -220,6 +228,12 @@ class LLPreviewLSL : public LLScriptEdContainer
|
|||
{
|
||||
public:
|
||||
LLPreviewLSL(const LLSD& key );
|
||||
~LLPreviewLSL();
|
||||
|
||||
LLUUID getScriptID() { return mItemUUID; }
|
||||
|
||||
void setDirty() { mDirty = true; }
|
||||
|
||||
virtual void callbackLSLCompileSucceeded();
|
||||
virtual void callbackLSLCompileFailed(const LLSD& compile_errors);
|
||||
|
||||
|
|
@ -251,6 +265,8 @@ protected:
|
|||
// Can safely close only after both text and bytecode are uploaded
|
||||
S32 mPendingUploads;
|
||||
|
||||
LLScriptMovedObserver* mItemObserver;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -283,6 +299,8 @@ public:
|
|||
void requestExperiences();
|
||||
void experienceChanged();
|
||||
void addAssociatedExperience(const LLSD& experience);
|
||||
|
||||
void setObjectName(std::string name) { mObjectName = name; }
|
||||
|
||||
private:
|
||||
virtual BOOL canClose();
|
||||
|
|
@ -341,6 +359,7 @@ private:
|
|||
LLSD mExperienceIds;
|
||||
|
||||
LLHandle<LLFloater> mExperienceProfile;
|
||||
std::string mObjectName;
|
||||
};
|
||||
|
||||
#endif // LL_LLPREVIEWSCRIPT_H
|
||||
|
|
|
|||
|
|
@ -657,19 +657,6 @@ void LLSceneMonitor::dumpToFile(const std::string &file_name)
|
|||
}
|
||||
}
|
||||
|
||||
typedef LLTrace::StatType<LLTrace::MemAccumulator> trace_mem;
|
||||
for (auto& it : trace_mem::instance_snapshot())
|
||||
{
|
||||
os << it.getName() << "(KiB)";
|
||||
|
||||
for (S32 frame = 1; frame <= frame_count; frame++)
|
||||
{
|
||||
os << ", " << scene_load_recording.getPrevRecording(frame_count - frame).getMax(it).valueInUnits<LLUnits::Kilobytes>();
|
||||
}
|
||||
|
||||
os << '\n';
|
||||
}
|
||||
|
||||
os.flush();
|
||||
os.close();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,19 +30,22 @@
|
|||
|
||||
#include "llsyntaxid.h"
|
||||
#include "lllocalcliprect.h"
|
||||
#include "llviewercontrol.h"
|
||||
|
||||
const S32 UI_TEXTEDITOR_LINE_NUMBER_MARGIN = 32;
|
||||
|
||||
static LLDefaultChildRegistry::Register<LLScriptEditor> r("script_editor");
|
||||
|
||||
LLScriptEditor::Params::Params()
|
||||
: show_line_numbers("show_line_numbers", true)
|
||||
: show_line_numbers("show_line_numbers", true),
|
||||
default_font_size("default_font_size", false)
|
||||
{}
|
||||
|
||||
|
||||
LLScriptEditor::LLScriptEditor(const Params& p)
|
||||
: LLTextEditor(p)
|
||||
, mShowLineNumbers(p.show_line_numbers)
|
||||
, mShowLineNumbers(p.show_line_numbers),
|
||||
mUseDefaultFontSize(p.default_font_size)
|
||||
{
|
||||
if (mShowLineNumbers)
|
||||
{
|
||||
|
|
@ -51,6 +54,12 @@ LLScriptEditor::LLScriptEditor(const Params& p)
|
|||
}
|
||||
}
|
||||
|
||||
BOOL LLScriptEditor::postBuild()
|
||||
{
|
||||
gSavedSettings.getControl("LSLFontSizeName")->getCommitSignal()->connect(boost::bind(&LLScriptEditor::onFontSizeChange, this));
|
||||
return LLTextEditor::postBuild();
|
||||
}
|
||||
|
||||
void LLScriptEditor::draw()
|
||||
{
|
||||
{
|
||||
|
|
@ -110,12 +119,11 @@ void LLScriptEditor::drawLineNumbers()
|
|||
// draw the line numbers
|
||||
if(line.mLineNum != last_line_num && line.mRect.mTop <= scrolled_view_rect.mTop)
|
||||
{
|
||||
const LLFontGL *num_font = LLFontGL::getFontMonospace();
|
||||
const LLWString ltext = utf8str_to_wstring(llformat("%d", line.mLineNum ));
|
||||
BOOL is_cur_line = cursor_line == line.mLineNum;
|
||||
const U8 style = is_cur_line ? LLFontGL::BOLD : LLFontGL::NORMAL;
|
||||
const LLColor4 fg_color = is_cur_line ? mCursorColor : mReadOnlyFgColor;
|
||||
num_font->render(
|
||||
getScriptFont()->render(
|
||||
ltext, // string to draw
|
||||
0, // begin offset
|
||||
UI_TEXTEDITOR_LINE_NUMBER_MARGIN - 2, // x
|
||||
|
|
@ -143,8 +151,10 @@ void LLScriptEditor::loadKeywords()
|
|||
LL_PROFILE_ZONE_SCOPED;
|
||||
mKeywords.processTokens();
|
||||
|
||||
LLStyleConstSP style = new LLStyle(LLStyle::Params().font(getScriptFont()).color(mDefaultColor.get()));
|
||||
|
||||
segment_vec_t segment_list;
|
||||
mKeywords.findSegments(&segment_list, getWText(), mDefaultColor.get(), *this);
|
||||
mKeywords.findSegments(&segment_list, getWText(), *this, style);
|
||||
|
||||
mSegments.clear();
|
||||
segment_set_t::iterator insert_it = mSegments.begin();
|
||||
|
|
@ -159,9 +169,12 @@ void LLScriptEditor::updateSegments()
|
|||
if (mReflowIndex < S32_MAX && mKeywords.isLoaded() && mParseOnTheFly)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
|
||||
LLStyleConstSP style = new LLStyle(LLStyle::Params().font(getScriptFont()).color(mDefaultColor.get()));
|
||||
|
||||
// HACK: No non-ascii keywords for now
|
||||
segment_vec_t segment_list;
|
||||
mKeywords.findSegments(&segment_list, getWText(), mDefaultColor.get(), *this);
|
||||
mKeywords.findSegments(&segment_list, getWText(), *this, style);
|
||||
|
||||
clearSegments();
|
||||
for (segment_vec_t::iterator list_it = segment_list.begin(); list_it != segment_list.end(); ++list_it)
|
||||
|
|
@ -211,3 +224,23 @@ void LLScriptEditor::drawSelectionBackground()
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string LLScriptEditor::getScriptFontSize()
|
||||
{
|
||||
static LLCachedControl<std::string> size_name(gSavedSettings, "LSLFontSizeName", "Monospace");
|
||||
return size_name;
|
||||
}
|
||||
|
||||
LLFontGL* LLScriptEditor::getScriptFont()
|
||||
{
|
||||
std::string font_size_name = mUseDefaultFontSize ? "Monospace" : getScriptFontSize();
|
||||
return LLFontGL::getFont(LLFontDescriptor("Monospace", font_size_name, 0));
|
||||
}
|
||||
|
||||
void LLScriptEditor::onFontSizeChange()
|
||||
{
|
||||
if (!mUseDefaultFontSize)
|
||||
{
|
||||
needsReflow();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ public:
|
|||
struct Params : public LLInitParam::Block<Params, LLTextEditor::Params>
|
||||
{
|
||||
Optional<bool> show_line_numbers;
|
||||
|
||||
Optional<bool> default_font_size;
|
||||
Params();
|
||||
};
|
||||
|
||||
|
|
@ -45,6 +45,7 @@ public:
|
|||
|
||||
// LLView override
|
||||
virtual void draw();
|
||||
BOOL postBuild();
|
||||
|
||||
void initKeywords();
|
||||
void loadKeywords();
|
||||
|
|
@ -52,7 +53,11 @@ public:
|
|||
LLKeywords::keyword_iterator_t keywordsBegin() { return mKeywords.begin(); }
|
||||
LLKeywords::keyword_iterator_t keywordsEnd() { return mKeywords.end(); }
|
||||
|
||||
protected:
|
||||
static std::string getScriptFontSize();
|
||||
LLFontGL* getScriptFont();
|
||||
void onFontSizeChange();
|
||||
|
||||
protected:
|
||||
friend class LLUICtrlFactory;
|
||||
LLScriptEditor(const Params& p);
|
||||
|
||||
|
|
@ -65,6 +70,7 @@ private:
|
|||
|
||||
LLKeywords mKeywords;
|
||||
bool mShowLineNumbers;
|
||||
bool mUseDefaultFontSize;
|
||||
};
|
||||
|
||||
#endif // LL_SCRIPTEDITOR_H
|
||||
|
|
|
|||
|
|
@ -75,6 +75,17 @@ bool LLSearchHistory::save()
|
|||
{
|
||||
// build filename for each user
|
||||
std::string resolved_filename = getHistoryFilePath();
|
||||
|
||||
// delete the file if it is empty or contains only empty entries
|
||||
if (std::find_if(mSearchHistory.begin(), mSearchHistory.end(), [](const LLSearchHistoryItem& x)
|
||||
{
|
||||
return !x.search_query.empty();
|
||||
}) == mSearchHistory.end())
|
||||
{
|
||||
remove(resolved_filename.c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
// open a file for writing
|
||||
llofstream file(resolved_filename.c_str());
|
||||
if (!file.is_open())
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/**
|
||||
/**
|
||||
* @file llurlsimstring.cpp (was llsimurlstring.cpp)
|
||||
* @brief Handles "SLURL fragments" like Ahern/123/45 for
|
||||
* startup processing, login screen, prefs, etc.
|
||||
|
|
@ -6,21 +6,21 @@
|
|||
* $LicenseInfo:firstyear=2010&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$
|
||||
*/
|
||||
|
|
@ -36,7 +36,7 @@
|
|||
#include "curl/curl.h"
|
||||
const char* LLSLURL::SLURL_HTTP_SCHEME = "http";
|
||||
const char* LLSLURL::SLURL_HTTPS_SCHEME = "https";
|
||||
const char* LLSLURL::SLURL_SECONDLIFE_SCHEME = "secondlife";
|
||||
const char* LLSLURL::SLURL_SECONDLIFE_SCHEME = "secondlife";
|
||||
const char* LLSLURL::SLURL_SECONDLIFE_PATH = "secondlife";
|
||||
const char* LLSLURL::SLURL_COM = "slurl.com";
|
||||
// For DnD - even though www.slurl.com redirects to slurl.com in a browser, you can copy and drag
|
||||
|
|
@ -54,473 +54,469 @@ const char* LLSLURL::SIM_LOCATION_LAST = "last";
|
|||
// resolve a simstring from a slurl
|
||||
LLSLURL::LLSLURL(const std::string& slurl)
|
||||
{
|
||||
// by default we go to agni.
|
||||
mType = INVALID;
|
||||
// by default we go to agni.
|
||||
mType = INVALID;
|
||||
|
||||
if(slurl == SIM_LOCATION_HOME)
|
||||
{
|
||||
mType = HOME_LOCATION;
|
||||
}
|
||||
else if(slurl.empty() || (slurl == SIM_LOCATION_LAST))
|
||||
{
|
||||
mType = LAST_LOCATION;
|
||||
}
|
||||
else
|
||||
{
|
||||
LLURI slurl_uri;
|
||||
// parse the slurl as a uri
|
||||
if(slurl.find(':') == std::string::npos)
|
||||
{
|
||||
// There may be no scheme ('secondlife:' etc.) passed in. In that case
|
||||
// we want to normalize the slurl by putting the appropriate scheme
|
||||
// in front of the slurl. So, we grab the appropriate slurl base
|
||||
// from the grid manager which may be http://slurl.com/secondlife/ for maingrid, or
|
||||
// https://<hostname>/region/ for Standalone grid (the word region, not the region name)
|
||||
// these slurls are typically passed in from the 'starting location' box on the login panel,
|
||||
// where the user can type in <regionname>/<x>/<y>/<z>
|
||||
std::string fixed_slurl = LLGridManager::getInstance()->getSLURLBase();
|
||||
if (slurl.empty() || (slurl == SIM_LOCATION_LAST))
|
||||
{
|
||||
mType = LAST_LOCATION;
|
||||
}
|
||||
else if (slurl == SIM_LOCATION_HOME)
|
||||
{
|
||||
mType = HOME_LOCATION;
|
||||
}
|
||||
else
|
||||
{
|
||||
LLURI slurl_uri;
|
||||
// parse the slurl as a uri
|
||||
if (slurl.find(':') == std::string::npos)
|
||||
{
|
||||
// There may be no scheme ('secondlife:' etc.) passed in. In that case
|
||||
// we want to normalize the slurl by putting the appropriate scheme
|
||||
// in front of the slurl. So, we grab the appropriate slurl base
|
||||
// from the grid manager which may be http://slurl.com/secondlife/ for maingrid, or
|
||||
// https://<hostname>/region/ for Standalone grid (the word region, not the region name)
|
||||
// these slurls are typically passed in from the 'starting location' box on the login panel,
|
||||
// where the user can type in <regionname>/<x>/<y>/<z>
|
||||
std::string fixed_slurl = LLGridManager::getInstance()->getSLURLBase();
|
||||
|
||||
// the slurl that was passed in might have a prepended /, or not. So,
|
||||
// we strip off the prepended '/' so we don't end up with http://slurl.com/secondlife/<region>/<x>/<y>/<z>
|
||||
// or some such.
|
||||
|
||||
if(slurl[0] == '/')
|
||||
{
|
||||
fixed_slurl += slurl.substr(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
fixed_slurl += slurl;
|
||||
}
|
||||
// We then load the slurl into a LLURI form
|
||||
slurl_uri = LLURI(fixed_slurl);
|
||||
}
|
||||
else
|
||||
{
|
||||
// as we did have a scheme, implying a URI style slurl, we
|
||||
// simply parse it as a URI
|
||||
slurl_uri = LLURI(slurl);
|
||||
}
|
||||
|
||||
LLSD path_array = slurl_uri.pathArray();
|
||||
|
||||
// determine whether it's a maingrid URI or an Standalone/open style URI
|
||||
// by looking at the scheme. If it's a 'secondlife:' slurl scheme or
|
||||
// 'sl:' scheme, we know it's maingrid
|
||||
|
||||
// At the end of this if/else block, we'll have determined the grid,
|
||||
// and the slurl type (APP or LOCATION)
|
||||
if(slurl_uri.scheme() == LLSLURL::SLURL_SECONDLIFE_SCHEME)
|
||||
{
|
||||
// parse a maingrid style slurl. We know the grid is maingrid
|
||||
// so grab it.
|
||||
// A location slurl for maingrid (with the special schemes) can be in the form
|
||||
// secondlife://<regionname>/<x>/<y>/<z>
|
||||
// or
|
||||
// secondlife://<Grid>/secondlife/<region>/<x>/<y>/<z>
|
||||
// where if grid is empty, it specifies Agni
|
||||
|
||||
// An app style slurl for maingrid can be
|
||||
// secondlife://<Grid>/app/<app parameters>
|
||||
// where an empty grid implies Agni
|
||||
|
||||
// we'll start by checking the top of the 'path' which will be
|
||||
// either 'app', 'secondlife', or <x>.
|
||||
|
||||
// default to maingrid
|
||||
|
||||
mGrid = MAINGRID;
|
||||
|
||||
if ((path_array[0].asString() == LLSLURL::SLURL_SECONDLIFE_PATH) ||
|
||||
(path_array[0].asString() == LLSLURL::SLURL_APP_PATH))
|
||||
{
|
||||
// it's in the form secondlife://<grid>/(app|secondlife)
|
||||
// so parse the grid name to derive the grid ID
|
||||
if (!slurl_uri.hostName().empty())
|
||||
{
|
||||
mGrid = LLGridManager::getInstance()->getGridId(slurl_uri.hostName());
|
||||
}
|
||||
else if(path_array[0].asString() == LLSLURL::SLURL_SECONDLIFE_PATH)
|
||||
{
|
||||
// If the slurl is in the form secondlife:///secondlife/<region> form,
|
||||
// then we are in fact on maingrid.
|
||||
mGrid = MAINGRID;
|
||||
}
|
||||
else if(path_array[0].asString() == LLSLURL::SLURL_APP_PATH)
|
||||
{
|
||||
// for app style slurls, where no grid name is specified, assume the currently
|
||||
// selected or logged in grid.
|
||||
mGrid = LLGridManager::getInstance()->getGridId();
|
||||
}
|
||||
// the slurl that was passed in might have a prepended /, or not. So,
|
||||
// we strip off the prepended '/' so we don't end up with http://slurl.com/secondlife/<region>/<x>/<y>/<z>
|
||||
// or some such.
|
||||
|
||||
if(mGrid.empty())
|
||||
{
|
||||
// we couldn't find the grid in the grid manager, so bail
|
||||
LL_WARNS("AppInit")<<"unable to find grid"<<LL_ENDL;
|
||||
return;
|
||||
}
|
||||
// set the type as appropriate.
|
||||
if(path_array[0].asString() == LLSLURL::SLURL_SECONDLIFE_PATH)
|
||||
{
|
||||
mType = LOCATION;
|
||||
}
|
||||
else
|
||||
{
|
||||
mType = APP;
|
||||
}
|
||||
path_array.erase(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(slurl_uri.hostName() == LLSLURL::SLURL_APP_PATH)
|
||||
if (slurl[0] == '/')
|
||||
{
|
||||
fixed_slurl += slurl.substr(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
fixed_slurl += slurl;
|
||||
}
|
||||
// We then load the slurl into a LLURI form
|
||||
slurl_uri = LLURI(fixed_slurl);
|
||||
}
|
||||
else
|
||||
{
|
||||
// as we did have a scheme, implying a URI style slurl, we
|
||||
// simply parse it as a URI
|
||||
slurl_uri = LLURI(slurl);
|
||||
}
|
||||
|
||||
LLSD path_array = slurl_uri.pathArray();
|
||||
|
||||
// determine whether it's a maingrid URI or an Standalone/open style URI
|
||||
// by looking at the scheme. If it's a 'secondlife:' slurl scheme or
|
||||
// 'sl:' scheme, we know it's maingrid
|
||||
|
||||
// At the end of this if/else block, we'll have determined the grid,
|
||||
// and the slurl type (APP or LOCATION)
|
||||
if (slurl_uri.scheme() == LLSLURL::SLURL_SECONDLIFE_SCHEME)
|
||||
{
|
||||
if (path_array.size() == 0
|
||||
&& slurl_uri.authority().empty()
|
||||
&& slurl_uri.escapedQuery().empty())
|
||||
{
|
||||
mType = EMPTY;
|
||||
// um, we need a path...
|
||||
return;
|
||||
}
|
||||
|
||||
// parse a maingrid style slurl. We know the grid is maingrid
|
||||
// so grab it.
|
||||
// A location slurl for maingrid (with the special schemes) can be in the form
|
||||
// secondlife://<regionname>/<x>/<y>/<z>
|
||||
// or
|
||||
// secondlife://<Grid>/secondlife/<region>/<x>/<y>/<z>
|
||||
// where if grid is empty, it specifies Agni
|
||||
|
||||
// An app style slurl for maingrid can be
|
||||
// secondlife://<Grid>/app/<app parameters>
|
||||
// where an empty grid implies Agni
|
||||
|
||||
// we'll start by checking the top of the 'path' which will be
|
||||
// either 'app', 'secondlife', or <x>.
|
||||
|
||||
// default to maingrid
|
||||
|
||||
mGrid = MAINGRID;
|
||||
|
||||
if ((path_array[0].asString() == LLSLURL::SLURL_SECONDLIFE_PATH) ||
|
||||
(path_array[0].asString() == LLSLURL::SLURL_APP_PATH))
|
||||
{
|
||||
// it's in the form secondlife://<grid>/(app|secondlife)
|
||||
// so parse the grid name to derive the grid ID
|
||||
if (!slurl_uri.hostName().empty())
|
||||
{
|
||||
mGrid = LLGridManager::getInstance()->getGridId(slurl_uri.hostName());
|
||||
}
|
||||
else if(path_array[0].asString() == LLSLURL::SLURL_SECONDLIFE_PATH)
|
||||
{
|
||||
// If the slurl is in the form secondlife:///secondlife/<region> form,
|
||||
// then we are in fact on maingrid.
|
||||
mGrid = MAINGRID;
|
||||
}
|
||||
else if(path_array[0].asString() == LLSLURL::SLURL_APP_PATH)
|
||||
{
|
||||
// for app style slurls, where no grid name is specified, assume the currently
|
||||
// selected or logged in grid.
|
||||
mGrid = LLGridManager::getInstance()->getGridId();
|
||||
}
|
||||
|
||||
if (mGrid.empty())
|
||||
{
|
||||
// we couldn't find the grid in the grid manager, so bail
|
||||
LL_WARNS("AppInit")<<"unable to find grid"<<LL_ENDL;
|
||||
return;
|
||||
}
|
||||
// set the type as appropriate.
|
||||
if (path_array[0].asString() == LLSLURL::SLURL_SECONDLIFE_PATH)
|
||||
{
|
||||
mType = LOCATION;
|
||||
}
|
||||
else
|
||||
{
|
||||
mType = APP;
|
||||
}
|
||||
path_array.erase(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (slurl_uri.hostName() == LLSLURL::SLURL_APP_PATH)
|
||||
{
|
||||
mType = APP;
|
||||
}
|
||||
else
|
||||
{
|
||||
// it wasn't a /secondlife/<region> or /app/<params>, so it must be secondlife://<region>
|
||||
// therefore the hostname will be the region name, and it's a location type
|
||||
mType = LOCATION;
|
||||
// 'normalize' it so the region name is in fact the head of the path_array
|
||||
path_array.insert(0, slurl_uri.hostName());
|
||||
// therefore the hostname will be the region name, and it's a location type
|
||||
mType = LOCATION;
|
||||
// 'normalize' it so the region name is in fact the head of the path_array
|
||||
path_array.insert(0, slurl_uri.hostName());
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((slurl_uri.scheme() == LLSLURL::SLURL_HTTP_SCHEME) ||
|
||||
(slurl_uri.scheme() == LLSLURL::SLURL_HTTPS_SCHEME) ||
|
||||
(slurl_uri.scheme() == LLSLURL::SLURL_X_GRID_LOCATION_INFO_SCHEME))
|
||||
{
|
||||
// We're dealing with either a Standalone style slurl or slurl.com slurl
|
||||
if ((slurl_uri.hostName() == LLSLURL::SLURL_COM) ||
|
||||
(slurl_uri.hostName() == LLSLURL::WWW_SLURL_COM) ||
|
||||
(slurl_uri.hostName() == LLSLURL::MAPS_SECONDLIFE_COM))
|
||||
{
|
||||
// slurl.com implies maingrid
|
||||
mGrid = MAINGRID;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Don't try to match any old http://<host>/ URL as a SLurl.
|
||||
// SLE SLurls will have the grid hostname in the URL, so only
|
||||
// match http URLs if the hostname matches the grid hostname
|
||||
// (or its a slurl.com or maps.secondlife.com URL).
|
||||
if ((slurl_uri.scheme() == LLSLURL::SLURL_HTTP_SCHEME ||
|
||||
slurl_uri.scheme() == LLSLURL::SLURL_HTTPS_SCHEME) &&
|
||||
slurl_uri.hostName() != LLGridManager::getInstance()->getGrid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if((slurl_uri.scheme() == LLSLURL::SLURL_HTTP_SCHEME) ||
|
||||
(slurl_uri.scheme() == LLSLURL::SLURL_HTTPS_SCHEME) ||
|
||||
(slurl_uri.scheme() == LLSLURL::SLURL_X_GRID_LOCATION_INFO_SCHEME))
|
||||
{
|
||||
// We're dealing with either a Standalone style slurl or slurl.com slurl
|
||||
if ((slurl_uri.hostName() == LLSLURL::SLURL_COM) ||
|
||||
(slurl_uri.hostName() == LLSLURL::WWW_SLURL_COM) ||
|
||||
(slurl_uri.hostName() == LLSLURL::MAPS_SECONDLIFE_COM))
|
||||
{
|
||||
// slurl.com implies maingrid
|
||||
mGrid = MAINGRID;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Don't try to match any old http://<host>/ URL as a SLurl.
|
||||
// SLE SLurls will have the grid hostname in the URL, so only
|
||||
// match http URLs if the hostname matches the grid hostname
|
||||
// (or its a slurl.com or maps.secondlife.com URL).
|
||||
if ((slurl_uri.scheme() == LLSLURL::SLURL_HTTP_SCHEME ||
|
||||
slurl_uri.scheme() == LLSLURL::SLURL_HTTPS_SCHEME) &&
|
||||
slurl_uri.hostName() != LLGridManager::getInstance()->getGrid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// As it's a Standalone grid/open, we will always have a hostname, as Standalone/open style
|
||||
// urls are properly formed, unlike the stinky maingrid style
|
||||
mGrid = slurl_uri.hostName();
|
||||
}
|
||||
if (path_array.size() == 0)
|
||||
{
|
||||
// um, we need a path...
|
||||
return;
|
||||
}
|
||||
|
||||
// we need to normalize the urls so
|
||||
// the path portion starts with the 'command' that we want to do
|
||||
// it can either be region or app.
|
||||
if ((path_array[0].asString() == LLSLURL::SLURL_REGION_PATH) ||
|
||||
(path_array[0].asString() == LLSLURL::SLURL_SECONDLIFE_PATH))
|
||||
{
|
||||
// strip off 'region' or 'secondlife'
|
||||
path_array.erase(0);
|
||||
// it's a location
|
||||
mType = LOCATION;
|
||||
}
|
||||
else if (path_array[0].asString() == LLSLURL::SLURL_APP_PATH)
|
||||
{
|
||||
mType = APP;
|
||||
path_array.erase(0);
|
||||
// leave app appended.
|
||||
}
|
||||
else
|
||||
{
|
||||
// not a valid https/http/x-grid-location-info slurl, so it'll likely just be a URL
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// invalid scheme, so bail
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if(path_array.size() == 0)
|
||||
{
|
||||
// we gotta have some stuff after the specifier as to whether it's a region or command
|
||||
return;
|
||||
}
|
||||
|
||||
// now that we know whether it's an app slurl or a location slurl,
|
||||
// parse the slurl into the proper data structures.
|
||||
if(mType == APP)
|
||||
{
|
||||
// grab the app command type and strip it (could be a command to jump somewhere,
|
||||
// or whatever )
|
||||
mAppCmd = path_array[0].asString();
|
||||
path_array.erase(0);
|
||||
|
||||
// Grab the parameters
|
||||
mAppPath = path_array;
|
||||
// and the query
|
||||
mAppQuery = slurl_uri.query();
|
||||
mAppQueryMap = slurl_uri.queryMap();
|
||||
return;
|
||||
}
|
||||
else if(mType == LOCATION)
|
||||
{
|
||||
// at this point, head of the path array should be [ <region>, <x>, <y>, <z> ] where x, y and z
|
||||
// are collectively optional
|
||||
// are optional
|
||||
// As it's a Standalone grid/open, we will always have a hostname, as Standalone/open style
|
||||
// urls are properly formed, unlike the stinky maingrid style
|
||||
mGrid = slurl_uri.hostName();
|
||||
}
|
||||
if (path_array.size() == 0)
|
||||
{
|
||||
// um, we need a path...
|
||||
return;
|
||||
}
|
||||
|
||||
mRegion = LLURI::unescape(path_array[0].asString());
|
||||
// we need to normalize the urls so
|
||||
// the path portion starts with the 'command' that we want to do
|
||||
// it can either be region or app.
|
||||
if ((path_array[0].asString() == LLSLURL::SLURL_REGION_PATH) ||
|
||||
(path_array[0].asString() == LLSLURL::SLURL_SECONDLIFE_PATH))
|
||||
{
|
||||
// strip off 'region' or 'secondlife'
|
||||
path_array.erase(0);
|
||||
// it's a location
|
||||
mType = LOCATION;
|
||||
}
|
||||
else if (path_array[0].asString() == LLSLURL::SLURL_APP_PATH)
|
||||
{
|
||||
mType = APP;
|
||||
path_array.erase(0);
|
||||
// leave app appended.
|
||||
}
|
||||
else
|
||||
{
|
||||
// not a valid https/http/x-grid-location-info slurl, so it'll likely just be a URL
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// invalid scheme, so bail
|
||||
return;
|
||||
}
|
||||
|
||||
if(LLStringUtil::containsNonprintable(mRegion))
|
||||
{
|
||||
LLStringUtil::stripNonprintable(mRegion);
|
||||
}
|
||||
if (path_array.size() == 0)
|
||||
{
|
||||
// we gotta have some stuff after the specifier as to whether it's a region or command
|
||||
return;
|
||||
}
|
||||
|
||||
path_array.erase(0);
|
||||
|
||||
// parse the x, y, and optionally z
|
||||
if(path_array.size() >= 2)
|
||||
{
|
||||
|
||||
mPosition = LLVector3(path_array); // this construction handles LLSD without all components (values default to 0.f)
|
||||
if((F32(mPosition[VX]) < 0.f) ||
|
||||
(mPosition[VX] > REGION_WIDTH_METERS) ||
|
||||
(F32(mPosition[VY]) < 0.f) ||
|
||||
(mPosition[VY] > REGION_WIDTH_METERS) ||
|
||||
(F32(mPosition[VZ]) < 0.f) ||
|
||||
(mPosition[VZ] > REGION_HEIGHT_METERS))
|
||||
{
|
||||
mType = INVALID;
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// if x, y and z were not fully passed in, go to the middle of the region.
|
||||
// teleport will adjust the actual location to make sure you're on the ground
|
||||
// and such
|
||||
mPosition = LLVector3(REGION_WIDTH_METERS/2, REGION_WIDTH_METERS/2, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
// now that we know whether it's an app slurl or a location slurl,
|
||||
// parse the slurl into the proper data structures.
|
||||
if (mType == APP)
|
||||
{
|
||||
// grab the app command type and strip it (could be a command to jump somewhere,
|
||||
// or whatever )
|
||||
mAppCmd = path_array[0].asString();
|
||||
path_array.erase(0);
|
||||
|
||||
// Grab the parameters
|
||||
mAppPath = path_array;
|
||||
// and the query
|
||||
mAppQuery = slurl_uri.query();
|
||||
mAppQueryMap = slurl_uri.queryMap();
|
||||
return;
|
||||
}
|
||||
else if (mType == LOCATION)
|
||||
{
|
||||
// at this point, head of the path array should be [ <region>, <x>, <y>, <z> ] where x, y and z
|
||||
// are collectively optional
|
||||
// are optional
|
||||
|
||||
mRegion = LLURI::unescape(path_array[0].asString());
|
||||
|
||||
if (LLStringUtil::containsNonprintable(mRegion))
|
||||
{
|
||||
LLStringUtil::stripNonprintable(mRegion);
|
||||
}
|
||||
|
||||
path_array.erase(0);
|
||||
|
||||
// parse the x, y, and optionally z
|
||||
if (path_array.size() >= 2)
|
||||
{
|
||||
mPosition = LLVector3(path_array); // this construction handles LLSD without all components (values default to 0.f)
|
||||
if ((F32(mPosition[VX]) < 0.f) || (mPosition[VX] > REGION_WIDTH_METERS) ||
|
||||
(F32(mPosition[VY]) < 0.f) || (mPosition[VY] > REGION_WIDTH_METERS) ||
|
||||
(F32(mPosition[VZ]) < 0.f) || (mPosition[VZ] > REGION_HEIGHT_METERS))
|
||||
{
|
||||
mType = INVALID;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// if x, y and z were not fully passed in, go to the middle of the region.
|
||||
// teleport will adjust the actual location to make sure you're on the ground
|
||||
// and such
|
||||
mPosition = LLVector3(REGION_WIDTH_METERS / 2, REGION_WIDTH_METERS / 2, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Create a slurl for the middle of the region
|
||||
LLSLURL::LLSLURL(const std::string& grid,
|
||||
const std::string& region)
|
||||
LLSLURL::LLSLURL(const std::string& grid, const std::string& region)
|
||||
{
|
||||
mGrid = grid;
|
||||
mRegion = region;
|
||||
mType = LOCATION;
|
||||
mPosition = LLVector3((F64)REGION_WIDTH_METERS/2, (F64)REGION_WIDTH_METERS/2, 0);
|
||||
mGrid = grid;
|
||||
mRegion = region;
|
||||
mType = LOCATION;
|
||||
mPosition = LLVector3((F64)REGION_WIDTH_METERS / 2, (F64)REGION_WIDTH_METERS / 2, 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// create a slurl given the position. The position will be modded with the region
|
||||
// width handling global positions as well
|
||||
LLSLURL::LLSLURL(const std::string& grid,
|
||||
const std::string& region,
|
||||
const LLVector3& position)
|
||||
LLSLURL::LLSLURL(const std::string& grid,
|
||||
const std::string& region,
|
||||
const LLVector3& position)
|
||||
{
|
||||
mGrid = grid;
|
||||
mRegion = region;
|
||||
S32 x = ll_round( (F32)fmod( position[VX], (F32)REGION_WIDTH_METERS ) );
|
||||
S32 y = ll_round( (F32)fmod( position[VY], (F32)REGION_WIDTH_METERS ) );
|
||||
S32 z = ll_round( (F32)position[VZ] );
|
||||
mType = LOCATION;
|
||||
mPosition = LLVector3(x, y, z);
|
||||
mGrid = grid;
|
||||
mRegion = region;
|
||||
S32 x = ll_round((F32)fmod(position[VX], (F32)REGION_WIDTH_METERS));
|
||||
S32 y = ll_round((F32)fmod(position[VY], (F32)REGION_WIDTH_METERS));
|
||||
S32 z = ll_round((F32)position[VZ]);
|
||||
mType = LOCATION;
|
||||
mPosition = LLVector3(x, y, z);
|
||||
}
|
||||
|
||||
|
||||
// create a simstring
|
||||
LLSLURL::LLSLURL(const std::string& region,
|
||||
const LLVector3& position)
|
||||
LLSLURL::LLSLURL(const std::string& region,
|
||||
const LLVector3& position)
|
||||
{
|
||||
*this = LLSLURL(LLGridManager::getInstance()->getGridId(),
|
||||
region, position);
|
||||
*this = LLSLURL(LLGridManager::getInstance()->getGridId(), region, position);
|
||||
}
|
||||
|
||||
// create a slurl from a global position
|
||||
LLSLURL::LLSLURL(const std::string& grid,
|
||||
const std::string& region,
|
||||
const LLVector3d& global_position)
|
||||
LLSLURL::LLSLURL(const std::string& grid,
|
||||
const std::string& region,
|
||||
const LLVector3d& global_position)
|
||||
{
|
||||
*this = LLSLURL(LLGridManager::getInstance()->getGridId(grid),
|
||||
region, LLVector3(global_position.mdV[VX],
|
||||
global_position.mdV[VY],
|
||||
global_position.mdV[VZ]));
|
||||
*this = LLSLURL(LLGridManager::getInstance()->getGridId(grid), region,
|
||||
LLVector3(global_position.mdV[VX], global_position.mdV[VY], global_position.mdV[VZ]));
|
||||
}
|
||||
|
||||
// create a slurl from a global position
|
||||
LLSLURL::LLSLURL(const std::string& region,
|
||||
const LLVector3d& global_position)
|
||||
LLSLURL::LLSLURL(const std::string& region,
|
||||
const LLVector3d& global_position)
|
||||
{
|
||||
*this = LLSLURL(LLGridManager::getInstance()->getGridId(),
|
||||
region, global_position);
|
||||
*this = LLSLURL(LLGridManager::getInstance()->getGridId(),
|
||||
region, global_position);
|
||||
}
|
||||
|
||||
LLSLURL::LLSLURL(const std::string& command, const LLUUID&id, const std::string& verb)
|
||||
{
|
||||
mType = APP;
|
||||
mAppCmd = command;
|
||||
mAppPath = LLSD::emptyArray();
|
||||
mAppPath.append(LLSD(id));
|
||||
mAppPath.append(LLSD(verb));
|
||||
mType = APP;
|
||||
mAppCmd = command;
|
||||
mAppPath = LLSD::emptyArray();
|
||||
mAppPath.append(LLSD(id));
|
||||
mAppPath.append(LLSD(verb));
|
||||
}
|
||||
|
||||
|
||||
std::string LLSLURL::getSLURLString() const
|
||||
{
|
||||
switch(mType)
|
||||
{
|
||||
case HOME_LOCATION:
|
||||
return SIM_LOCATION_HOME;
|
||||
case LAST_LOCATION:
|
||||
return SIM_LOCATION_LAST;
|
||||
case LOCATION:
|
||||
{
|
||||
// lookup the grid
|
||||
S32 x = ll_round( (F32)mPosition[VX] );
|
||||
S32 y = ll_round( (F32)mPosition[VY] );
|
||||
S32 z = ll_round( (F32)mPosition[VZ] );
|
||||
return LLGridManager::getInstance()->getSLURLBase(mGrid) +
|
||||
LLURI::escape(mRegion) + llformat("/%d/%d/%d",x,y,z);
|
||||
}
|
||||
case APP:
|
||||
{
|
||||
std::ostringstream app_url;
|
||||
app_url << LLGridManager::getInstance()->getAppSLURLBase() << "/" << mAppCmd;
|
||||
for(LLSD::array_const_iterator i = mAppPath.beginArray();
|
||||
i != mAppPath.endArray();
|
||||
i++)
|
||||
{
|
||||
app_url << "/" << i->asString();
|
||||
}
|
||||
if(mAppQuery.length() > 0)
|
||||
{
|
||||
app_url << "?" << mAppQuery;
|
||||
}
|
||||
return app_url.str();
|
||||
}
|
||||
default:
|
||||
LL_WARNS("AppInit") << "Unexpected SLURL type for SLURL string" << (int)mType << LL_ENDL;
|
||||
return std::string();
|
||||
}
|
||||
switch (mType)
|
||||
{
|
||||
case HOME_LOCATION:
|
||||
return SIM_LOCATION_HOME;
|
||||
case LAST_LOCATION:
|
||||
return SIM_LOCATION_LAST;
|
||||
case LOCATION:
|
||||
{
|
||||
// lookup the grid
|
||||
S32 x = ll_round((F32)mPosition[VX]);
|
||||
S32 y = ll_round((F32)mPosition[VY]);
|
||||
S32 z = ll_round((F32)mPosition[VZ]);
|
||||
return LLGridManager::getInstance()->getSLURLBase(mGrid) +
|
||||
LLURI::escape(mRegion) + llformat("/%d/%d/%d", x, y, z);
|
||||
}
|
||||
case APP:
|
||||
{
|
||||
std::ostringstream app_url;
|
||||
app_url << LLGridManager::getInstance()->getAppSLURLBase() << "/" << mAppCmd;
|
||||
for (LLSD::array_const_iterator i = mAppPath.beginArray();
|
||||
i != mAppPath.endArray();
|
||||
i++)
|
||||
{
|
||||
app_url << "/" << i->asString();
|
||||
}
|
||||
if (mAppQuery.length() > 0)
|
||||
{
|
||||
app_url << "?" << mAppQuery;
|
||||
}
|
||||
return app_url.str();
|
||||
}
|
||||
default:
|
||||
LL_WARNS("AppInit") << "Unexpected SLURL type for SLURL string" << (int)mType << LL_ENDL;
|
||||
return std::string();
|
||||
}
|
||||
}
|
||||
|
||||
std::string LLSLURL::getLoginString() const
|
||||
{
|
||||
|
||||
std::stringstream unescaped_start;
|
||||
switch(mType)
|
||||
{
|
||||
case LOCATION:
|
||||
unescaped_start << "uri:"
|
||||
<< mRegion << "&"
|
||||
<< ll_round(mPosition[0]) << "&"
|
||||
<< ll_round(mPosition[1]) << "&"
|
||||
<< ll_round(mPosition[2]);
|
||||
break;
|
||||
case HOME_LOCATION:
|
||||
unescaped_start << "home";
|
||||
break;
|
||||
case LAST_LOCATION:
|
||||
unescaped_start << "last";
|
||||
break;
|
||||
default:
|
||||
LL_WARNS("AppInit") << "Unexpected SLURL type ("<<(int)mType <<")for login string"<< LL_ENDL;
|
||||
break;
|
||||
}
|
||||
return xml_escape_string(unescaped_start.str());
|
||||
std::stringstream unescaped_start;
|
||||
switch (mType)
|
||||
{
|
||||
case LOCATION:
|
||||
unescaped_start << "uri:"
|
||||
<< mRegion << "&"
|
||||
<< ll_round(mPosition[0]) << "&"
|
||||
<< ll_round(mPosition[1]) << "&"
|
||||
<< ll_round(mPosition[2]);
|
||||
break;
|
||||
case HOME_LOCATION:
|
||||
unescaped_start << "home";
|
||||
break;
|
||||
case LAST_LOCATION:
|
||||
unescaped_start << "last";
|
||||
break;
|
||||
default:
|
||||
LL_WARNS("AppInit") << "Unexpected SLURL type (" << (int)mType << ")for login string" << LL_ENDL;
|
||||
break;
|
||||
}
|
||||
return xml_escape_string(unescaped_start.str());
|
||||
}
|
||||
|
||||
bool LLSLURL::operator==(const LLSLURL& rhs)
|
||||
bool LLSLURL::operator ==(const LLSLURL& rhs)
|
||||
{
|
||||
if(rhs.mType != mType) return false;
|
||||
switch(mType)
|
||||
{
|
||||
case LOCATION:
|
||||
return ((mGrid == rhs.mGrid) &&
|
||||
(mRegion == rhs.mRegion) &&
|
||||
(mPosition == rhs.mPosition));
|
||||
case APP:
|
||||
return getSLURLString() == rhs.getSLURLString();
|
||||
|
||||
case HOME_LOCATION:
|
||||
case LAST_LOCATION:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
if (rhs.mType != mType)
|
||||
return false;
|
||||
|
||||
switch (mType)
|
||||
{
|
||||
case LOCATION:
|
||||
return (mGrid == rhs.mGrid) &&
|
||||
(mRegion == rhs.mRegion) &&
|
||||
(mPosition == rhs.mPosition);
|
||||
|
||||
case APP:
|
||||
return getSLURLString() == rhs.getSLURLString();
|
||||
|
||||
case HOME_LOCATION:
|
||||
case LAST_LOCATION:
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool LLSLURL::operator !=(const LLSLURL& rhs)
|
||||
{
|
||||
return !(*this == rhs);
|
||||
return !(*this == rhs);
|
||||
}
|
||||
|
||||
std::string LLSLURL::getLocationString() const
|
||||
{
|
||||
return llformat("%s/%d/%d/%d",
|
||||
mRegion.c_str(),
|
||||
(int)ll_round(mPosition[0]),
|
||||
(int)ll_round(mPosition[1]),
|
||||
(int)ll_round(mPosition[2]));
|
||||
return llformat("%s/%d/%d/%d",
|
||||
mRegion.c_str(),
|
||||
(int)ll_round(mPosition[0]),
|
||||
(int)ll_round(mPosition[1]),
|
||||
(int)ll_round(mPosition[2]));
|
||||
}
|
||||
|
||||
// static
|
||||
const std::string LLSLURL::typeName[NUM_SLURL_TYPES] =
|
||||
const std::string LLSLURL::typeName[NUM_SLURL_TYPES] =
|
||||
{
|
||||
"INVALID",
|
||||
"LOCATION",
|
||||
"HOME_LOCATION",
|
||||
"LAST_LOCATION",
|
||||
"APP",
|
||||
"HELP"
|
||||
"INVALID",
|
||||
"LOCATION",
|
||||
"HOME_LOCATION",
|
||||
"LAST_LOCATION",
|
||||
"APP",
|
||||
"HELP",
|
||||
"EMPTY"
|
||||
};
|
||||
|
||||
|
||||
std::string LLSLURL::getTypeString(SLURL_TYPE type)
|
||||
{
|
||||
std::string name;
|
||||
if ( type >= INVALID && type < NUM_SLURL_TYPES )
|
||||
{
|
||||
name = LLSLURL::typeName[type];
|
||||
}
|
||||
else
|
||||
{
|
||||
name = llformat("Out of Range (%d)",type);
|
||||
}
|
||||
return name;
|
||||
std::string name;
|
||||
if (type >= INVALID && type < NUM_SLURL_TYPES)
|
||||
{
|
||||
name = LLSLURL::typeName[type];
|
||||
}
|
||||
else
|
||||
{
|
||||
name = llformat("Out of Range (%d)", type);
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
std::string LLSLURL::asString() const
|
||||
{
|
||||
std::ostringstream result;
|
||||
result
|
||||
<< " mType: " << LLSLURL::getTypeString(mType)
|
||||
<< " mGrid: " + getGrid()
|
||||
<< " mRegion: " + getRegion()
|
||||
<< " mPosition: " << mPosition
|
||||
<< " mAppCmd:" << getAppCmd()
|
||||
<< " mAppPath:" + getAppPath().asString()
|
||||
<< " mAppQueryMap:" + getAppQueryMap().asString()
|
||||
<< " mAppQuery: " + getAppQuery()
|
||||
;
|
||||
|
||||
<< " mType: " << LLSLURL::getTypeString(mType)
|
||||
<< " mGrid: " + getGrid()
|
||||
<< " mRegion: " + getRegion()
|
||||
<< " mPosition: " << mPosition
|
||||
<< " mAppCmd:" << getAppCmd()
|
||||
<< " mAppPath:" + getAppPath().asString()
|
||||
<< " mAppQueryMap:" + getAppQueryMap().asString()
|
||||
<< " mAppQuery: " + getAppQuery()
|
||||
;
|
||||
|
||||
return result.str();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -52,13 +52,14 @@ public:
|
|||
static const char* SLURL_REGION_PATH;
|
||||
|
||||
// if you modify this enumeration, update typeName as well
|
||||
enum SLURL_TYPE {
|
||||
INVALID,
|
||||
enum SLURL_TYPE {
|
||||
INVALID,
|
||||
LOCATION,
|
||||
HOME_LOCATION,
|
||||
LAST_LOCATION,
|
||||
APP,
|
||||
HELP,
|
||||
EMPTY,
|
||||
NUM_SLURL_TYPES // must be last
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -830,6 +830,41 @@ void LLSpatialGroup::handleChildAddition(const OctreeNode* parent, OctreeNode* c
|
|||
assert_states_valid(this);
|
||||
}
|
||||
|
||||
//virtual
|
||||
void LLSpatialGroup::rebound()
|
||||
{
|
||||
if (!isDirty())
|
||||
return;
|
||||
|
||||
super::rebound();
|
||||
|
||||
if (mSpatialPartition->mDrawableType == LLPipeline::RENDER_TYPE_CONTROL_AV)
|
||||
{
|
||||
llassert(mSpatialPartition->mPartitionType == LLViewerRegion::PARTITION_CONTROL_AV);
|
||||
|
||||
LLSpatialBridge* bridge = getSpatialPartition()->asBridge();
|
||||
if (bridge &&
|
||||
bridge->mDrawable &&
|
||||
bridge->mDrawable->getVObj() &&
|
||||
bridge->mDrawable->getVObj()->isRoot())
|
||||
{
|
||||
LLControlAvatar* controlAvatar = bridge->mDrawable->getVObj()->getControlAvatar();
|
||||
if (controlAvatar &&
|
||||
controlAvatar->mDrawable &&
|
||||
controlAvatar->mControlAVBridge &&
|
||||
controlAvatar->mControlAVBridge->mOctree)
|
||||
{
|
||||
LLSpatialGroup* root = (LLSpatialGroup*)controlAvatar->mControlAVBridge->mOctree->getListener(0);
|
||||
if (this == root)
|
||||
{
|
||||
const LLVector4a* addingExtents = controlAvatar->mDrawable->getSpatialExtents();
|
||||
const LLXformMatrix* currentTransform = bridge->mDrawable->getXform();
|
||||
expandExtents(addingExtents, *currentTransform);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLSpatialGroup::destroyGLState(bool keep_occlusion)
|
||||
{
|
||||
|
|
@ -1283,17 +1318,8 @@ void drawBox(const LLVector4a& c, const LLVector4a& r)
|
|||
|
||||
void drawBoxOutline(const LLVector3& pos, const LLVector3& size)
|
||||
{
|
||||
|
||||
llassert(pos.isFinite());
|
||||
llassert(size.isFinite());
|
||||
|
||||
llassert(!llisnan(pos.mV[0]));
|
||||
llassert(!llisnan(pos.mV[1]));
|
||||
llassert(!llisnan(pos.mV[2]));
|
||||
|
||||
llassert(!llisnan(size.mV[0]));
|
||||
llassert(!llisnan(size.mV[1]));
|
||||
llassert(!llisnan(size.mV[2]));
|
||||
if (!pos.isFinite() || !size.isFinite())
|
||||
return;
|
||||
|
||||
LLVector3 v1 = size.scaledVec(LLVector3( 1, 1,1));
|
||||
LLVector3 v2 = size.scaledVec(LLVector3(-1, 1,1));
|
||||
|
|
|
|||
|
|
@ -201,6 +201,7 @@ public:
|
|||
LL_ALIGN_PREFIX(16)
|
||||
class LLSpatialGroup : public LLOcclusionCullingGroup
|
||||
{
|
||||
using super = LLOcclusionCullingGroup;
|
||||
friend class LLSpatialPartition;
|
||||
friend class LLOctreeStateCheck;
|
||||
public:
|
||||
|
|
@ -333,6 +334,9 @@ public:
|
|||
virtual void handleDestruction(const TreeNode* node);
|
||||
virtual void handleChildAddition(const OctreeNode* parent, OctreeNode* child);
|
||||
|
||||
// LLViewerOctreeGroup
|
||||
virtual void rebound();
|
||||
|
||||
public:
|
||||
LL_ALIGN_16(LLVector4a mViewAngle);
|
||||
LL_ALIGN_16(LLVector4a mLastUpdateViewAngle);
|
||||
|
|
|
|||
|
|
@ -2480,6 +2480,34 @@ void login_callback(S32 option, void *userdata)
|
|||
}
|
||||
}
|
||||
|
||||
void release_notes_coro(const std::string url)
|
||||
{
|
||||
if (url.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
|
||||
LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
|
||||
httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("releaseNotesCoro", httpPolicy));
|
||||
LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
|
||||
LLCore::HttpOptions::ptr_t httpOpts = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions);
|
||||
|
||||
httpOpts->setHeadersOnly(true); // only making sure it isn't 404 or something like that
|
||||
|
||||
LLSD result = httpAdapter->getAndSuspend(httpRequest, url, httpOpts);
|
||||
|
||||
LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
|
||||
LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
|
||||
|
||||
if (!status)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
LLWeb::loadURLInternal(url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if user is running a new version of the viewer.
|
||||
* Display the Release Notes if it's not overriden by the "UpdaterShowReleaseNotes" setting.
|
||||
|
|
@ -2512,7 +2540,8 @@ void show_release_notes_if_required()
|
|||
LLEventPumps::instance().obtain("relnotes").listen(
|
||||
"showrelnotes",
|
||||
[](const LLSD& url) {
|
||||
LLWeb::loadURLInternal(url.asString());
|
||||
LLCoros::instance().launch("releaseNotesCoro",
|
||||
boost::bind(&release_notes_coro, url.asString()));
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
|
@ -2520,7 +2549,9 @@ void show_release_notes_if_required()
|
|||
#endif // LL_RELEASE_FOR_DOWNLOAD
|
||||
{
|
||||
LLSD info(LLAppViewer::instance()->getViewerInfo());
|
||||
LLWeb::loadURLInternal(info["VIEWER_RELEASE_NOTES_URL"]);
|
||||
std::string url = info["VIEWER_RELEASE_NOTES_URL"].asString();
|
||||
LLCoros::instance().launch("releaseNotesCoro",
|
||||
boost::bind(&release_notes_coro, url));
|
||||
}
|
||||
release_notes_shown = true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -190,6 +190,13 @@ BOOL LLStatusBar::postBuild()
|
|||
LLHints::getInstance()->registerHintTarget("linden_balance", getChild<LLView>("balance_bg")->getHandle());
|
||||
|
||||
gSavedSettings.getControl("MuteAudio")->getSignal()->connect(boost::bind(&LLStatusBar::onVolumeChanged, this, _2));
|
||||
gSavedSettings.getControl("EnableVoiceChat")->getSignal()->connect(boost::bind(&LLStatusBar::onVoiceChanged, this, _2));
|
||||
|
||||
if (!gSavedSettings.getBOOL("EnableVoiceChat") && LLAppViewer::instance()->isSecondInstance())
|
||||
{
|
||||
// Indicate that second instance started without sound
|
||||
mBtnVolume->setImageUnselected(LLUI::getUIImage("VoiceMute_Off"));
|
||||
}
|
||||
|
||||
// Adding Net Stat Graph
|
||||
S32 x = getRect().getWidth() - 2;
|
||||
|
|
@ -640,6 +647,16 @@ void LLStatusBar::onVolumeChanged(const LLSD& newvalue)
|
|||
refresh();
|
||||
}
|
||||
|
||||
void LLStatusBar::onVoiceChanged(const LLSD& newvalue)
|
||||
{
|
||||
if (newvalue.asBoolean())
|
||||
{
|
||||
// Second instance starts with "VoiceMute_Off" icon, fix it
|
||||
mBtnVolume->setImageUnselected(LLUI::getUIImage("Audio_Off"));
|
||||
}
|
||||
refresh();
|
||||
}
|
||||
|
||||
void LLStatusBar::onUpdateFilterTerm()
|
||||
{
|
||||
LLWString searchValue = utf8str_to_wstring( mFilterEdit->getValue() );
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue