summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
Diffstat (limited to 'indra')
-rw-r--r--indra/llcommon/llthread.cpp15
-rw-r--r--indra/llcommon/llthread.h1
-rw-r--r--indra/llcommon/llversionviewer.h2
-rw-r--r--indra/llmessage/llbuffer.cpp90
-rw-r--r--indra/llmessage/llbuffer.h25
-rw-r--r--indra/llmessage/llbufferstream.cpp8
-rw-r--r--indra/llmessage/llcurl.cpp325
-rw-r--r--indra/llmessage/llcurl.h29
-rw-r--r--indra/llmessage/llhttpassetstorage.cpp10
-rw-r--r--indra/llmessage/llhttpclient.cpp12
-rw-r--r--indra/llmessage/lliohttpserver.cpp4
-rw-r--r--indra/llmessage/lliopipe.cpp6
-rw-r--r--indra/llmessage/lliopipe.h2
-rw-r--r--indra/llmessage/lliosocket.cpp3
-rw-r--r--indra/llmessage/llpumpio.cpp51
-rw-r--r--indra/llmessage/llpumpio.h13
-rw-r--r--indra/llmessage/llsdrpcclient.h22
-rw-r--r--indra/llmessage/llurlrequest.cpp24
-rw-r--r--indra/llmessage/llurlrequest.h2
-rw-r--r--indra/llrender/llrender.cpp2
-rw-r--r--indra/newview/CMakeLists.txt4
-rw-r--r--indra/newview/app_settings/settings.xml22
-rw-r--r--indra/newview/llagentwearablesfetch.cpp6
-rw-r--r--indra/newview/llappviewer.cpp4
-rw-r--r--indra/newview/llfilteredpathfindinglinksets.cpp313
-rw-r--r--indra/newview/llfilteredpathfindinglinksets.h111
-rw-r--r--indra/newview/llfloaterpathfindingconsole.cpp125
-rw-r--r--indra/newview/llfloaterpathfindingconsole.h10
-rw-r--r--indra/newview/llfloaterpathfindinglinksets.cpp795
-rw-r--r--indra/newview/llfloaterpathfindinglinksets.h199
-rw-r--r--indra/newview/llmeshrepository.cpp131
-rw-r--r--indra/newview/llmeshrepository.h4
-rw-r--r--indra/newview/llpathfindinglinkset.cpp356
-rw-r--r--indra/newview/llpathfindinglinkset.h108
-rw-r--r--indra/newview/llviewerdisplay.cpp28
-rw-r--r--indra/newview/llviewerwindow.cpp11
-rw-r--r--indra/newview/llxmlrpctransaction.cpp19
-rw-r--r--indra/newview/skins/default/xui/en/floater_pathfinding_linksets.xml6
-rw-r--r--indra/viewer_components/updater/llupdatedownloader.cpp23
39 files changed, 1816 insertions, 1105 deletions
diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp
index 4063cc730b..a6ad6b125c 100644
--- a/indra/llcommon/llthread.cpp
+++ b/indra/llcommon/llthread.cpp
@@ -337,11 +337,7 @@ LLMutex::~LLMutex()
void LLMutex::lock()
{
-#if LL_DARWIN
- if (mLockingThread == LLThread::currentID())
-#else
- if (mLockingThread == sThreadID)
-#endif
+ if(isSelfLocked())
{ //redundant lock
mCount++;
return;
@@ -398,6 +394,15 @@ bool LLMutex::isLocked()
}
}
+bool LLMutex::isSelfLocked()
+{
+#if LL_DARWIN
+ return mLockingThread == LLThread::currentID();
+#else
+ return mLockingThread == sThreadID;
+#endif
+}
+
U32 LLMutex::lockingThread() const
{
return mLockingThread;
diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h
index f0e0de6173..b52e70ab2e 100644
--- a/indra/llcommon/llthread.h
+++ b/indra/llcommon/llthread.h
@@ -151,6 +151,7 @@ public:
void lock(); // blocks
void unlock();
bool isLocked(); // non-blocking, but does do a lock/unlock so not free
+ bool isSelfLocked(); //return true if locked in a same thread
U32 lockingThread() const; //get ID of locking thread
protected:
diff --git a/indra/llcommon/llversionviewer.h b/indra/llcommon/llversionviewer.h
index 99ab053b25..27cdfcaa4e 100644
--- a/indra/llcommon/llversionviewer.h
+++ b/indra/llcommon/llversionviewer.h
@@ -29,7 +29,7 @@
const S32 LL_VERSION_MAJOR = 3;
const S32 LL_VERSION_MINOR = 2;
-const S32 LL_VERSION_PATCH = 8;
+const S32 LL_VERSION_PATCH = 9;
const S32 LL_VERSION_BUILD = 0;
const char * const LL_CHANNEL = "Second Life Developer";
diff --git a/indra/llmessage/llbuffer.cpp b/indra/llmessage/llbuffer.cpp
index 0316797f00..250cace6e9 100644
--- a/indra/llmessage/llbuffer.cpp
+++ b/indra/llmessage/llbuffer.cpp
@@ -32,6 +32,9 @@
#include "llmath.h"
#include "llmemtype.h"
#include "llstl.h"
+#include "llthread.h"
+
+#define ASSERT_LLBUFFERARRAY_MUTEX_LOCKED llassert(!mMutexp || mMutexp->isSelfLocked());
/**
* LLSegment
@@ -224,7 +227,8 @@ void LLHeapBuffer::allocate(S32 size)
* LLBufferArray
*/
LLBufferArray::LLBufferArray() :
- mNextBaseChannel(0)
+ mNextBaseChannel(0),
+ mMutexp(NULL)
{
LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
}
@@ -233,6 +237,8 @@ LLBufferArray::~LLBufferArray()
{
LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
std::for_each(mBuffers.begin(), mBuffers.end(), DeletePointer());
+
+ delete mMutexp;
}
// static
@@ -243,14 +249,57 @@ LLChannelDescriptors LLBufferArray::makeChannelConsumer(
return rv;
}
+void LLBufferArray::lock()
+{
+ if(mMutexp)
+ {
+ mMutexp->lock() ;
+ }
+}
+
+void LLBufferArray::unlock()
+{
+ if(mMutexp)
+ {
+ mMutexp->unlock() ;
+ }
+}
+
+LLMutex* LLBufferArray::getMutex()
+{
+ return mMutexp ;
+}
+
+void LLBufferArray::setThreaded(bool threaded)
+{
+ if(threaded)
+ {
+ if(!mMutexp)
+ {
+ mMutexp = new LLMutex(NULL);
+ }
+ }
+ else
+ {
+ if(mMutexp)
+ {
+ delete mMutexp ;
+ mMutexp = NULL ;
+ }
+ }
+}
+
LLChannelDescriptors LLBufferArray::nextChannel()
{
LLChannelDescriptors rv(mNextBaseChannel++);
return rv;
}
+//mMutexp should be locked before calling this.
S32 LLBufferArray::capacity() const
{
+ ASSERT_LLBUFFERARRAY_MUTEX_LOCKED
+
S32 total = 0;
const_buffer_iterator_t iter = mBuffers.begin();
const_buffer_iterator_t end = mBuffers.end();
@@ -263,6 +312,8 @@ S32 LLBufferArray::capacity() const
bool LLBufferArray::append(S32 channel, const U8* src, S32 len)
{
+ LLMutexLock lock(mMutexp) ;
+
LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
std::vector<LLSegment> segments;
if(copyIntoBuffers(channel, src, len, segments))
@@ -273,8 +324,11 @@ bool LLBufferArray::append(S32 channel, const U8* src, S32 len)
return false;
}
+//mMutexp should be locked before calling this.
bool LLBufferArray::prepend(S32 channel, const U8* src, S32 len)
{
+ ASSERT_LLBUFFERARRAY_MUTEX_LOCKED
+
LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
std::vector<LLSegment> segments;
if(copyIntoBuffers(channel, src, len, segments))
@@ -293,6 +347,8 @@ bool LLBufferArray::insertAfter(
{
LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
std::vector<LLSegment> segments;
+
+ LLMutexLock lock(mMutexp) ;
if(mSegments.end() != segment)
{
++segment;
@@ -305,8 +361,11 @@ bool LLBufferArray::insertAfter(
return false;
}
+//mMutexp should be locked before calling this.
LLBufferArray::segment_iterator_t LLBufferArray::splitAfter(U8* address)
{
+ ASSERT_LLBUFFERARRAY_MUTEX_LOCKED
+
LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
segment_iterator_t end = mSegments.end();
segment_iterator_t it = getSegment(address);
@@ -335,20 +394,26 @@ LLBufferArray::segment_iterator_t LLBufferArray::splitAfter(U8* address)
return rv;
}
+//mMutexp should be locked before calling this.
LLBufferArray::segment_iterator_t LLBufferArray::beginSegment()
{
+ ASSERT_LLBUFFERARRAY_MUTEX_LOCKED
return mSegments.begin();
}
+//mMutexp should be locked before calling this.
LLBufferArray::segment_iterator_t LLBufferArray::endSegment()
{
+ ASSERT_LLBUFFERARRAY_MUTEX_LOCKED
return mSegments.end();
}
+//mMutexp should be locked before calling this.
LLBufferArray::segment_iterator_t LLBufferArray::constructSegmentAfter(
U8* address,
LLSegment& segment)
{
+ ASSERT_LLBUFFERARRAY_MUTEX_LOCKED
LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
segment_iterator_t rv = mSegments.begin();
segment_iterator_t end = mSegments.end();
@@ -395,8 +460,10 @@ LLBufferArray::segment_iterator_t LLBufferArray::constructSegmentAfter(
return rv;
}
+//mMutexp should be locked before calling this.
LLBufferArray::segment_iterator_t LLBufferArray::getSegment(U8* address)
{
+ ASSERT_LLBUFFERARRAY_MUTEX_LOCKED
segment_iterator_t end = mSegments.end();
if(!address)
{
@@ -414,9 +481,11 @@ LLBufferArray::segment_iterator_t LLBufferArray::getSegment(U8* address)
return end;
}
+//mMutexp should be locked before calling this.
LLBufferArray::const_segment_iterator_t LLBufferArray::getSegment(
U8* address) const
{
+ ASSERT_LLBUFFERARRAY_MUTEX_LOCKED
const_segment_iterator_t end = mSegments.end();
if(!address)
{
@@ -466,6 +535,8 @@ S32 LLBufferArray::countAfter(S32 channel, U8* start) const
S32 count = 0;
S32 offset = 0;
const_segment_iterator_t it;
+
+ LLMutexLock lock(mMutexp) ;
const_segment_iterator_t end = mSegments.end();
if(start)
{
@@ -517,6 +588,8 @@ U8* LLBufferArray::readAfter(
len = 0;
S32 bytes_to_copy = 0;
const_segment_iterator_t it;
+
+ LLMutexLock lock(mMutexp) ;
const_segment_iterator_t end = mSegments.end();
if(start)
{
@@ -568,6 +641,7 @@ U8* LLBufferArray::seek(
U8* start,
S32 delta) const
{
+ ASSERT_LLBUFFERARRAY_MUTEX_LOCKED
LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
const_segment_iterator_t it;
const_segment_iterator_t end = mSegments.end();
@@ -709,9 +783,14 @@ U8* LLBufferArray::seek(
return rv;
}
+//test use only
bool LLBufferArray::takeContents(LLBufferArray& source)
{
LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
+
+ LLMutexLock lock(mMutexp);
+ source.lock();
+
std::copy(
source.mBuffers.begin(),
source.mBuffers.end(),
@@ -723,13 +802,17 @@ bool LLBufferArray::takeContents(LLBufferArray& source)
std::back_insert_iterator<segment_list_t>(mSegments));
source.mSegments.clear();
source.mNextBaseChannel = 0;
+ source.unlock();
+
return true;
}
+//mMutexp should be locked before calling this.
LLBufferArray::segment_iterator_t LLBufferArray::makeSegment(
S32 channel,
S32 len)
{
+ ASSERT_LLBUFFERARRAY_MUTEX_LOCKED
LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
// start at the end of the buffers, because it is the most likely
// to have free space.
@@ -765,8 +848,10 @@ LLBufferArray::segment_iterator_t LLBufferArray::makeSegment(
return send;
}
+//mMutexp should be locked before calling this.
bool LLBufferArray::eraseSegment(const segment_iterator_t& erase_iter)
{
+ ASSERT_LLBUFFERARRAY_MUTEX_LOCKED
LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
// Find out which buffer contains the segment, and if it is found,
@@ -792,13 +877,14 @@ bool LLBufferArray::eraseSegment(const segment_iterator_t& erase_iter)
return rv;
}
-
+//mMutexp should be locked before calling this.
bool LLBufferArray::copyIntoBuffers(
S32 channel,
const U8* src,
S32 len,
std::vector<LLSegment>& segments)
{
+ ASSERT_LLBUFFERARRAY_MUTEX_LOCKED
LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
if(!src || !len) return false;
S32 copied = 0;
diff --git a/indra/llmessage/llbuffer.h b/indra/llmessage/llbuffer.h
index 1c42b6fbc6..ccdb9fa7ee 100644
--- a/indra/llmessage/llbuffer.h
+++ b/indra/llmessage/llbuffer.h
@@ -39,6 +39,7 @@
#include <list>
#include <vector>
+class LLMutex;
/**
* @class LLChannelDescriptors
* @brief A way simple interface to accesss channels inside a buffer
@@ -564,6 +565,29 @@ public:
* @return Returns true on success.
*/
bool eraseSegment(const segment_iterator_t& iter);
+
+ /**
+ * @brief Lock the mutex if it exists
+ * This method locks mMutexp to make accessing LLBufferArray thread-safe
+ */
+ void lock();
+
+ /**
+ * @brief Unlock the mutex if it exists
+ */
+ void unlock();
+
+ /**
+ * @brief Return mMutexp
+ */
+ LLMutex* getMutex();
+
+ /**
+ * @brief Set LLBufferArray to be shared across threads or not
+ * This method is to create mMutexp if is threaded.
+ * @param threaded Indicates this LLBufferArray instance is shared across threads if true.
+ */
+ void setThreaded(bool threaded);
//@}
protected:
@@ -595,6 +619,7 @@ protected:
S32 mNextBaseChannel;
buffer_list_t mBuffers;
segment_list_t mSegments;
+ LLMutex* mMutexp;
};
#endif // LL_LLBUFFER_H
diff --git a/indra/llmessage/llbufferstream.cpp b/indra/llmessage/llbufferstream.cpp
index 6257983c43..8d8ad05ad5 100644
--- a/indra/llmessage/llbufferstream.cpp
+++ b/indra/llmessage/llbufferstream.cpp
@@ -31,6 +31,7 @@
#include "llbuffer.h"
#include "llmemtype.h"
+#include "llthread.h"
static const S32 DEFAULT_OUTPUT_SEGMENT_SIZE = 1024 * 4;
@@ -62,6 +63,7 @@ int LLBufferStreamBuf::underflow()
return EOF;
}
+ LLMutexLock lock(mBuffer->getMutex());
LLBufferArray::segment_iterator_t iter;
LLBufferArray::segment_iterator_t end = mBuffer->endSegment();
U8* last_pos = (U8*)gptr();
@@ -149,6 +151,7 @@ int LLBufferStreamBuf::overflow(int c)
// since we got here, we have a buffer, and we have a character to
// put on it.
LLBufferArray::segment_iterator_t it;
+ LLMutexLock lock(mBuffer->getMutex());
it = mBuffer->makeSegment(mChannels.out(), DEFAULT_OUTPUT_SEGMENT_SIZE);
if(it != mBuffer->endSegment())
{
@@ -210,6 +213,7 @@ int LLBufferStreamBuf::sync()
// *NOTE: I bet we could just --address if address is not NULL.
// Need to think about that.
+ LLMutexLock lock(mBuffer->getMutex());
address = mBuffer->seek(mChannels.out(), address, -1);
if(address)
{
@@ -273,6 +277,8 @@ streampos LLBufferStreamBuf::seekoff(
// NULL is fine
break;
}
+
+ LLMutexLock lock(mBuffer->getMutex());
address = mBuffer->seek(mChannels.in(), base_addr, off);
if(address)
{
@@ -304,6 +310,8 @@ streampos LLBufferStreamBuf::seekoff(
// NULL is fine
break;
}
+
+ LLMutexLock lock(mBuffer->getMutex());
address = mBuffer->seek(mChannels.out(), base_addr, off);
if(address)
{
diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp
index e17380fdf5..3bcaffc275 100644
--- a/indra/llmessage/llcurl.cpp
+++ b/indra/llmessage/llcurl.cpp
@@ -72,10 +72,9 @@
static const U32 EASY_HANDLE_POOL_SIZE = 5;
static const S32 MULTI_PERFORM_CALL_REPEAT = 5;
-static const S32 CURL_REQUEST_TIMEOUT = 30; // seconds
+static const S32 CURL_REQUEST_TIMEOUT = 30; // seconds per operation
static const S32 MAX_ACTIVE_REQUEST_COUNT = 100;
-static
// DEBUG //
S32 gCurlEasyCount = 0;
S32 gCurlMultiCount = 0;
@@ -87,6 +86,11 @@ std::vector<LLMutex*> LLCurl::sSSLMutex;
std::string LLCurl::sCAPath;
std::string LLCurl::sCAFile;
LLCurlThread* LLCurl::sCurlThread = NULL ;
+LLMutex* LLCurl::sHandleMutexp = NULL ;
+S32 LLCurl::sTotalHandles = 0 ;
+bool LLCurl::sNotQuitting = true;
+F32 LLCurl::sCurlRequestTimeOut = 120.f; //seonds
+S32 LLCurl::sMaxHandles = 256; //max number of handles, (multi handles and easy handles combined).
void check_curl_code(CURLcode code)
{
@@ -224,13 +228,15 @@ LLMutex* LLCurl::Easy::sHandleMutexp = NULL ;
//static
CURL* LLCurl::Easy::allocEasyHandle()
{
+ llassert(LLCurl::getCurlThread()) ;
+
CURL* ret = NULL;
LLMutexLock lock(sHandleMutexp) ;
if (sFreeHandles.empty())
{
- ret = curl_easy_init();
+ ret = LLCurl::newEasyHandle();
}
else
{
@@ -250,16 +256,27 @@ CURL* LLCurl::Easy::allocEasyHandle()
//static
void LLCurl::Easy::releaseEasyHandle(CURL* handle)
{
+ static const S32 MAX_NUM_FREE_HANDLES = 32 ;
+
if (!handle)
{
- llerrs << "handle cannot be NULL!" << llendl;
+ return ; //handle allocation failed.
+ //llerrs << "handle cannot be NULL!" << llendl;
}
LLMutexLock lock(sHandleMutexp) ;
if (sActiveHandles.find(handle) != sActiveHandles.end())
{
sActiveHandles.erase(handle);
- sFreeHandles.insert(handle);
+
+ if(sFreeHandles.size() < MAX_NUM_FREE_HANDLES)
+ {
+ sFreeHandles.insert(handle);
+ }
+ else
+ {
+ LLCurl::deleteEasyHandle(handle) ;
+ }
}
else
{
@@ -302,6 +319,14 @@ LLCurl::Easy::~Easy()
--gCurlEasyCount;
curl_slist_free_all(mHeaders);
for_each(mStrings.begin(), mStrings.end(), DeletePointerArray());
+
+ if (mResponder && LLCurl::sNotQuitting) //aborted
+ {
+ std::string reason("Request timeout, aborted.") ;
+ mResponder->completedRaw(408, //HTTP_REQUEST_TIME_OUT, timeout, abort
+ reason, mChannels, mOutput);
+ }
+ mResponder = NULL;
}
void LLCurl::Easy::resetState()
@@ -474,6 +499,7 @@ void LLCurl::Easy::prepRequest(const std::string& url,
LLProxy::getInstance()->applyProxySettings(this);
mOutput.reset(new LLBufferArray);
+ mOutput->setThreaded(true);
setopt(CURLOPT_WRITEFUNCTION, (void*)&curlWriteCallback);
setopt(CURLOPT_WRITEDATA, (void*)this);
@@ -517,8 +543,7 @@ void LLCurl::Easy::prepRequest(const std::string& url,
}
////////////////////////////////////////////////////////////////////////////
-LLMutex* LLCurl::Multi::sMultiInitMutexp = NULL ;
-LLCurl::Multi::Multi()
+LLCurl::Multi::Multi(F32 idle_time_out)
: mQueued(0),
mErrorCount(0),
mState(STATE_READY),
@@ -527,28 +552,47 @@ LLCurl::Multi::Multi()
mDeletionMutexp(NULL),
mEasyMutexp(NULL)
{
- mCurlMultiHandle = initMulti();
+ mCurlMultiHandle = LLCurl::newMultiHandle();
if (!mCurlMultiHandle)
{
llwarns << "curl_multi_init() returned NULL! Easy handles: " << gCurlEasyCount << " Multi handles: " << gCurlMultiCount << llendl;
- mCurlMultiHandle = initMulti();
+ mCurlMultiHandle = LLCurl::newMultiHandle();
}
- llassert_always(mCurlMultiHandle);
-
- if(LLCurl::getCurlThread()->getThreaded())
+ //llassert_always(mCurlMultiHandle);
+
+ if(mCurlMultiHandle)
{
- mMutexp = new LLMutex(NULL) ;
- mDeletionMutexp = new LLMutex(NULL) ;
- mEasyMutexp = new LLMutex(NULL) ;
- }
- LLCurl::getCurlThread()->addMulti(this) ;
+ if(LLCurl::getCurlThread()->getThreaded())
+ {
+ mMutexp = new LLMutex(NULL) ;
+ mDeletionMutexp = new LLMutex(NULL) ;
+ mEasyMutexp = new LLMutex(NULL) ;
+ }
+ LLCurl::getCurlThread()->addMulti(this) ;
- ++gCurlMultiCount;
+ mIdleTimeOut = idle_time_out ;
+ if(mIdleTimeOut < LLCurl::sCurlRequestTimeOut)
+ {
+ mIdleTimeOut = LLCurl::sCurlRequestTimeOut ;
+ }
+
+ ++gCurlMultiCount;
+ }
}
LLCurl::Multi::~Multi()
{
+ cleanup() ;
+}
+
+void LLCurl::Multi::cleanup()
+{
+ if(!mCurlMultiHandle)
+ {
+ return ; //nothing to clean.
+ }
+
// Clean up active
for(easy_active_list_t::iterator iter = mEasyActiveList.begin();
iter != mEasyActiveList.end(); ++iter)
@@ -564,7 +608,8 @@ LLCurl::Multi::~Multi()
for_each(mEasyFreeList.begin(), mEasyFreeList.end(), DeletePointer());
mEasyFreeList.clear();
- check_curl_multi_code(curl_multi_cleanup(mCurlMultiHandle));
+ check_curl_multi_code(LLCurl::deleteMultiHandle(mCurlMultiHandle));
+ mCurlMultiHandle = NULL ;
delete mMutexp ;
mMutexp = NULL ;
@@ -572,15 +617,13 @@ LLCurl::Multi::~Multi()
mDeletionMutexp = NULL ;
delete mEasyMutexp ;
mEasyMutexp = NULL ;
-
+
+ mQueued = 0 ;
+ mState = STATE_COMPLETED;
+
--gCurlMultiCount;
-}
-
-CURLM* LLCurl::Multi::initMulti()
-{
- LLMutexLock lock(sMultiInitMutexp) ;
- return curl_multi_init() ;
+ return ;
}
void LLCurl::Multi::lock()
@@ -604,6 +647,7 @@ void LLCurl::Multi::markDead()
LLMutexLock lock(mDeletionMutexp) ;
mDead = TRUE ;
+ LLCurl::getCurlThread()->setPriority(mHandle, LLQueuedThread::PRIORITY_URGENT) ;
}
void LLCurl::Multi::setState(LLCurl::Multi::ePerformState state)
@@ -630,6 +674,11 @@ bool LLCurl::Multi::isCompleted()
bool LLCurl::Multi::waitToComplete()
{
+ if(!isValid())
+ {
+ return true ;
+ }
+
if(!mMutexp) //not threaded
{
doPerform() ;
@@ -639,7 +688,7 @@ bool LLCurl::Multi::waitToComplete()
bool completed = (STATE_COMPLETED == mState) ;
if(!completed)
{
- LLCurl::getCurlThread()->setPriority(mHandle, LLQueuedThread::PRIORITY_URGENT) ;
+ LLCurl::getCurlThread()->setPriority(mHandle, LLQueuedThread::PRIORITY_HIGH) ;
}
return completed;
@@ -689,7 +738,12 @@ bool LLCurl::Multi::doPerform()
}
mQueued = q;
- setState(STATE_COMPLETED) ;
+ setState(STATE_COMPLETED) ;
+ mIdleTimer.reset() ;
+ }
+ else if(mIdleTimer.getElapsedTimeF32() > mIdleTimeOut) //idle for too long, remove it.
+ {
+ dead = true ;
}
return dead ;
@@ -697,6 +751,11 @@ bool LLCurl::Multi::doPerform()
S32 LLCurl::Multi::process()
{
+ if(!isValid())
+ {
+ return 0 ;
+ }
+
waitToComplete() ;
if (getState() != STATE_COMPLETED)
@@ -849,7 +908,11 @@ bool LLCurlThread::CurlRequest::processRequest()
if(mMulti)
{
completed = mCurlThread->doMultiPerform(mMulti) ;
- setPriority(LLQueuedThread::PRIORITY_LOW) ;
+
+ if(!completed)
+ {
+ setPriority(LLQueuedThread::PRIORITY_LOW) ;
+ }
}
return completed ;
@@ -857,24 +920,26 @@ bool LLCurlThread::CurlRequest::processRequest()
void LLCurlThread::CurlRequest::finishRequest(bool completed)
{
- mCurlThread->deleteMulti(mMulti) ;
+ if(mMulti->isDead())
+ {
+ mCurlThread->deleteMulti(mMulti) ;
+ }
+ else
+ {
+ mCurlThread->cleanupMulti(mMulti) ; //being idle too long, remove the request.
+ }
+
mMulti = NULL ;
}
LLCurlThread::LLCurlThread(bool threaded) :
LLQueuedThread("curlthread", threaded)
{
- if(!LLCurl::Multi::sMultiInitMutexp)
- {
- LLCurl::Multi::sMultiInitMutexp = new LLMutex(NULL) ;
- }
}
//virtual
LLCurlThread::~LLCurlThread()
{
- delete LLCurl::Multi::sMultiInitMutexp ;
- LLCurl::Multi::sMultiInitMutexp = NULL ;
}
S32 LLCurlThread::update(F32 max_time_ms)
@@ -896,7 +961,19 @@ void LLCurlThread::addMulti(LLCurl::Multi* multi)
void LLCurlThread::killMulti(LLCurl::Multi* multi)
{
- multi->markDead() ;
+ if(!multi)
+ {
+ return ;
+ }
+
+ if(multi->isValid())
+ {
+ multi->markDead() ;
+ }
+ else
+ {
+ deleteMulti(multi) ;
+ }
}
//private
@@ -910,6 +987,13 @@ void LLCurlThread::deleteMulti(LLCurl::Multi* multi)
{
delete multi ;
}
+
+//private
+void LLCurlThread::cleanupMulti(LLCurl::Multi* multi)
+{
+ multi->cleanup() ;
+}
+
//------------------------------------------------------------
//static
@@ -942,7 +1026,14 @@ LLCurlRequest::~LLCurlRequest()
void LLCurlRequest::addMulti()
{
LLCurl::Multi* multi = new LLCurl::Multi();
-
+ if(!multi->isValid())
+ {
+ LLCurl::getCurlThread()->killMulti(multi) ;
+ mActiveMulti = NULL ;
+ mActiveRequestCount = 0 ;
+ return;
+ }
+
mMultiSet.insert(multi);
mActiveMulti = multi;
mActiveRequestCount = 0;
@@ -956,7 +1047,12 @@ LLCurl::Easy* LLCurlRequest::allocEasy()
{
addMulti();
}
- llassert_always(mActiveMulti);
+ if(!mActiveMulti)
+ {
+ return NULL ;
+ }
+
+ //llassert_always(mActiveMulti);
++mActiveRequestCount;
LLCurl::Easy* easy = mActiveMulti->allocEasy();
return easy;
@@ -1066,6 +1162,19 @@ S32 LLCurlRequest::process()
{
curlmulti_set_t::iterator curiter = iter++;
LLCurl::Multi* multi = *curiter;
+
+ if(!multi->isValid())
+ {
+ if(multi == mActiveMulti)
+ {
+ mActiveMulti = NULL ;
+ mActiveRequestCount = 0 ;
+ }
+ mMultiSet.erase(curiter) ;
+ LLCurl::getCurlThread()->killMulti(multi) ;
+ continue ;
+ }
+
S32 tres = multi->process();
res += tres;
if (multi != mActiveMulti && tres == 0 && multi->mQueued == 0)
@@ -1086,6 +1195,19 @@ S32 LLCurlRequest::getQueued()
{
curlmulti_set_t::iterator curiter = iter++;
LLCurl::Multi* multi = *curiter;
+
+ if(!multi->isValid())
+ {
+ if(multi == mActiveMulti)
+ {
+ mActiveMulti = NULL ;
+ mActiveRequestCount = 0 ;
+ }
+ LLCurl::getCurlThread()->killMulti(multi);
+ mMultiSet.erase(curiter) ;
+ continue ;
+ }
+
queued += multi->mQueued;
if (multi->getState() != LLCurl::Multi::STATE_READY)
{
@@ -1105,13 +1227,22 @@ LLCurlEasyRequest::LLCurlEasyRequest()
{
mMulti = new LLCurl::Multi();
- mEasy = mMulti->allocEasy();
- if (mEasy)
+ if(mMulti->isValid())
{
- mEasy->setErrorBuffer();
- mEasy->setCA();
- // Set proxy settings if configured to do so.
- LLProxy::getInstance()->applyProxySettings(mEasy);
+ mEasy = mMulti->allocEasy();
+ if (mEasy)
+ {
+ mEasy->setErrorBuffer();
+ mEasy->setCA();
+ // Set proxy settings if configured to do so.
+ LLProxy::getInstance()->applyProxySettings(mEasy);
+ }
+ }
+ else
+ {
+ LLCurl::getCurlThread()->killMulti(mMulti) ;
+ mEasy = NULL ;
+ mMulti = NULL ;
}
}
@@ -1122,7 +1253,7 @@ LLCurlEasyRequest::~LLCurlEasyRequest()
void LLCurlEasyRequest::setopt(CURLoption option, S32 value)
{
- if (mEasy)
+ if (isValid() && mEasy)
{
mEasy->setopt(option, value);
}
@@ -1130,7 +1261,7 @@ void LLCurlEasyRequest::setopt(CURLoption option, S32 value)
void LLCurlEasyRequest::setoptString(CURLoption option, const std::string& value)
{
- if (mEasy)
+ if (isValid() && mEasy)
{
mEasy->setoptString(option, value);
}
@@ -1138,7 +1269,7 @@ void LLCurlEasyRequest::setoptString(CURLoption option, const std::string& value
void LLCurlEasyRequest::setPost(char* postdata, S32 size)
{
- if (mEasy)
+ if (isValid() && mEasy)
{
mEasy->setopt(CURLOPT_POST, 1);
mEasy->setopt(CURLOPT_POSTFIELDS, postdata);
@@ -1148,7 +1279,7 @@ void LLCurlEasyRequest::setPost(char* postdata, S32 size)
void LLCurlEasyRequest::setHeaderCallback(curl_header_callback callback, void* userdata)
{
- if (mEasy)
+ if (isValid() && mEasy)
{
mEasy->setopt(CURLOPT_HEADERFUNCTION, (void*)callback);
mEasy->setopt(CURLOPT_HEADERDATA, userdata); // aka CURLOPT_WRITEHEADER
@@ -1157,7 +1288,7 @@ void LLCurlEasyRequest::setHeaderCallback(curl_header_callback callback, void* u
void LLCurlEasyRequest::setWriteCallback(curl_write_callback callback, void* userdata)
{
- if (mEasy)
+ if (isValid() && mEasy)
{
mEasy->setopt(CURLOPT_WRITEFUNCTION, (void*)callback);
mEasy->setopt(CURLOPT_WRITEDATA, userdata);
@@ -1166,7 +1297,7 @@ void LLCurlEasyRequest::setWriteCallback(curl_write_callback callback, void* use
void LLCurlEasyRequest::setReadCallback(curl_read_callback callback, void* userdata)
{
- if (mEasy)
+ if (isValid() && mEasy)
{
mEasy->setopt(CURLOPT_READFUNCTION, (void*)callback);
mEasy->setopt(CURLOPT_READDATA, userdata);
@@ -1175,7 +1306,7 @@ void LLCurlEasyRequest::setReadCallback(curl_read_callback callback, void* userd
void LLCurlEasyRequest::setSSLCtxCallback(curl_ssl_ctx_callback callback, void* userdata)
{
- if (mEasy)
+ if (isValid() && mEasy)
{
mEasy->setopt(CURLOPT_SSL_CTX_FUNCTION, (void*)callback);
mEasy->setopt(CURLOPT_SSL_CTX_DATA, userdata);
@@ -1184,7 +1315,7 @@ void LLCurlEasyRequest::setSSLCtxCallback(curl_ssl_ctx_callback callback, void*
void LLCurlEasyRequest::slist_append(const char* str)
{
- if (mEasy)
+ if (isValid() && mEasy)
{
mEasy->slist_append(str);
}
@@ -1195,7 +1326,7 @@ void LLCurlEasyRequest::sendRequest(const std::string& url)
llassert_always(!mRequestSent);
mRequestSent = true;
lldebugs << url << llendl;
- if (mEasy)
+ if (isValid() && mEasy)
{
mEasy->setHeaders();
mEasy->setoptString(CURLOPT_URL, url);
@@ -1207,7 +1338,7 @@ void LLCurlEasyRequest::requestComplete()
{
llassert_always(mRequestSent);
mRequestSent = false;
- if (mEasy)
+ if (isValid() && mEasy)
{
mMulti->removeEasy(mEasy);
}
@@ -1216,6 +1347,10 @@ void LLCurlEasyRequest::requestComplete()
// Usage: Call getRestult until it returns false (no more messages)
bool LLCurlEasyRequest::getResult(CURLcode* result, LLCurl::TransferInfo* info)
{
+ if(!isValid())
+ {
+ return false ;
+ }
if (!mMulti->isCompleted())
{ //we're busy, try again later
return false;
@@ -1280,7 +1415,7 @@ CURLMsg* LLCurlEasyRequest::info_read(S32* q, LLCurl::TransferInfo* info)
std::string LLCurlEasyRequest::getErrorString()
{
- return mEasy ? std::string(mEasy->getErrorBuffer()) : std::string();
+ return isValid() && mEasy ? std::string(mEasy->getErrorBuffer()) : std::string();
}
////////////////////////////////////////////////////////////////////////////
@@ -1306,8 +1441,11 @@ unsigned long LLCurl::ssl_thread_id(void)
}
#endif
-void LLCurl::initClass(bool multi_threaded)
+void LLCurl::initClass(F32 curl_reuest_timeout, S32 max_number_handles, bool multi_threaded)
{
+ sCurlRequestTimeOut = curl_reuest_timeout ; //seconds
+ sMaxHandles = max_number_handles ; //max number of handles, (multi handles and easy handles combined).
+
// Do not change this "unless you are familiar with and mean to control
// internal operations of libcurl"
// - http://curl.haxx.se/libcurl/c/curl_global_init.html
@@ -1328,12 +1466,15 @@ void LLCurl::initClass(bool multi_threaded)
sCurlThread = new LLCurlThread(multi_threaded) ;
if(multi_threaded)
{
+ sHandleMutexp = new LLMutex(NULL) ;
Easy::sHandleMutexp = new LLMutex(NULL) ;
}
}
void LLCurl::cleanupClass()
{
+ sNotQuitting = false; //set quitting
+
//shut down curl thread
while(1)
{
@@ -1354,7 +1495,7 @@ void LLCurl::cleanupClass()
for (std::set<CURL*>::iterator iter = Easy::sFreeHandles.begin(); iter != Easy::sFreeHandles.end(); ++iter)
{
CURL* curl = *iter;
- curl_easy_cleanup(curl);
+ LLCurl::deleteEasyHandle(curl);
}
Easy::sFreeHandles.clear();
@@ -1362,9 +1503,77 @@ void LLCurl::cleanupClass()
delete Easy::sHandleMutexp ;
Easy::sHandleMutexp = NULL ;
+ delete sHandleMutexp ;
+ sHandleMutexp = NULL ;
+
llassert(Easy::sActiveHandles.empty());
}
+//static
+CURLM* LLCurl::newMultiHandle()
+{
+ LLMutexLock lock(sHandleMutexp) ;
+
+ if(sTotalHandles + 1 > sMaxHandles)
+ {
+ llwarns << "no more handles available." << llendl ;
+ return NULL ; //failed
+ }
+ sTotalHandles++;
+
+ CURLM* ret = curl_multi_init() ;
+ if(!ret)
+ {
+ llwarns << "curl_multi_init failed." << llendl ;
+ }
+
+ return ret ;
+}
+
+//static
+CURLMcode LLCurl::deleteMultiHandle(CURLM* handle)
+{
+ if(handle)
+ {
+ LLMutexLock lock(sHandleMutexp) ;
+ sTotalHandles-- ;
+ return curl_multi_cleanup(handle) ;
+ }
+ return CURLM_OK ;
+}
+
+//static
+CURL* LLCurl::newEasyHandle()
+{
+ LLMutexLock lock(sHandleMutexp) ;
+
+ if(sTotalHandles + 1 > sMaxHandles)
+ {
+ llwarns << "no more handles available." << llendl ;
+ return NULL ; //failed
+ }
+ sTotalHandles++;
+
+ CURL* ret = curl_easy_init() ;
+ if(!ret)
+ {
+ llwarns << "curl_easy_init failed." << llendl ;
+ }
+
+ return ret ;
+}
+
+//static
+void LLCurl::deleteEasyHandle(CURL* handle)
+{
+ if(handle)
+ {
+ LLMutexLock lock(sHandleMutexp) ;
+ curl_easy_cleanup(handle) ;
+ sTotalHandles-- ;
+ }
+}
+
const unsigned int LLCurl::MAX_REDIRECTS = 5;
// Provide access to LLCurl free functions outside of llcurl.cpp without polluting the global namespace.
diff --git a/indra/llmessage/llcurl.h b/indra/llmessage/llcurl.h
index 9c2c215c7a..fd664c0fa1 100644
--- a/indra/llmessage/llcurl.h
+++ b/indra/llmessage/llcurl.h
@@ -43,6 +43,7 @@
#include "llsd.h"
#include "llthread.h"
#include "llqueuedthread.h"
+#include "llframetimer.h"
class LLMutex;
class LLCurlThread;
@@ -162,7 +163,7 @@ public:
/**
* @ brief Initialize LLCurl class
*/
- static void initClass(bool multi_threaded = false);
+ static void initClass(F32 curl_reuest_timeout = 120.f, S32 max_number_handles = 256, bool multi_threaded = false);
/**
* @ brief Cleanup LLCurl class
@@ -182,11 +183,24 @@ public:
static unsigned long ssl_thread_id(void);
static LLCurlThread* getCurlThread() { return sCurlThread ;}
+
+ static CURLM* newMultiHandle() ;
+ static CURLMcode deleteMultiHandle(CURLM* handle) ;
+ static CURL* newEasyHandle() ;
+ static void deleteEasyHandle(CURL* handle) ;
+
private:
static std::string sCAPath;
static std::string sCAFile;
static const unsigned int MAX_REDIRECTS;
static LLCurlThread* sCurlThread;
+
+ static LLMutex* sHandleMutexp ;
+ static S32 sTotalHandles ;
+ static S32 sMaxHandles;
+public:
+ static bool sNotQuitting;
+ static F32 sCurlRequestTimeOut;
};
class LLCurl::Easy
@@ -277,7 +291,7 @@ public:
STATE_COMPLETED=2
} ePerformState;
- Multi();
+ Multi(F32 idle_time_out = 0.f);
LLCurl::Easy* allocEasy();
bool addEasy(LLCurl::Easy* easy);
@@ -288,7 +302,10 @@ public:
void setState(ePerformState state) ;
ePerformState getState() ;
+
bool isCompleted() ;
+ bool isValid() {return mCurlMultiHandle != NULL ;}
+ bool isDead() {return mDead;}
bool waitToComplete() ;
@@ -299,9 +316,9 @@ public:
S32 mQueued;
S32 mErrorCount;
- static CURLM* initMulti() ;
private:
void easyFree(LLCurl::Easy*);
+ void cleanup() ;
CURLM* mCurlMultiHandle;
@@ -319,8 +336,8 @@ private:
LLMutex* mMutexp ;
LLMutex* mDeletionMutexp ;
LLMutex* mEasyMutexp ;
-
- static LLMutex* sMultiInitMutexp ;
+ LLFrameTimer mIdleTimer ;
+ F32 mIdleTimeOut;
};
class LLCurlThread : public LLQueuedThread
@@ -357,6 +374,7 @@ public:
private:
bool doMultiPerform(LLCurl::Multi* multi) ;
void deleteMulti(LLCurl::Multi* multi) ;
+ void cleanupMulti(LLCurl::Multi* multi) ;
} ;
namespace boost
@@ -414,6 +432,7 @@ public:
std::string getErrorString();
bool isCompleted() {return mMulti->isCompleted() ;}
bool wait() { return mMulti->waitToComplete(); }
+ bool isValid() {return mMulti && mMulti->isValid(); }
LLCurl::Easy* getEasy() const { return mEasy; }
diff --git a/indra/llmessage/llhttpassetstorage.cpp b/indra/llmessage/llhttpassetstorage.cpp
index 2bca517e97..612d765969 100644
--- a/indra/llmessage/llhttpassetstorage.cpp
+++ b/indra/llmessage/llhttpassetstorage.cpp
@@ -232,7 +232,8 @@ LLSD LLHTTPAssetRequest::getFullDetails() const
void LLHTTPAssetRequest::setupCurlHandle()
{
// *NOTE: Similar code exists in mapserver/llcurlutil.cpp JC
- mCurlHandle = curl_easy_init();
+ mCurlHandle = LLCurl::newEasyHandle();
+ llassert_always(mCurlHandle != NULL) ;
// Apply proxy settings if configured to do so
LLProxy::getInstance()->applyProxySettings(mCurlHandle);
@@ -278,7 +279,7 @@ void LLHTTPAssetRequest::setupCurlHandle()
void LLHTTPAssetRequest::cleanupCurlHandle()
{
- curl_easy_cleanup(mCurlHandle);
+ LLCurl::deleteEasyHandle(mCurlHandle);
if (mAssetStoragep)
{
// Terminating a request. Thus upload or download is no longer pending.
@@ -429,12 +430,13 @@ void LLHTTPAssetStorage::_init(const std::string& web_host, const std::string& l
// curl_global_init moved to LLCurl::initClass()
- mCurlMultiHandle = curl_multi_init();
+ mCurlMultiHandle = LLCurl::newMultiHandle() ;
+ llassert_always(mCurlMultiHandle != NULL) ;
}
LLHTTPAssetStorage::~LLHTTPAssetStorage()
{
- curl_multi_cleanup(mCurlMultiHandle);
+ LLCurl::deleteMultiHandle(mCurlMultiHandle);
mCurlMultiHandle = NULL;
// curl_global_cleanup moved to LLCurl::initClass()
diff --git a/indra/llmessage/llhttpclient.cpp b/indra/llmessage/llhttpclient.cpp
index dd4e3a6300..231cb7ca8f 100644
--- a/indra/llmessage/llhttpclient.cpp
+++ b/indra/llmessage/llhttpclient.cpp
@@ -228,6 +228,12 @@ static void request(
LLPumpIO::chain_t chain;
LLURLRequest* req = new LLURLRequest(method, url);
+ if(!req->isValid())//failed
+ {
+ delete req ;
+ return ;
+ }
+
req->setSSLVerifyCallback(LLHTTPClient::getCertVerifyCallback(), (void *)req);
@@ -423,7 +429,9 @@ static LLSD blocking_request(
{
lldebugs << "blockingRequest of " << url << llendl;
char curl_error_buffer[CURL_ERROR_SIZE] = "\0";
- CURL* curlp = curl_easy_init();
+ CURL* curlp = LLCurl::newEasyHandle();
+ llassert_always(curlp != NULL) ;
+
LLHTTPBuffer http_buffer;
std::string body_str;
@@ -517,7 +525,7 @@ static LLSD blocking_request(
}
// * Cleanup
- curl_easy_cleanup(curlp);
+ LLCurl::deleteEasyHandle(curlp);
return response;
}
diff --git a/indra/llmessage/lliohttpserver.cpp b/indra/llmessage/lliohttpserver.cpp
index 73e8a69085..987f386aa3 100644
--- a/indra/llmessage/lliohttpserver.cpp
+++ b/indra/llmessage/lliohttpserver.cpp
@@ -818,6 +818,8 @@ LLIOPipe::EStatus LLHTTPResponder::process_impl(
// Copy everything after mLast read to the out.
LLBufferArray::segment_iterator_t seg_iter;
+
+ buffer->lock();
seg_iter = buffer->splitAfter(mLastRead);
if(seg_iter != buffer->endSegment())
{
@@ -838,7 +840,7 @@ LLIOPipe::EStatus LLHTTPResponder::process_impl(
}
#endif
}
-
+ buffer->unlock();
//
// *FIX: get rid of extra bytes off the end
//
diff --git a/indra/llmessage/lliopipe.cpp b/indra/llmessage/lliopipe.cpp
index 6e4eec74a6..8f827f7a30 100644
--- a/indra/llmessage/lliopipe.cpp
+++ b/indra/llmessage/lliopipe.cpp
@@ -75,6 +75,12 @@ LLIOPipe::~LLIOPipe()
//lldebugs << "destroying LLIOPipe" << llendl;
}
+//virtual
+bool LLIOPipe::isValid()
+{
+ return true ;
+}
+
// static
std::string LLIOPipe::lookupStatusString(EStatus status)
{
diff --git a/indra/llmessage/lliopipe.h b/indra/llmessage/lliopipe.h
index 8e656b6da1..cbd17b5a3d 100644
--- a/indra/llmessage/lliopipe.h
+++ b/indra/llmessage/lliopipe.h
@@ -231,6 +231,8 @@ public:
*/
virtual ~LLIOPipe();
+ virtual bool isValid() ;
+
protected:
/**
* @brief Base Constructor.
diff --git a/indra/llmessage/lliosocket.cpp b/indra/llmessage/lliosocket.cpp
index 54ceab3422..d5b4d45821 100644
--- a/indra/llmessage/lliosocket.cpp
+++ b/indra/llmessage/lliosocket.cpp
@@ -445,6 +445,7 @@ LLIOPipe::EStatus LLIOSocketWriter::process_impl(
// efficient - not only because writev() is better, but also
// because we won't have to do as much work to find the start
// address.
+ buffer->lock();
LLBufferArray::segment_iterator_t it;
LLBufferArray::segment_iterator_t end = buffer->endSegment();
LLSegment segment;
@@ -524,6 +525,8 @@ LLIOPipe::EStatus LLIOSocketWriter::process_impl(
}
}
+ buffer->unlock();
+
PUMP_DEBUG;
if(done && eos)
{
diff --git a/indra/llmessage/llpumpio.cpp b/indra/llmessage/llpumpio.cpp
index a8d2a0a224..f3ef4f2684 100644
--- a/indra/llmessage/llpumpio.cpp
+++ b/indra/llmessage/llpumpio.cpp
@@ -195,7 +195,7 @@ bool LLPumpIO::prime(apr_pool_t* pool)
return ((pool == NULL) ? false : true);
}
-bool LLPumpIO::addChain(const chain_t& chain, F32 timeout)
+bool LLPumpIO::addChain(const chain_t& chain, F32 timeout, bool has_curl_request)
{
LLMemType m1(LLMemType::MTYPE_IO_PUMP);
if(chain.empty()) return false;
@@ -204,8 +204,10 @@ bool LLPumpIO::addChain(const chain_t& chain, F32 timeout)
LLScopedLock lock(mChainsMutex);
#endif
LLChainInfo info;
+ info.mHasCurlRequest = has_curl_request;
info.setTimeoutSeconds(timeout);
info.mData = LLIOPipe::buffer_ptr_t(new LLBufferArray);
+ info.mData->setThreaded(has_curl_request);
LLLinkInfo link;
#if LL_DEBUG_PIPE_TYPE_IN_PUMP
lldebugs << "LLPumpIO::addChain() " << chain[0] << " '"
@@ -440,6 +442,15 @@ void LLPumpIO::pump()
static LLFastTimer::DeclareTimer FTM_PUMP_IO("Pump IO");
+LLPumpIO::current_chain_t LLPumpIO::removeRunningChain(LLPumpIO::current_chain_t& run_chain)
+{
+ std::for_each(
+ (*run_chain).mDescriptors.begin(),
+ (*run_chain).mDescriptors.end(),
+ ll_delete_apr_pollset_fd_client_data());
+ return mRunningChains.erase(run_chain);
+}
+
//timeout is in microseconds
void LLPumpIO::pump(const S32& poll_timeout)
{
@@ -585,10 +596,16 @@ void LLPumpIO::pump(const S32& poll_timeout)
// << (*run_chain).mChainLinks[0].mPipe
// << " because we reached the end." << llendl;
#endif
- run_chain = mRunningChains.erase(run_chain);
+ run_chain = removeRunningChain(run_chain);
continue;
}
}
+ else if(isChainExpired(*run_chain))
+ {
+ run_chain = removeRunningChain(run_chain);
+ continue;
+ }
+
PUMP_DEBUG;
if((*run_chain).mLock)
{
@@ -696,11 +713,7 @@ void LLPumpIO::pump(const S32& poll_timeout)
PUMP_DEBUG;
// This chain is done. Clean up any allocated memory and
// erase the chain info.
- std::for_each(
- (*run_chain).mDescriptors.begin(),
- (*run_chain).mDescriptors.end(),
- ll_delete_apr_pollset_fd_client_data());
- run_chain = mRunningChains.erase(run_chain);
+ run_chain = removeRunningChain(run_chain);
// *NOTE: may not always need to rebuild the pollset.
mRebuildPollset = true;
@@ -1095,6 +1108,24 @@ void LLPumpIO::processChain(LLChainInfo& chain)
PUMP_DEBUG;
}
+bool LLPumpIO::isChainExpired(LLChainInfo& chain)
+{
+ if(!chain.mHasCurlRequest)
+ {
+ return false ;
+ }
+
+ for(links_t::iterator iter = chain.mChainLinks.begin(); iter != chain.mChainLinks.end(); ++iter)
+ {
+ if(!(*iter).mPipe->isValid())
+ {
+ return true ;
+ }
+ }
+
+ return false ;
+}
+
bool LLPumpIO::handleChainError(
LLChainInfo& chain,
LLIOPipe::EStatus error)
@@ -1136,6 +1167,9 @@ bool LLPumpIO::handleChainError(
#endif
keep_going = false;
break;
+ case LLIOPipe::STATUS_EXPIRED:
+ keep_going = false;
+ break ;
default:
if(LLIOPipe::isSuccess(error))
{
@@ -1157,7 +1191,8 @@ bool LLPumpIO::handleChainError(
LLPumpIO::LLChainInfo::LLChainInfo() :
mInit(false),
mLock(0),
- mEOS(false)
+ mEOS(false),
+ mHasCurlRequest(false)
{
LLMemType m1(LLMemType::MTYPE_IO_PUMP);
mTimer.setTimerExpirySec(DEFAULT_CHAIN_EXPIRY_SECS);
diff --git a/indra/llmessage/llpumpio.h b/indra/llmessage/llpumpio.h
index 9303c9d7fc..d2c5d37571 100644
--- a/indra/llmessage/llpumpio.h
+++ b/indra/llmessage/llpumpio.h
@@ -111,9 +111,10 @@ public:
* @param chain The pipes for the chain
* @param timeout The number of seconds in the future to
* expire. Pass in 0.0f to never expire.
+ * @param has_curl_request The chain contains LLURLRequest if true.
* @return Returns true if anything was added to the pump.
*/
- bool addChain(const chain_t& chain, F32 timeout);
+ bool addChain(const chain_t& chain, F32 timeout, bool has_curl_request = false);
/**
* @brief Struct to associate a pipe with it's buffer io indexes.
@@ -356,12 +357,13 @@ protected:
// basic member data
bool mInit;
+ bool mEOS;
+ bool mHasCurlRequest;
S32 mLock;
LLFrameTimer mTimer;
links_t::iterator mHead;
links_t mChainLinks;
- LLIOPipe::buffer_ptr_t mData;
- bool mEOS;
+ LLIOPipe::buffer_ptr_t mData;
LLSD mContext;
// tracking inside the pump
@@ -402,7 +404,7 @@ protected:
protected:
void initialize(apr_pool_t* pool);
void cleanup();
-
+ current_chain_t removeRunningChain(current_chain_t& chain) ;
/**
* @brief Given the internal state of the chains, rebuild the pollset
* @see setConditional()
@@ -429,6 +431,9 @@ protected:
*/
bool handleChainError(LLChainInfo& chain, LLIOPipe::EStatus error);
+ //if the chain is expired, remove it
+ bool isChainExpired(LLChainInfo& chain) ;
+
public:
/**
* @brief Return number of running chains.
diff --git a/indra/llmessage/llsdrpcclient.h b/indra/llmessage/llsdrpcclient.h
index 9fb49a5c33..0cecf4f688 100644
--- a/indra/llmessage/llsdrpcclient.h
+++ b/indra/llmessage/llsdrpcclient.h
@@ -240,9 +240,16 @@ public:
virtual bool build(LLPumpIO::chain_t& chain, LLSD context) const
{
lldebugs << "LLSDRPCClientFactory::build" << llendl;
- LLIOPipe::ptr_t service(new Client);
- chain.push_back(service);
LLURLRequest* http(new LLURLRequest(LLURLRequest::HTTP_POST));
+ if(!http->isValid())
+ {
+ llwarns << "Creating LLURLRequest failed." << llendl ;
+ delete http;
+ return false;
+ }
+
+ LLIOPipe::ptr_t service(new Client);
+ chain.push_back(service);
LLIOPipe::ptr_t http_pipe(http);
http->addHeader("Content-Type: text/llsd");
if(mURL.empty())
@@ -283,9 +290,16 @@ public:
virtual bool build(LLPumpIO::chain_t& chain, LLSD context) const
{
lldebugs << "LLXMLSDRPCClientFactory::build" << llendl;
- LLIOPipe::ptr_t service(new Client);
- chain.push_back(service);
+
LLURLRequest* http(new LLURLRequest(LLURLRequest::HTTP_POST));
+ if(!http->isValid())
+ {
+ llwarns << "Creating LLURLRequest failed." << llendl ;
+ delete http;
+ return false ;
+ }
+ LLIOPipe::ptr_t service(new Client);
+ chain.push_back(service);
LLIOPipe::ptr_t http_pipe(http);
http->addHeader("Content-Type: text/xml");
if(mURL.empty())
diff --git a/indra/llmessage/llurlrequest.cpp b/indra/llmessage/llurlrequest.cpp
index 261e57e79e..a16f5c7bf0 100644
--- a/indra/llmessage/llurlrequest.cpp
+++ b/indra/llmessage/llurlrequest.cpp
@@ -83,6 +83,12 @@ LLURLRequestDetail::LLURLRequestDetail() :
{
LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);
mCurlRequest = new LLCurlEasyRequest();
+
+ if(!mCurlRequest->isValid()) //failed.
+ {
+ delete mCurlRequest ;
+ mCurlRequest = NULL ;
+ }
}
LLURLRequestDetail::~LLURLRequestDetail()
@@ -250,12 +256,24 @@ void LLURLRequest::allowCookies()
mDetail->mCurlRequest->setoptString(CURLOPT_COOKIEFILE, "");
}
+//virtual
+bool LLURLRequest::isValid()
+{
+ return mDetail->mCurlRequest && mDetail->mCurlRequest->isValid();
+}
+
// virtual
LLIOPipe::EStatus LLURLRequest::handleError(
LLIOPipe::EStatus status,
LLPumpIO* pump)
{
LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);
+
+ if(!isValid())
+ {
+ return STATUS_EXPIRED ;
+ }
+
if(mCompletionCallback && pump)
{
LLURLRequestComplete* complete = NULL;
@@ -441,6 +459,12 @@ void LLURLRequest::initialize()
LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);
mState = STATE_INITIALIZED;
mDetail = new LLURLRequestDetail;
+
+ if(!isValid())
+ {
+ return ;
+ }
+
mDetail->mCurlRequest->setopt(CURLOPT_NOSIGNAL, 1);
mDetail->mCurlRequest->setWriteCallback(&downCallback, (void*)this);
mDetail->mCurlRequest->setReadCallback(&upCallback, (void*)this);
diff --git a/indra/llmessage/llurlrequest.h b/indra/llmessage/llurlrequest.h
index ec5c2c1941..44d358d906 100644
--- a/indra/llmessage/llurlrequest.h
+++ b/indra/llmessage/llurlrequest.h
@@ -188,6 +188,8 @@ public:
*/
void allowCookies();
+ /*virtual*/ bool isValid() ;
+
public:
/**
* @brief Give this pipe a chance to handle a generated error
diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp
index cd827f5091..03a9884c2b 100644
--- a/indra/llrender/llrender.cpp
+++ b/indra/llrender/llrender.cpp
@@ -1434,6 +1434,8 @@ void LLRender::loadIdentity()
flush();
{
+ llassert_always(mMatrixMode < NUM_MATRIX_MODES) ;
+
mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].make_identity();
mMatHash[mMatrixMode]++;
}
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 9a15b65f83..2e4c537942 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -162,6 +162,7 @@ set(viewer_SOURCE_FILES
llfavoritesbar.cpp
llfeaturemanager.cpp
llfilepicker.cpp
+ llfilteredpathfindinglinksets.cpp
llfilteredwearablelist.cpp
llfirstuse.cpp
llflexibleobject.cpp
@@ -415,6 +416,7 @@ set(viewer_SOURCE_FILES
llparcelselection.cpp
llparticipantlist.cpp
llpatchvertexarray.cpp
+ llpathfindinglinkset.cpp
llphysicsmotion.cpp
llphysicsshapebuilderutil.cpp
llplacesinventorybridge.cpp
@@ -721,6 +723,7 @@ set(viewer_HEADER_FILES
llfavoritesbar.h
llfeaturemanager.h
llfilepicker.h
+ llfilteredpathfindinglinksets.h
llfilteredwearablelist.h
llfirstuse.h
llflexibleobject.h
@@ -963,6 +966,7 @@ set(viewer_HEADER_FILES
llparcelselection.h
llparticipantlist.h
llpatchvertexarray.h
+ llpathfindinglinkset.h
llphysicsmotion.h
llphysicsshapebuilderutil.h
llplacesinventorybridge.h
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 28ba9fd704..ea00a0204d 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -1828,6 +1828,28 @@
<key>Value</key>
<integer>0</integer>
</map>
+ <key>CurlMaximumNumberOfHandles</key>
+ <map>
+ <key>Comment</key>
+ <string>Maximum number of handles curl can use (requires restart)</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>256</integer>
+ </map>
+ <key>CurlRequestTimeOut</key>
+ <map>
+ <key>Comment</key>
+ <string>Max idle time of a curl request before killed (requires restart)</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>120.0</real>
+ </map>
<key>CurlUseMultipleThreads</key>
<map>
<key>Comment</key>
diff --git a/indra/newview/llagentwearablesfetch.cpp b/indra/newview/llagentwearablesfetch.cpp
index 1edc96e165..4097ff707c 100644
--- a/indra/newview/llagentwearablesfetch.cpp
+++ b/indra/newview/llagentwearablesfetch.cpp
@@ -111,6 +111,12 @@ void LLInitialWearablesFetch::add(InitialWearableData &data)
void LLInitialWearablesFetch::processContents()
{
+ if(!gAgentAvatarp) //no need to process wearables if the agent avatar is deleted.
+ {
+ delete this;
+ return ;
+ }
+
// Fetch the wearable items from the Current Outfit Folder
LLInventoryModel::cat_array_t cat_array;
LLInventoryModel::item_array_t wearable_array;
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 172eb834b4..261553599b 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -723,7 +723,9 @@ bool LLAppViewer::init()
// *NOTE:Mani - LLCurl::initClass is not thread safe.
// Called before threads are created.
- LLCurl::initClass(gSavedSettings.getBOOL("CurlUseMultipleThreads"));
+ LLCurl::initClass(gSavedSettings.getF32("CurlRequestTimeOut"),
+ gSavedSettings.getS32("CurlMaximumNumberOfHandles"),
+ gSavedSettings.getBOOL("CurlUseMultipleThreads"));
LL_INFOS("InitInfo") << "LLCurl initialized." << LL_ENDL ;
LLMachineID::init();
diff --git a/indra/newview/llfilteredpathfindinglinksets.cpp b/indra/newview/llfilteredpathfindinglinksets.cpp
new file mode 100644
index 0000000000..aaff2bcc68
--- /dev/null
+++ b/indra/newview/llfilteredpathfindinglinksets.cpp
@@ -0,0 +1,313 @@
+/**
+ * @file llfilteredpathfindinglinksets.h
+ * @author William Todd Stinson
+ * @brief Class to implement the filtering of a set of pathfinding linksets
+ *
+ * $LicenseInfo:firstyear=2002&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$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include <string>
+#include <map>
+
+#include "llsd.h"
+#include "lluuid.h"
+#include "llpathfindinglinkset.h"
+#include "llfilteredpathfindinglinksets.h"
+
+//---------------------------------------------------------------------------
+// FilterString
+//---------------------------------------------------------------------------
+
+FilterString::FilterString()
+ : mFilter(),
+ mUpperFilter()
+{
+}
+
+FilterString::FilterString(const std::string& pFilter)
+ : mFilter(pFilter),
+ mUpperFilter()
+{
+ LLStringUtil::trim(mFilter);
+ mUpperFilter = mFilter;
+ if (!mUpperFilter.empty())
+ {
+ LLStringUtil::toUpper(mUpperFilter);
+ }
+}
+
+FilterString::~FilterString()
+{
+}
+
+const std::string& FilterString::get() const
+{
+ return mFilter;
+}
+
+bool FilterString::set(const std::string& pFilter)
+{
+ std::string newFilter(pFilter);
+ LLStringUtil::trim(newFilter);
+ bool didFilterChange = (mFilter.compare(newFilter) != 0);
+ if (didFilterChange)
+ {
+ mFilter = newFilter;
+ mUpperFilter = newFilter;
+ LLStringUtil::toUpper(mUpperFilter);
+ }
+
+ return didFilterChange;
+}
+
+void FilterString::clear()
+{
+ mFilter.clear();
+ mUpperFilter.clear();
+}
+
+bool FilterString::isActive() const
+{
+ return !mFilter.empty();
+}
+
+bool FilterString::doesMatch(const std::string& pTestString) const
+{
+ bool doesMatch = true;
+
+ if (isActive())
+ {
+ std::string upperTestString(pTestString);
+ LLStringUtil::toUpper(upperTestString);
+ doesMatch = (upperTestString.find(mUpperFilter) != std::string::npos);
+ }
+
+ return doesMatch;
+}
+
+//---------------------------------------------------------------------------
+// LLFilteredPathfindingLinksets
+//---------------------------------------------------------------------------
+
+LLFilteredPathfindingLinksets::LLFilteredPathfindingLinksets()
+ : mAllLinksets(),
+ mFilteredLinksets(),
+ mIsFiltersDirty(false),
+ mNameFilter(),
+ mDescriptionFilter(),
+ mIsWalkableFilter(true),
+ mIsObstacleFilter(true),
+ mIsIgnoredFilter(true)
+{
+}
+
+LLFilteredPathfindingLinksets::LLFilteredPathfindingLinksets(const LLSD& pLinksetItems)
+ : mAllLinksets(),
+ mFilteredLinksets(),
+ mIsFiltersDirty(false),
+ mNameFilter(),
+ mDescriptionFilter(),
+ mIsWalkableFilter(true),
+ mIsObstacleFilter(true),
+ mIsIgnoredFilter(true)
+{
+ setPathfindingLinksets(pLinksetItems);
+}
+
+LLFilteredPathfindingLinksets::LLFilteredPathfindingLinksets(const LLFilteredPathfindingLinksets& pOther)
+ : mAllLinksets(pOther.mAllLinksets),
+ mFilteredLinksets(pOther.mFilteredLinksets),
+ mIsFiltersDirty(pOther.mIsFiltersDirty),
+ mNameFilter(pOther.mNameFilter),
+ mDescriptionFilter(pOther.mDescriptionFilter),
+ mIsWalkableFilter(pOther.mIsWalkableFilter),
+ mIsObstacleFilter(pOther.mIsObstacleFilter),
+ mIsIgnoredFilter(pOther.mIsIgnoredFilter)
+{
+}
+
+LLFilteredPathfindingLinksets::~LLFilteredPathfindingLinksets()
+{
+ clearPathfindingLinksets();
+}
+
+void LLFilteredPathfindingLinksets::setPathfindingLinksets(const LLSD& pLinksetItems)
+{
+ clearPathfindingLinksets();
+
+ for (LLSD::map_const_iterator linksetItemIter = pLinksetItems.beginMap();
+ linksetItemIter != pLinksetItems.endMap(); ++linksetItemIter)
+ {
+ const std::string& uuid(linksetItemIter->first);
+ const LLSD& linksetData = linksetItemIter->second;
+ LLPathfindingLinkset linkset(uuid, linksetData);
+
+ mAllLinksets.insert(std::pair<std::string, LLPathfindingLinkset>(uuid, linkset));
+ }
+
+ mIsFiltersDirty = true;
+}
+
+void LLFilteredPathfindingLinksets::updatePathfindingLinksets(const LLSD& pLinksetItems)
+{
+ for (LLSD::map_const_iterator linksetItemIter = pLinksetItems.beginMap();
+ linksetItemIter != pLinksetItems.endMap(); ++linksetItemIter)
+ {
+ const std::string& uuid(linksetItemIter->first);
+ const LLSD& linksetData = linksetItemIter->second;
+ LLPathfindingLinkset linkset(uuid, linksetData);
+
+ PathfindingLinksetMap::iterator linksetIter = mAllLinksets.find(uuid);
+ if (linksetIter == mAllLinksets.end())
+ {
+ mAllLinksets.insert(std::pair<std::string, LLPathfindingLinkset>(uuid, linkset));
+ }
+ else
+ {
+ linksetIter->second = linkset;
+ }
+ }
+
+ mIsFiltersDirty = true;
+}
+
+void LLFilteredPathfindingLinksets::clearPathfindingLinksets()
+{
+ mAllLinksets.clear();
+ mFilteredLinksets.clear();
+ mIsFiltersDirty = false;
+}
+
+const LLFilteredPathfindingLinksets::PathfindingLinksetMap& LLFilteredPathfindingLinksets::getAllLinksets() const
+{
+ return mAllLinksets;
+}
+
+const LLFilteredPathfindingLinksets::PathfindingLinksetMap& LLFilteredPathfindingLinksets::getFilteredLinksets()
+{
+ if (!isFiltersActive())
+ {
+ return mAllLinksets;
+ }
+ else
+ {
+ applyFilters();
+ return mFilteredLinksets;
+ }
+}
+
+BOOL LLFilteredPathfindingLinksets::isFiltersActive() const
+{
+ return (mNameFilter.isActive() || mDescriptionFilter.isActive() || !mIsWalkableFilter || !mIsObstacleFilter || !mIsIgnoredFilter);
+}
+
+void LLFilteredPathfindingLinksets::setNameFilter(const std::string& pNameFilter)
+{
+ mIsFiltersDirty = (mNameFilter.set(pNameFilter) || mIsFiltersDirty);
+}
+
+const std::string& LLFilteredPathfindingLinksets::getNameFilter() const
+{
+ return mNameFilter.get();
+}
+
+void LLFilteredPathfindingLinksets::setDescriptionFilter(const std::string& pDescriptionFilter)
+{
+ mIsFiltersDirty = (mDescriptionFilter.set(pDescriptionFilter) || mIsFiltersDirty);
+}
+
+const std::string& LLFilteredPathfindingLinksets::getDescriptionFilter() const
+{
+ return mDescriptionFilter.get();
+}
+
+void LLFilteredPathfindingLinksets::setWalkableFilter(BOOL pWalkableFilter)
+{
+ mIsFiltersDirty = (mIsFiltersDirty || (mIsWalkableFilter == pWalkableFilter));
+ mIsWalkableFilter = pWalkableFilter;
+}
+
+BOOL LLFilteredPathfindingLinksets::isWalkableFilter() const
+{
+ return mIsWalkableFilter;
+}
+
+void LLFilteredPathfindingLinksets::setObstacleFilter(BOOL pObstacleFilter)
+{
+ mIsFiltersDirty = (mIsFiltersDirty || (mIsObstacleFilter == pObstacleFilter));
+ mIsObstacleFilter = pObstacleFilter;
+}
+
+BOOL LLFilteredPathfindingLinksets::isObstacleFilter() const
+{
+ return mIsObstacleFilter;
+}
+
+void LLFilteredPathfindingLinksets::setIgnoredFilter(BOOL pIgnoredFilter)
+{
+ mIsFiltersDirty = (mIsFiltersDirty || (mIsIgnoredFilter == pIgnoredFilter));
+ mIsIgnoredFilter = pIgnoredFilter;
+}
+
+BOOL LLFilteredPathfindingLinksets::isIgnoredFilter() const
+{
+ return mIsIgnoredFilter;
+}
+
+void LLFilteredPathfindingLinksets::clearFilters()
+{
+ mNameFilter.clear();
+ mDescriptionFilter.clear();
+ mIsWalkableFilter = true;
+ mIsObstacleFilter = true;
+ mIsIgnoredFilter = true;
+ mIsFiltersDirty = false;
+}
+
+void LLFilteredPathfindingLinksets::applyFilters()
+{
+ mFilteredLinksets.clear();
+
+ for (PathfindingLinksetMap::const_iterator linksetIter = mAllLinksets.begin();
+ linksetIter != mAllLinksets.end(); ++linksetIter)
+ {
+ const std::string& uuid(linksetIter->first);
+ const LLPathfindingLinkset& linkset(linksetIter->second);
+ if (doesMatchFilters(linkset))
+ {
+ mFilteredLinksets.insert(std::pair<std::string, LLPathfindingLinkset>(uuid, linkset));
+ }
+ }
+
+ mIsFiltersDirty = false;
+}
+
+BOOL LLFilteredPathfindingLinksets::doesMatchFilters(const LLPathfindingLinkset& pLinkset) const
+{
+ return (((mIsWalkableFilter && (pLinkset.getPathState() == LLPathfindingLinkset::kWalkable)) ||
+ (mIsObstacleFilter && (pLinkset.getPathState() == LLPathfindingLinkset::kObstacle)) ||
+ (mIsIgnoredFilter && (pLinkset.getPathState() == LLPathfindingLinkset::kIgnored))) &&
+ (!mNameFilter.isActive() || mNameFilter.doesMatch(pLinkset.getName())) &&
+ (!mDescriptionFilter.isActive() || mDescriptionFilter.doesMatch(pLinkset.getDescription())));
+}
diff --git a/indra/newview/llfilteredpathfindinglinksets.h b/indra/newview/llfilteredpathfindinglinksets.h
new file mode 100644
index 0000000000..de9b3a5e15
--- /dev/null
+++ b/indra/newview/llfilteredpathfindinglinksets.h
@@ -0,0 +1,111 @@
+/**
+ * @file llfilteredpathfindinglinksets.h
+ * @author William Todd Stinson
+ * @brief Class to implement the filtering of a set of pathfinding linksets
+ *
+ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_FILTEREDPATHFINDINGLINKSETS_H
+#define LL_FILTEREDPATHFINDINGLINKSETS_H
+
+#include <string>
+#include <map>
+
+class LLSD;
+class LLPathfindingLinkset;
+
+class FilterString
+{
+public:
+ FilterString();
+ FilterString(const std::string& pFilter);
+ virtual ~FilterString();
+
+ const std::string& get() const;
+ bool set(const std::string& pFilter);
+ void clear();
+
+ bool isActive() const;
+ bool doesMatch(const std::string& pTestString) const;
+
+protected:
+
+private:
+ std::string mFilter;
+ std::string mUpperFilter;
+};
+
+class LLFilteredPathfindingLinksets
+{
+public:
+ typedef std::map<std::string, LLPathfindingLinkset> PathfindingLinksetMap;
+
+ LLFilteredPathfindingLinksets();
+ LLFilteredPathfindingLinksets(const LLSD& pLinksetItems);
+ LLFilteredPathfindingLinksets(const LLFilteredPathfindingLinksets& pOther);
+ virtual ~LLFilteredPathfindingLinksets();
+
+ void setPathfindingLinksets(const LLSD& pLinksetItems);
+ void updatePathfindingLinksets(const LLSD& pLinksetItems);
+ void clearPathfindingLinksets();
+
+ const PathfindingLinksetMap& getAllLinksets() const;
+ const PathfindingLinksetMap& getFilteredLinksets();
+
+ BOOL isFiltersActive() const;
+
+ void setNameFilter(const std::string& pNameFilter);
+ const std::string& getNameFilter() const;
+
+ void setDescriptionFilter(const std::string& pDescriptionFilter);
+ const std::string& getDescriptionFilter() const;
+
+ void setWalkableFilter(BOOL pWalkableFilter);
+ BOOL isWalkableFilter() const;
+
+ void setObstacleFilter(BOOL pObstacleFilter);
+ BOOL isObstacleFilter() const;
+
+ void setIgnoredFilter(BOOL pIgnoredFilter);
+ BOOL isIgnoredFilter() const;
+
+ void clearFilters();
+
+protected:
+
+private:
+ PathfindingLinksetMap mAllLinksets;
+ PathfindingLinksetMap mFilteredLinksets;
+
+ bool mIsFiltersDirty;
+ FilterString mNameFilter;
+ FilterString mDescriptionFilter;
+ BOOL mIsWalkableFilter;
+ BOOL mIsObstacleFilter;
+ BOOL mIsIgnoredFilter;
+
+ void applyFilters();
+ BOOL doesMatchFilters(const LLPathfindingLinkset& pLinkset) const;
+};
+
+#endif // LL_FILTEREDPATHFINDINGLINKSETS_H
diff --git a/indra/newview/llfloaterpathfindingconsole.cpp b/indra/newview/llfloaterpathfindingconsole.cpp
index fce67c4171..50edc55d76 100644
--- a/indra/newview/llfloaterpathfindingconsole.cpp
+++ b/indra/newview/llfloaterpathfindingconsole.cpp
@@ -313,6 +313,12 @@ void LLFloaterPathfindingConsole::setHasNavMeshReceived()
{
std::string str = getString("navmesh_fetch_complete_available");
mPathfindingStatus->setText((LLStringExplicit)str);
+ //check to see if all regions are done loading and they are then stitch the navmeshes together
+ --mNavMeshCnt;
+ if ( mNavMeshCnt == 0 )
+ {
+ //LLPathingLib::getInstance()->stitchNavMeshes();
+ }
}
void LLFloaterPathfindingConsole::setHasNoNavMesh()
@@ -335,7 +341,10 @@ LLFloaterPathfindingConsole::LLFloaterPathfindingConsole(const LLSD& pSeed)
mTerrainMaterialA(NULL),
mTerrainMaterialB(NULL),
mTerrainMaterialC(NULL),
- mTerrainMaterialD(NULL)
+ mTerrainMaterialD(NULL),
+ mNavMeshCnt(0),
+ mHasStartPoint(false),
+ mHasEndPoint(false)
{
for (int i=0;i<MAX_OBSERVERS;++i)
{
@@ -353,12 +362,7 @@ void LLFloaterPathfindingConsole::onOpen(const LLSD& pKey)
if ( !LLPathingLib::getInstance() )
{
LLPathingLib::initSystem();
- }
- //prep# test remove
- //LLSD content;
- //LLPathingLib::getInstance()->extractNavMeshSrcFromLLSD( content );
- //return true;
- //prep# end test
+ }
if ( LLPathingLib::getInstance() == NULL )
{
std::string str = getString("navmesh_library_not_implemented");
@@ -370,6 +374,8 @@ void LLFloaterPathfindingConsole::onOpen(const LLSD& pKey)
else
{
mCurrentMDO = 0;
+ mNavMeshCnt = 0;
+
//make sure the region is essentially enabled for navmesh support
std::string capability = "RetrieveNavMeshSrc";
@@ -383,7 +389,15 @@ void LLFloaterPathfindingConsole::onOpen(const LLSD& pKey)
shift.push_back( CURRENT_REGION );
//pCurrentRegion->getNeighboringRegionsStatus( shift );
+ //If the navmesh shift ops and the total region counts do not match - use the current region, only.
+ if ( shift.size() != regions.size() )
+ {
+ shift.clear();regions.clear();
+ regions.push_back( pCurrentRegion );
+ shift.push_back( CURRENT_REGION );
+ }
int regionCnt = regions.size();
+ mNavMeshCnt = regionCnt;
for ( int i=0; i<regionCnt; ++i )
{
std::string url = regions[i]->getCapability( capability );
@@ -399,6 +413,7 @@ void LLFloaterPathfindingConsole::onOpen(const LLSD& pKey)
}
else
{
+ --mNavMeshCnt;
std::string str = getString("navmesh_region_not_enabled");
LLStyle::Params styleParams;
styleParams.color = LLUIColorTable::instance().getColor("DrYellow");
@@ -432,7 +447,7 @@ void LLFloaterPathfindingConsole::onShowExcludeVolumesToggle()
LLPathingLib *llPathingLibInstance = LLPathingLib::getInstance();
if (llPathingLibInstance != NULL)
{
- llPathingLibInstance->setRenderNavMeshandShapes(checkBoxValue);
+ llPathingLibInstance->setRenderShapes(checkBoxValue);
}
else
{
@@ -445,15 +460,33 @@ void LLFloaterPathfindingConsole::onShowPathToggle()
{
BOOL checkBoxValue = mShowPathCheckBox->get();
- llwarns << "functionality has not yet been implemented to toggle '"
- << mShowPathCheckBox->getLabel() << "' to "
- << (checkBoxValue ? "ON" : "OFF") << llendl;
+ LLPathingLib *llPathingLibInstance = LLPathingLib::getInstance();
+ if (llPathingLibInstance != NULL)
+ {
+ llPathingLibInstance->setRenderPath(checkBoxValue);
+ }
+ else
+ {
+ mShowPathCheckBox->set(FALSE);
+ llwarns << "cannot find LLPathingLib instance" << llendl;
+ }
}
void LLFloaterPathfindingConsole::onShowWaterPlaneToggle()
{
BOOL checkBoxValue = mShowWaterPlaneCheckBox->get();
+ LLPathingLib *llPathingLibInstance = LLPathingLib::getInstance();
+ if (llPathingLibInstance != NULL)
+ {
+ llPathingLibInstance->setRenderWaterPlane(checkBoxValue);
+ }
+ else
+ {
+ mShowWaterPlaneCheckBox->set(FALSE);
+ llwarns << "cannot find LLPathingLib instance" << llendl;
+ }
+
llwarns << "functionality has not yet been implemented to toggle '"
<< mShowWaterPlaneCheckBox->getLabel() << "' to "
<< (checkBoxValue ? "ON" : "OFF") << llendl;
@@ -461,21 +494,27 @@ void LLFloaterPathfindingConsole::onShowWaterPlaneToggle()
void LLFloaterPathfindingConsole::onRegionOverlayDisplaySwitch()
{
- switch (getRegionOverlayDisplay())
+ LLPathingLib *llPathingLibInstance = LLPathingLib::getInstance();
+ if (llPathingLibInstance != NULL)
{
- case kRenderOverlayOnFixedPhysicsGeometry :
- llwarns << "functionality has not yet been implemented to toggle '"
- << mRegionOverlayDisplayRadioGroup->getName() << "' to RenderOverlayOnFixedPhysicsGeometry"
- << llendl;
- break;
- case kRenderOverlayOnAllRenderableGeometry :
- llwarns << "functionality has not yet been implemented to toggle '"
- << mRegionOverlayDisplayRadioGroup->getName() << "' to RenderOverlayOnAllRenderableGeometry"
- << llendl;
- break;
- default :
- llassert(0);
- break;
+ switch (getRegionOverlayDisplay())
+ {
+ case kRenderOverlayOnFixedPhysicsGeometry :
+ llPathingLibInstance->setRenderOverlayMode(false);
+ break;
+ case kRenderOverlayOnAllRenderableGeometry :
+ llPathingLibInstance->setRenderOverlayMode(true);
+ break;
+ default :
+ llPathingLibInstance->setRenderOverlayMode(false);
+ llassert(0);
+ break;
+ }
+ }
+ else
+ {
+ this->setRegionOverlayDisplay(kRenderOverlayOnFixedPhysicsGeometry);
+ llwarns << "cannot find LLPathingLib instance" << llendl;
}
}
@@ -484,19 +523,10 @@ void LLFloaterPathfindingConsole::onPathSelectionSwitch()
switch (getPathSelectionState())
{
case kPathSelectNone :
- llwarns << "functionality has not yet been implemented to toggle '"
- << mPathSelectionRadioGroup->getName() << "' to PathSelectNone"
- << llendl;
break;
case kPathSelectStartPoint :
- llwarns << "functionality has not yet been implemented to toggle '"
- << mPathSelectionRadioGroup->getName() << "' to PathSelectStartPoint"
- << llendl;
break;
case kPathSelectEndPoint :
- llwarns << "functionality has not yet been implemented to toggle '"
- << mPathSelectionRadioGroup->getName() << "' to PathSelectEndPoint"
- << llendl;
break;
default :
llassert(0);
@@ -506,9 +536,7 @@ void LLFloaterPathfindingConsole::onPathSelectionSwitch()
void LLFloaterPathfindingConsole::onCharacterWidthSet()
{
- F32 characterWidth = getCharacterWidth();
- llwarns << "functionality has not yet been implemented to set '" << mCharacterWidthSlider->getName()
- << "' to the value (" << characterWidth << ")" << llendl;
+ generatePath();
}
void LLFloaterPathfindingConsole::onCharacterTypeSwitch()
@@ -586,11 +614,6 @@ void LLFloaterPathfindingConsole::onTerrainMaterialDSet()
}
-BOOL LLFloaterPathfindingConsole::allowAllRenderables() const
-{
- return getRegionOverlayDisplay() == kRenderOverlayOnAllRenderableGeometry ? true : false;
-}
-
void LLFloaterPathfindingConsole::providePathingData( const LLVector3& point1, const LLVector3& point2 )
{
switch (getPathSelectionState())
@@ -604,18 +627,28 @@ void LLFloaterPathfindingConsole::providePathingData( const LLVector3& point1, c
case kPathSelectStartPoint :
mPathData.mStartPointA = point1;
mPathData.mEndPointA = point2;
+ mHasStartPoint = true;
break;
case kPathSelectEndPoint :
mPathData.mStartPointB = point1;
mPathData.mEndPointB = point2;
- mPathData.mCharacterWidth = getCharacterWidth();
- //prep#TODO# possibly consider an alternate behavior - perhaps add a "path" button to submit the data.
- LLPathingLib::getInstance()->generatePath( mPathData );
+ mHasEndPoint = true;
break;
default :
llassert(0);
break;
- }
+ }
+
+ generatePath();
+}
+
+void LLFloaterPathfindingConsole::generatePath()
+{
+ if (mHasStartPoint && mHasEndPoint)
+ {
+ mPathData.mCharacterWidth = getCharacterWidth();
+ LLPathingLib::getInstance()->generatePath(mPathData);
+ }
}
diff --git a/indra/newview/llfloaterpathfindingconsole.h b/indra/newview/llfloaterpathfindingconsole.h
index 3ae5e25695..f62fd9742b 100644
--- a/indra/newview/llfloaterpathfindingconsole.h
+++ b/indra/newview/llfloaterpathfindingconsole.h
@@ -31,13 +31,13 @@
#include "llfloater.h"
#include "llnavmeshstation.h"
#include "LLPathingLib.h"
-#include "llcheckboxctrl.h"
class LLSD;
class LLRadioGroup;
class LLSliderCtrl;
class LLLineEditor;
class LLTextBase;
+class LLCheckBoxCtrl;
class LLFloaterPathfindingConsole
: public LLFloater
@@ -67,8 +67,6 @@ public:
} ECharacterType;
virtual BOOL postBuild();
- //Accessor to determine whether renderables are allowed
- BOOL allowAllRenderables() const;
//Populates a data packet that is forwarded onto the LLPathingSystem
void providePathingData( const LLVector3& point1, const LLVector3& point2 );
@@ -96,8 +94,6 @@ public:
F32 getTerrainMaterialD() const;
void setTerrainMaterialD(F32 pTerrainMaterial);
- BOOL getShowPathToggle() const {return mShowPathCheckBox->get(); }
-
void setHasNavMeshReceived();
void setHasNoNavMesh();
@@ -126,6 +122,7 @@ private:
void onTerrainMaterialBSet();
void onTerrainMaterialCSet();
void onTerrainMaterialDSet();
+ void generatePath();
LLCheckBoxCtrl *mShowNavMeshCheckBox;
LLCheckBoxCtrl *mShowExcludeVolumesCheckBox;
@@ -143,9 +140,12 @@ private:
LLNavMeshDownloadObserver mNavMeshDownloadObserver[10];
int mCurrentMDO;
+ int mNavMeshCnt;
//Container that is populated and subsequently submitted to the LLPathingSystem for processing
LLPathingLib::PathingPacket mPathData;
+ bool mHasStartPoint;
+ bool mHasEndPoint;
};
#endif // LL_LLFLOATERPATHFINDINGCONSOLE_H
diff --git a/indra/newview/llfloaterpathfindinglinksets.cpp b/indra/newview/llfloaterpathfindinglinksets.cpp
index e8f1401095..4d3581fc60 100644
--- a/indra/newview/llfloaterpathfindinglinksets.cpp
+++ b/indra/newview/llfloaterpathfindinglinksets.cpp
@@ -32,7 +32,7 @@
#include "v3math.h"
#include "lltextvalidate.h"
#include "llagent.h"
-#include "llfloater.h"
+#include "llhandle.h"
#include "llfloaterreg.h"
#include "lltextbase.h"
#include "lllineeditor.h"
@@ -45,6 +45,8 @@
#include "llviewerregion.h"
#include "llhttpclient.h"
#include "lluuid.h"
+#include "llpathfindinglinkset.h"
+#include "llfilteredpathfindinglinksets.h"
#define XUI_PATH_STATE_WALKABLE 1
#define XUI_PATH_STATE_OBSTACLE 2
@@ -57,7 +59,8 @@
class NavMeshDataGetResponder : public LLHTTPClient::Responder
{
public:
- NavMeshDataGetResponder(const std::string& pNavMeshDataGetURL, LLFloaterPathfindingLinksets *pLinksetsFloater);
+ NavMeshDataGetResponder(const std::string& pNavMeshDataGetURL,
+ const LLHandle<LLFloaterPathfindingLinksets> &pLinksetsHandle);
virtual ~NavMeshDataGetResponder();
virtual void result(const LLSD& pContent);
@@ -66,8 +69,8 @@ public:
private:
NavMeshDataGetResponder(const NavMeshDataGetResponder& pOther);
- std::string mNavMeshDataGetURL;
- LLFloaterPathfindingLinksets *mLinksetsFloater;
+ std::string mNavMeshDataGetURL;
+ LLHandle<LLFloaterPathfindingLinksets> mLinksetsFloaterHandle;
};
//---------------------------------------------------------------------------
@@ -77,7 +80,8 @@ private:
class NavMeshDataPutResponder : public LLHTTPClient::Responder
{
public:
- NavMeshDataPutResponder(const std::string& pNavMeshDataPutURL, LLFloaterPathfindingLinksets *pLinksetsFloater);
+ NavMeshDataPutResponder(const std::string& pNavMeshDataPutURL,
+ const LLHandle<LLFloaterPathfindingLinksets> &pLinksetsHandle);
virtual ~NavMeshDataPutResponder();
virtual void result(const LLSD& pContent);
@@ -86,670 +90,11 @@ public:
private:
NavMeshDataPutResponder(const NavMeshDataPutResponder& pOther);
- std::string mNavMeshDataPutURL;
- LLFloaterPathfindingLinksets *mLinksetsFloater;
+ std::string mNavMeshDataPutURL;
+ LLHandle<LLFloaterPathfindingLinksets> mLinksetsFloaterHandle;
};
//---------------------------------------------------------------------------
-// PathfindingLinkset
-//---------------------------------------------------------------------------
-
-const S32 PathfindingLinkset::MIN_WALKABILITY_VALUE(0);
-const S32 PathfindingLinkset::MAX_WALKABILITY_VALUE(100);
-
-PathfindingLinkset::PathfindingLinkset(const std::string &pUUID, const LLSD& pNavMeshItem)
- : mUUID(pUUID),
- mName(),
- mDescription(),
- mLandImpact(0U),
- mLocation(),
- mPathState(kIgnored),
- mIsPhantom(false),
-#ifdef XXX_STINSON_WALKABILITY_COEFFICIENTS_TYPE_CHANGE
- mIsWalkabilityCoefficientsF32(false),
-#endif // XXX_STINSON_WALKABILITY_COEFFICIENTS_TYPE_CHANGE
- mA(MIN_WALKABILITY_VALUE),
- mB(MIN_WALKABILITY_VALUE),
- mC(MIN_WALKABILITY_VALUE),
- mD(MIN_WALKABILITY_VALUE)
-{
- llassert(pNavMeshItem.has("name"));
- llassert(pNavMeshItem.get("name").isString());
- mName = pNavMeshItem.get("name").asString();
-
- llassert(pNavMeshItem.has("description"));
- llassert(pNavMeshItem.get("description").isString());
- mDescription = pNavMeshItem.get("description").asString();
-
- llassert(pNavMeshItem.has("landimpact"));
- llassert(pNavMeshItem.get("landimpact").isInteger());
- llassert(pNavMeshItem.get("landimpact").asInteger() >= 0);
- mLandImpact = pNavMeshItem.get("landimpact").asInteger();
-
- llassert(pNavMeshItem.has("permanent"));
- llassert(pNavMeshItem.get("permanent").isBoolean());
- bool isPermanent = pNavMeshItem.get("permanent").asBoolean();
-
- llassert(pNavMeshItem.has("walkable"));
- llassert(pNavMeshItem.get("walkable").isBoolean());
- bool isWalkable = pNavMeshItem.get("walkable").asBoolean();
-
- mPathState = getPathState(isPermanent, isWalkable);
-
- llassert(pNavMeshItem.has("phantom"));
- llassert(pNavMeshItem.get("phantom").isBoolean());
- mIsPhantom = pNavMeshItem.get("phantom").asBoolean();
-
- llassert(pNavMeshItem.has("A"));
-#ifdef XXX_STINSON_WALKABILITY_COEFFICIENTS_TYPE_CHANGE
- mIsWalkabilityCoefficientsF32 = pNavMeshItem.get("A").isReal();
- if (mIsWalkabilityCoefficientsF32)
- {
- // Old server-side storage was real
- mA = llround(pNavMeshItem.get("A").asReal() * 100.0f);
-
- llassert(pNavMeshItem.has("B"));
- llassert(pNavMeshItem.get("B").isReal());
- mB = llround(pNavMeshItem.get("B").asReal() * 100.0f);
-
- llassert(pNavMeshItem.has("C"));
- llassert(pNavMeshItem.get("C").isReal());
- mC = llround(pNavMeshItem.get("C").asReal() * 100.0f);
-
- llassert(pNavMeshItem.has("D"));
- llassert(pNavMeshItem.get("D").isReal());
- mD = llround(pNavMeshItem.get("D").asReal() * 100.0f);
- }
- else
- {
- // New server-side storage will be integer
- llassert(pNavMeshItem.get("A").isInteger());
- mA = pNavMeshItem.get("A").asInteger();
- llassert(mA >= MIN_WALKABILITY_VALUE);
- llassert(mA <= MAX_WALKABILITY_VALUE);
-
- llassert(pNavMeshItem.has("B"));
- llassert(pNavMeshItem.get("B").isInteger());
- mB = pNavMeshItem.get("B").asInteger();
- llassert(mB >= MIN_WALKABILITY_VALUE);
- llassert(mB <= MAX_WALKABILITY_VALUE);
-
- llassert(pNavMeshItem.has("C"));
- llassert(pNavMeshItem.get("C").isInteger());
- mC = pNavMeshItem.get("C").asInteger();
- llassert(mC >= MIN_WALKABILITY_VALUE);
- llassert(mC <= MAX_WALKABILITY_VALUE);
-
- llassert(pNavMeshItem.has("D"));
- llassert(pNavMeshItem.get("D").isInteger());
- mD = pNavMeshItem.get("D").asInteger();
- llassert(mD >= MIN_WALKABILITY_VALUE);
- llassert(mD <= MAX_WALKABILITY_VALUE);
- }
-#else // XXX_STINSON_WALKABILITY_COEFFICIENTS_TYPE_CHANGE
- llassert(pNavMeshItem.get("A").isInteger());
- mA = pNavMeshItem.get("A").asInteger();
- llassert(mA >= MIN_WALKABILITY_VALUE);
- llassert(mA <= MAX_WALKABILITY_VALUE);
-
- llassert(pNavMeshItem.has("B"));
- llassert(pNavMeshItem.get("B").isInteger());
- mB = pNavMeshItem.get("B").asInteger();
- llassert(mB >= MIN_WALKABILITY_VALUE);
- llassert(mB <= MAX_WALKABILITY_VALUE);
-
- llassert(pNavMeshItem.has("C"));
- llassert(pNavMeshItem.get("C").isInteger());
- mC = pNavMeshItem.get("C").asInteger();
- llassert(mC >= MIN_WALKABILITY_VALUE);
- llassert(mC <= MAX_WALKABILITY_VALUE);
-
- llassert(pNavMeshItem.has("D"));
- llassert(pNavMeshItem.get("D").isInteger());
- mD = pNavMeshItem.get("D").asInteger();
- llassert(mD >= MIN_WALKABILITY_VALUE);
- llassert(mD <= MAX_WALKABILITY_VALUE);
-#endif // XXX_STINSON_WALKABILITY_COEFFICIENTS_TYPE_CHANGE
-
- llassert(pNavMeshItem.has("position"));
- llassert(pNavMeshItem.get("position").isArray());
- mLocation.setValue(pNavMeshItem.get("position"));
-}
-
-PathfindingLinkset::PathfindingLinkset(const PathfindingLinkset& pOther)
- : mUUID(pOther.mUUID),
- mName(pOther.mName),
- mDescription(pOther.mDescription),
- mLandImpact(pOther.mLandImpact),
- mLocation(pOther.mLocation),
- mPathState(pOther.mPathState),
- mIsPhantom(pOther.mIsPhantom),
-#ifdef XXX_STINSON_WALKABILITY_COEFFICIENTS_TYPE_CHANGE
- mIsWalkabilityCoefficientsF32(pOther.mIsWalkabilityCoefficientsF32),
-#endif // XXX_STINSON_WALKABILITY_COEFFICIENTS_TYPE_CHANGE
- mA(pOther.mA),
- mB(pOther.mB),
- mC(pOther.mC),
- mD(pOther.mD)
-{
-}
-
-PathfindingLinkset::~PathfindingLinkset()
-{
-}
-
-PathfindingLinkset& PathfindingLinkset::operator =(const PathfindingLinkset& pOther)
-{
- mUUID = pOther.mUUID;
- mName = pOther.mName;
- mDescription = pOther.mDescription;
- mLandImpact = pOther.mLandImpact;
- mLocation = pOther.mLocation;
- mPathState = pOther.mPathState;
- mIsPhantom = pOther.mIsPhantom;
-#ifdef XXX_STINSON_WALKABILITY_COEFFICIENTS_TYPE_CHANGE
- mIsWalkabilityCoefficientsF32 = pOther.mIsWalkabilityCoefficientsF32;
-#endif // XXX_STINSON_WALKABILITY_COEFFICIENTS_TYPE_CHANGE
- mA = pOther.mA;
- mB = pOther.mB;
- mC = pOther.mC;
- mD = pOther.mD;
-
- return *this;
-}
-
-const LLUUID& PathfindingLinkset::getUUID() const
-{
- return mUUID;
-}
-
-const std::string& PathfindingLinkset::getName() const
-{
- return mName;
-}
-
-const std::string& PathfindingLinkset::getDescription() const
-{
- return mDescription;
-}
-
-U32 PathfindingLinkset::getLandImpact() const
-{
- return mLandImpact;
-}
-
-const LLVector3& PathfindingLinkset::getPositionAgent() const
-{
- return mLocation;
-}
-
-PathfindingLinkset::EPathState PathfindingLinkset::getPathState() const
-{
- return mPathState;
-}
-
-void PathfindingLinkset::setPathState(EPathState pPathState)
-{
- mPathState = pPathState;
-}
-
-PathfindingLinkset::EPathState PathfindingLinkset::getPathState(bool pIsPermanent, bool pIsWalkable)
-{
- return (pIsPermanent ? (pIsWalkable ? kWalkable : kObstacle) : kIgnored);
-}
-
-BOOL PathfindingLinkset::isPermanent(EPathState pPathState)
-{
- BOOL retVal;
-
- switch (pPathState)
- {
- case kWalkable :
- case kObstacle :
- retVal = true;
- break;
- case kIgnored :
- retVal = false;
- break;
- default :
- retVal = false;
- llassert(0);
- break;
- }
-
- return retVal;
-}
-
-BOOL PathfindingLinkset::isWalkable(EPathState pPathState)
-{
- BOOL retVal;
-
- switch (pPathState)
- {
- case kWalkable :
- retVal = true;
- break;
- case kObstacle :
- case kIgnored :
- retVal = false;
- break;
- default :
- retVal = false;
- llassert(0);
- break;
- }
-
- return retVal;
-}
-
-BOOL PathfindingLinkset::isPhantom() const
-{
- return mIsPhantom;
-}
-
-void PathfindingLinkset::setPhantom(BOOL pIsPhantom)
-{
- mIsPhantom = pIsPhantom;
-}
-
-S32 PathfindingLinkset::getA() const
-{
- return mA;
-}
-
-void PathfindingLinkset::setA(S32 pA)
-{
- mA = pA;
-}
-
-S32 PathfindingLinkset::getB() const
-{
- return mB;
-}
-
-void PathfindingLinkset::setB(S32 pB)
-{
- mB = pB;
-}
-
-S32 PathfindingLinkset::getC() const
-{
- return mC;
-}
-
-void PathfindingLinkset::setC(S32 pC)
-{
- mC = pC;
-}
-
-S32 PathfindingLinkset::getD() const
-{
- return mD;
-}
-
-void PathfindingLinkset::setD(S32 pD)
-{
- mD = pD;
-}
-
-LLSD PathfindingLinkset::getAlteredFields(EPathState pPathState, S32 pA, S32 pB, S32 pC, S32 pD, BOOL pIsPhantom) const
-{
- LLSD itemData;
-
- if (mPathState != pPathState)
- {
- itemData["permanent"] = static_cast<bool>(PathfindingLinkset::isPermanent(pPathState));
- itemData["walkable"] = static_cast<bool>(PathfindingLinkset::isWalkable(pPathState));
- }
-#ifdef XXX_STINSON_WALKABILITY_COEFFICIENTS_TYPE_CHANGE
- if (mIsWalkabilityCoefficientsF32)
- {
- if (mA != pA)
- {
- itemData["A"] = llclamp(static_cast<F32>(pA) / 100.0f, 0.0f, 1.0f);
- }
- if (mB != pB)
- {
- itemData["B"] = llclamp(static_cast<F32>(pB) / 100.0f, 0.0f, 1.0f);
- }
- if (mC != pC)
- {
- itemData["C"] = llclamp(static_cast<F32>(pC) / 100.0f, 0.0f, 1.0f);
- }
- if (mD != pD)
- {
- itemData["D"] = llclamp(static_cast<F32>(pD) / 100.0f, 0.0f, 1.0f);
- }
- }
- else
- {
- if (mA != pA)
- {
- itemData["A"] = llclamp(pA, MIN_WALKABILITY_VALUE, MAX_WALKABILITY_VALUE);
- }
- if (mB != pB)
- {
- itemData["B"] = llclamp(pB, MIN_WALKABILITY_VALUE, MAX_WALKABILITY_VALUE);
- }
- if (mC != pC)
- {
- itemData["C"] = llclamp(pC, MIN_WALKABILITY_VALUE, MAX_WALKABILITY_VALUE);
- }
- if (mD != pD)
- {
- itemData["D"] = llclamp(pD, MIN_WALKABILITY_VALUE, MAX_WALKABILITY_VALUE);
- }
- }
-#else // XXX_STINSON_WALKABILITY_COEFFICIENTS_TYPE_CHANGE
- if (mA != pA)
- {
- itemData["A"] = llclamp(pA, MIN_WALKABILITY_VALUE, MAX_WALKABILITY_VALUE);
- }
- if (mB != pB)
- {
- itemData["B"] = llclamp(pB, MIN_WALKABILITY_VALUE, MAX_WALKABILITY_VALUE);
- }
- if (mC != pC)
- {
- itemData["C"] = llclamp(pC, MIN_WALKABILITY_VALUE, MAX_WALKABILITY_VALUE);
- }
- if (mD != pD)
- {
- itemData["D"] = llclamp(pD, MIN_WALKABILITY_VALUE, MAX_WALKABILITY_VALUE);
- }
-#endif // XXX_STINSON_WALKABILITY_COEFFICIENTS_TYPE_CHANGE
- if (mIsPhantom != pIsPhantom)
- {
- itemData["phantom"] = static_cast<bool>(pIsPhantom);
- }
-
- return itemData;
-}
-
-//---------------------------------------------------------------------------
-// FilterString
-//---------------------------------------------------------------------------
-
-FilterString::FilterString()
- : mFilter(),
- mUpperFilter()
-{
-}
-
-FilterString::FilterString(const std::string& pFilter)
- : mFilter(pFilter),
- mUpperFilter()
-{
- LLStringUtil::trim(mFilter);
- mUpperFilter = mFilter;
- if (!mUpperFilter.empty())
- {
- LLStringUtil::toUpper(mUpperFilter);
- }
-}
-
-FilterString::FilterString(const FilterString& pOther)
- : mFilter(pOther.mFilter),
- mUpperFilter(pOther.mUpperFilter)
-{
-}
-
-FilterString::~FilterString()
-{
-}
-
-const std::string& FilterString::get() const
-{
- return mFilter;
-}
-
-bool FilterString::set(const std::string& pFilter)
-{
- std::string newFilter(pFilter);
- LLStringUtil::trim(newFilter);
- bool didFilterChange = (mFilter.compare(newFilter) != 0);
- if (didFilterChange)
- {
- mFilter = newFilter;
- mUpperFilter = newFilter;
- LLStringUtil::toUpper(mUpperFilter);
- }
-
- return didFilterChange;
-}
-
-void FilterString::clear()
-{
- mFilter.clear();
- mUpperFilter.clear();
-}
-
-bool FilterString::isActive() const
-{
- return !mFilter.empty();
-}
-
-bool FilterString::doesMatch(const std::string& pTestString) const
-{
- bool doesMatch = true;
-
- if (isActive())
- {
- std::string upperTestString(pTestString);
- LLStringUtil::toUpper(upperTestString);
- doesMatch = (upperTestString.find(mUpperFilter) != std::string::npos);
- }
-
- return doesMatch;
-}
-
-//---------------------------------------------------------------------------
-// PathfindingLinksets
-//---------------------------------------------------------------------------
-
-PathfindingLinksets::PathfindingLinksets()
- : mAllLinksets(),
- mFilteredLinksets(),
- mIsFiltersDirty(false),
- mNameFilter(),
- mDescriptionFilter(),
- mIsWalkableFilter(true),
- mIsObstacleFilter(true),
- mIsIgnoredFilter(true)
-{
-}
-
-PathfindingLinksets::PathfindingLinksets(const LLSD& pNavMeshData)
- : mAllLinksets(),
- mFilteredLinksets(),
- mIsFiltersDirty(false),
- mNameFilter(),
- mDescriptionFilter(),
- mIsWalkableFilter(true),
- mIsObstacleFilter(true),
- mIsIgnoredFilter(true)
-{
- setNavMeshData(pNavMeshData);
-}
-
-PathfindingLinksets::PathfindingLinksets(const PathfindingLinksets& pOther)
- : mAllLinksets(pOther.mAllLinksets),
- mFilteredLinksets(pOther.mFilteredLinksets),
- mIsFiltersDirty(pOther.mIsFiltersDirty),
- mNameFilter(pOther.mNameFilter),
- mDescriptionFilter(pOther.mDescriptionFilter),
- mIsWalkableFilter(pOther.mIsWalkableFilter),
- mIsObstacleFilter(pOther.mIsObstacleFilter),
- mIsIgnoredFilter(pOther.mIsIgnoredFilter)
-{
-}
-
-PathfindingLinksets::~PathfindingLinksets()
-{
- clearLinksets();
-}
-
-void PathfindingLinksets::setNavMeshData(const LLSD& pNavMeshData)
-{
- clearLinksets();
-
- for (LLSD::map_const_iterator navMeshDataIter = pNavMeshData.beginMap();
- navMeshDataIter != pNavMeshData.endMap(); ++navMeshDataIter)
- {
- const std::string& uuid(navMeshDataIter->first);
- const LLSD& linksetData = navMeshDataIter->second;
- PathfindingLinkset linkset(uuid, linksetData);
-
- mAllLinksets.insert(std::pair<std::string, PathfindingLinkset>(uuid, linkset));
- }
-
- mIsFiltersDirty = true;
-}
-
-void PathfindingLinksets::updateNavMeshData(const LLSD& pNavMeshData)
-{
- for (LLSD::map_const_iterator navMeshDataIter = pNavMeshData.beginMap();
- navMeshDataIter != pNavMeshData.endMap(); ++navMeshDataIter)
- {
- const std::string& uuid(navMeshDataIter->first);
- const LLSD& linksetData = navMeshDataIter->second;
- PathfindingLinkset linkset(uuid, linksetData);
-
- PathfindingLinksetMap::iterator linksetIter = mAllLinksets.find(uuid);
- if (linksetIter == mAllLinksets.end())
- {
- mAllLinksets.insert(std::pair<std::string, PathfindingLinkset>(uuid, linkset));
- }
- else
- {
- linksetIter->second = linkset;
- }
- }
-
- mIsFiltersDirty = true;
-}
-
-void PathfindingLinksets::clearLinksets()
-{
- mAllLinksets.clear();
- mFilteredLinksets.clear();
- mIsFiltersDirty = false;
-}
-
-const PathfindingLinksets::PathfindingLinksetMap& PathfindingLinksets::getAllLinksets() const
-{
- return mAllLinksets;
-}
-
-const PathfindingLinksets::PathfindingLinksetMap& PathfindingLinksets::getFilteredLinksets()
-{
- if (!isFiltersActive())
- {
- return mAllLinksets;
- }
- else
- {
- applyFilters();
- return mFilteredLinksets;
- }
-}
-
-BOOL PathfindingLinksets::isFiltersActive() const
-{
- return (mNameFilter.isActive() || mDescriptionFilter.isActive() || !mIsWalkableFilter || !mIsObstacleFilter || !mIsIgnoredFilter);
-}
-
-void PathfindingLinksets::setNameFilter(const std::string& pNameFilter)
-{
- mIsFiltersDirty = (mNameFilter.set(pNameFilter) || mIsFiltersDirty);
-}
-
-const std::string& PathfindingLinksets::getNameFilter() const
-{
- return mNameFilter.get();
-}
-
-void PathfindingLinksets::setDescriptionFilter(const std::string& pDescriptionFilter)
-{
- mIsFiltersDirty = (mDescriptionFilter.set(pDescriptionFilter) || mIsFiltersDirty);
-}
-
-const std::string& PathfindingLinksets::getDescriptionFilter() const
-{
- return mDescriptionFilter.get();
-}
-
-void PathfindingLinksets::setWalkableFilter(BOOL pWalkableFilter)
-{
- mIsFiltersDirty = (mIsFiltersDirty || (mIsWalkableFilter == pWalkableFilter));
- mIsWalkableFilter = pWalkableFilter;
-}
-
-BOOL PathfindingLinksets::isWalkableFilter() const
-{
- return mIsWalkableFilter;
-}
-
-void PathfindingLinksets::setObstacleFilter(BOOL pObstacleFilter)
-{
- mIsFiltersDirty = (mIsFiltersDirty || (mIsObstacleFilter == pObstacleFilter));
- mIsObstacleFilter = pObstacleFilter;
-}
-
-BOOL PathfindingLinksets::isObstacleFilter() const
-{
- return mIsObstacleFilter;
-}
-
-void PathfindingLinksets::setIgnoredFilter(BOOL pIgnoredFilter)
-{
- mIsFiltersDirty = (mIsFiltersDirty || (mIsIgnoredFilter == pIgnoredFilter));
- mIsIgnoredFilter = pIgnoredFilter;
-}
-
-BOOL PathfindingLinksets::isIgnoredFilter() const
-{
- return mIsIgnoredFilter;
-}
-
-void PathfindingLinksets::clearFilters()
-{
- mNameFilter.clear();
- mDescriptionFilter.clear();
- mIsWalkableFilter = true;
- mIsObstacleFilter = true;
- mIsIgnoredFilter = true;
- mIsFiltersDirty = false;
-}
-
-void PathfindingLinksets::applyFilters()
-{
- mFilteredLinksets.clear();
-
- for (PathfindingLinksetMap::const_iterator linksetIter = mAllLinksets.begin();
- linksetIter != mAllLinksets.end(); ++linksetIter)
- {
- const std::string& uuid(linksetIter->first);
- const PathfindingLinkset& linkset(linksetIter->second);
- if (doesMatchFilters(linkset))
- {
- mFilteredLinksets.insert(std::pair<std::string, PathfindingLinkset>(uuid, linkset));
- }
- }
-
- mIsFiltersDirty = false;
-}
-
-BOOL PathfindingLinksets::doesMatchFilters(const PathfindingLinkset& pLinkset) const
-{
- return (((mIsWalkableFilter && (pLinkset.getPathState() == PathfindingLinkset::kWalkable)) ||
- (mIsObstacleFilter && (pLinkset.getPathState() == PathfindingLinkset::kObstacle)) ||
- (mIsIgnoredFilter && (pLinkset.getPathState() == PathfindingLinkset::kIgnored))) &&
- (!mNameFilter.isActive() || mNameFilter.doesMatch(pLinkset.getName())) &&
- (!mDescriptionFilter.isActive() || mDescriptionFilter.doesMatch(pLinkset.getDescription())));
-}
-
-//---------------------------------------------------------------------------
// LLFloaterPathfindingLinksets
//---------------------------------------------------------------------------
@@ -889,6 +234,7 @@ BOOL LLFloaterPathfindingLinksets::isMessagingInProgress() const
LLFloaterPathfindingLinksets::LLFloaterPathfindingLinksets(const LLSD& pSeed)
: LLFloater(pSeed),
+ mSelfHandle(),
mPathfindingLinksets(),
mMessagingState(kMessagingInitial),
mLinksetsScrollList(NULL),
@@ -914,6 +260,7 @@ LLFloaterPathfindingLinksets::LLFloaterPathfindingLinksets(const LLSD& pSeed)
mEditPhantom(NULL),
mApplyEdits(NULL)
{
+ mSelfHandle.bind(this);
}
LLFloaterPathfindingLinksets::~LLFloaterPathfindingLinksets()
@@ -932,7 +279,7 @@ void LLFloaterPathfindingLinksets::sendNavMeshDataGetRequest()
else
{
setMessagingState(kMessagingFetchStarting);
- mPathfindingLinksets.clearLinksets();
+ mPathfindingLinksets.clearPathfindingLinksets();
updateLinksetsList();
std::string navMeshDataURL = getCapabilityURL();
@@ -944,7 +291,7 @@ void LLFloaterPathfindingLinksets::sendNavMeshDataGetRequest()
else
{
setMessagingState(kMessagingFetchRequestSent);
- LLHTTPClient::get(navMeshDataURL, new NavMeshDataGetResponder(navMeshDataURL, this));
+ LLHTTPClient::get(navMeshDataURL, new NavMeshDataGetResponder(navMeshDataURL, mSelfHandle));
}
}
}
@@ -960,7 +307,7 @@ void LLFloaterPathfindingLinksets::sendNavMeshDataPutRequest(const LLSD& pPostDa
}
else
{
- LLHTTPClient::put(navMeshDataURL, pPostData, new NavMeshDataPutResponder(navMeshDataURL, this));
+ LLHTTPClient::put(navMeshDataURL, pPostData, new NavMeshDataPutResponder(navMeshDataURL, mSelfHandle));
}
}
}
@@ -968,7 +315,7 @@ void LLFloaterPathfindingLinksets::sendNavMeshDataPutRequest(const LLSD& pPostDa
void LLFloaterPathfindingLinksets::handleNavMeshDataGetReply(const LLSD& pNavMeshData)
{
setMessagingState(kMessagingFetchReceived);
- mPathfindingLinksets.setNavMeshData(pNavMeshData);
+ mPathfindingLinksets.setPathfindingLinksets(pNavMeshData);
updateLinksetsList();
setMessagingState(kMessagingComplete);
}
@@ -976,7 +323,7 @@ void LLFloaterPathfindingLinksets::handleNavMeshDataGetReply(const LLSD& pNavMes
void LLFloaterPathfindingLinksets::handleNavMeshDataGetError(const std::string& pURL, const std::string& pErrorReason)
{
setMessagingState(kMessagingFetchError);
- mPathfindingLinksets.clearLinksets();
+ mPathfindingLinksets.clearPathfindingLinksets();
updateLinksetsList();
llwarns << "Error fetching object navmesh properties from URL '" << pURL << "' because " << pErrorReason << llendl;
}
@@ -984,7 +331,7 @@ void LLFloaterPathfindingLinksets::handleNavMeshDataGetError(const std::string&
void LLFloaterPathfindingLinksets::handleNavMeshDataPutReply(const LLSD& pModifiedData)
{
setMessagingState(kMessagingModifyReceived);
- mPathfindingLinksets.updateNavMeshData(pModifiedData);
+ mPathfindingLinksets.updatePathfindingLinksets(pModifiedData);
updateLinksetsList();
setMessagingState(kMessagingComplete);
}
@@ -1025,6 +372,7 @@ void LLFloaterPathfindingLinksets::setMessagingState(EMessagingState pMessagingS
{
mMessagingState = pMessagingState;
updateLinksetsStatusMessage();
+ updateEditFields();
}
void LLFloaterPathfindingLinksets::onApplyFiltersClicked()
@@ -1104,12 +452,12 @@ void LLFloaterPathfindingLinksets::updateLinksetsList()
updateLinksetsStatusMessage();
const LLVector3& avatarPosition = gAgent.getPositionAgent();
- const PathfindingLinksets::PathfindingLinksetMap& linksetMap = mPathfindingLinksets.getFilteredLinksets();
+ const LLFilteredPathfindingLinksets::PathfindingLinksetMap& linksetMap = mPathfindingLinksets.getFilteredLinksets();
- for (PathfindingLinksets::PathfindingLinksetMap::const_iterator linksetIter = linksetMap.begin();
+ for (LLFilteredPathfindingLinksets::PathfindingLinksetMap::const_iterator linksetIter = linksetMap.begin();
linksetIter != linksetMap.end(); ++linksetIter)
{
- const PathfindingLinkset& linkset(linksetIter->second);
+ const LLPathfindingLinkset& linkset(linksetIter->second);
LLSD columns;
@@ -1126,19 +474,19 @@ void LLFloaterPathfindingLinksets::updateLinksetsList()
columns[2]["font"] = "SANSSERIF";
columns[3]["column"] = "dist_from_you";
- columns[3]["value"] = llformat("%1.0f m", dist_vec(avatarPosition, linkset.getPositionAgent()));
+ columns[3]["value"] = llformat("%1.0f m", dist_vec(avatarPosition, linkset.getLocation()));
columns[3]["font"] = "SANSSERIF";
columns[4]["column"] = "path_state";
switch (linkset.getPathState())
{
- case PathfindingLinkset::kWalkable :
+ case LLPathfindingLinkset::kWalkable :
columns[4]["value"] = getString("linkset_path_state_walkable");
break;
- case PathfindingLinkset::kObstacle :
+ case LLPathfindingLinkset::kObstacle :
columns[4]["value"] = getString("linkset_path_state_obstacle");
break;
- case PathfindingLinkset::kIgnored :
+ case LLPathfindingLinkset::kIgnored :
columns[4]["value"] = getString("linkset_path_state_ignored");
break;
default :
@@ -1153,19 +501,19 @@ void LLFloaterPathfindingLinksets::updateLinksetsList()
columns[5]["font"] = "SANSSERIF";
columns[6]["column"] = "a_percent";
- columns[6]["value"] = llformat("%3d", linkset.getA());
+ columns[6]["value"] = llformat("%3d", linkset.getWalkabilityCoefficientA());
columns[6]["font"] = "SANSSERIF";
columns[7]["column"] = "b_percent";
- columns[7]["value"] = llformat("%3d", linkset.getB());
+ columns[7]["value"] = llformat("%3d", linkset.getWalkabilityCoefficientB());
columns[7]["font"] = "SANSSERIF";
columns[8]["column"] = "c_percent";
- columns[8]["value"] = llformat("%3d", linkset.getC());
+ columns[8]["value"] = llformat("%3d", linkset.getWalkabilityCoefficientC());
columns[8]["font"] = "SANSSERIF";
columns[9]["column"] = "d_percent";
- columns[9]["value"] = llformat("%3d", linkset.getD());
+ columns[9]["value"] = llformat("%3d", linkset.getWalkabilityCoefficientD());
columns[9]["font"] = "SANSSERIF";
LLSD element;
@@ -1177,6 +525,7 @@ void LLFloaterPathfindingLinksets::updateLinksetsList()
mLinksetsScrollList->selectMultiple(selectedUUIDs);
updateLinksetsStatusMessage();
+ updateEditFields();
}
void LLFloaterPathfindingLinksets::selectAllLinksets()
@@ -1280,15 +629,15 @@ void LLFloaterPathfindingLinksets::updateEditFields()
{
LLScrollListItem *firstItem = selectedItems.front();
- const PathfindingLinksets::PathfindingLinksetMap &linksetsMap = mPathfindingLinksets.getAllLinksets();
- PathfindingLinksets::PathfindingLinksetMap::const_iterator linksetIter = linksetsMap.find(firstItem->getUUID().asString());
- const PathfindingLinkset &linkset(linksetIter->second);
+ const LLFilteredPathfindingLinksets::PathfindingLinksetMap &linksetsMap = mPathfindingLinksets.getAllLinksets();
+ LLFilteredPathfindingLinksets::PathfindingLinksetMap::const_iterator linksetIter = linksetsMap.find(firstItem->getUUID().asString());
+ const LLPathfindingLinkset &linkset(linksetIter->second);
setPathState(linkset.getPathState());
- mEditA->setValue(LLSD(linkset.getA()));
- mEditB->setValue(LLSD(linkset.getB()));
- mEditC->setValue(LLSD(linkset.getC()));
- mEditD->setValue(LLSD(linkset.getD()));
+ mEditA->setValue(LLSD(linkset.getWalkabilityCoefficientA()));
+ mEditB->setValue(LLSD(linkset.getWalkabilityCoefficientB()));
+ mEditC->setValue(LLSD(linkset.getWalkabilityCoefficientC()));
+ mEditD->setValue(LLSD(linkset.getWalkabilityCoefficientD()));
mEditPhantom->set(linkset.isPhantom());
setEnableEditFields(true);
@@ -1300,7 +649,7 @@ void LLFloaterPathfindingLinksets::applyEditFields()
std::vector<LLScrollListItem*> selectedItems = mLinksetsScrollList->getAllSelected();
if (!selectedItems.empty())
{
- PathfindingLinkset::EPathState pathState = getPathState();
+ LLPathfindingLinkset::EPathState pathState = getPathState();
const std::string &aString = mEditA->getText();
const std::string &bString = mEditB->getText();
const std::string &cString = mEditC->getText();
@@ -1311,7 +660,7 @@ void LLFloaterPathfindingLinksets::applyEditFields()
S32 dValue = static_cast<S32>(atoi(dString.c_str()));
BOOL isPhantom = mEditPhantom->getValue();
- const PathfindingLinksets::PathfindingLinksetMap &linksetsMap = mPathfindingLinksets.getAllLinksets();
+ const LLFilteredPathfindingLinksets::PathfindingLinksetMap &linksetsMap = mPathfindingLinksets.getAllLinksets();
LLSD editData;
for (std::vector<LLScrollListItem*>::const_iterator itemIter = selectedItems.begin();
@@ -1320,10 +669,10 @@ void LLFloaterPathfindingLinksets::applyEditFields()
const LLScrollListItem *listItem = *itemIter;
LLUUID uuid = listItem->getUUID();
- const PathfindingLinksets::PathfindingLinksetMap::const_iterator linksetIter = linksetsMap.find(uuid.asString());
- const PathfindingLinkset &linkset = linksetIter->second;
+ const LLFilteredPathfindingLinksets::PathfindingLinksetMap::const_iterator linksetIter = linksetsMap.find(uuid.asString());
+ const LLPathfindingLinkset &linkset = linksetIter->second;
- LLSD itemData = linkset.getAlteredFields(pathState, aValue, bValue, cValue, dValue, isPhantom);
+ LLSD itemData = linkset.encodeAlteredFields(pathState, aValue, bValue, cValue, dValue, isPhantom);
if (!itemData.isUndefined())
{
@@ -1361,23 +710,23 @@ void LLFloaterPathfindingLinksets::setEnableEditFields(BOOL pEnabled)
mApplyEdits->setEnabled(pEnabled);
}
-PathfindingLinkset::EPathState LLFloaterPathfindingLinksets::getPathState() const
+LLPathfindingLinkset::EPathState LLFloaterPathfindingLinksets::getPathState() const
{
- PathfindingLinkset::EPathState pathState;
+ LLPathfindingLinkset::EPathState pathState;
switch (mEditPathState->getValue().asInteger())
{
case XUI_PATH_STATE_WALKABLE :
- pathState = PathfindingLinkset::kWalkable;
+ pathState = LLPathfindingLinkset::kWalkable;
break;
case XUI_PATH_STATE_OBSTACLE :
- pathState = PathfindingLinkset::kObstacle;
+ pathState = LLPathfindingLinkset::kObstacle;
break;
case XUI_PATH_STATE_IGNORED :
- pathState = PathfindingLinkset::kIgnored;
+ pathState = LLPathfindingLinkset::kIgnored;
break;
default :
- pathState = PathfindingLinkset::kIgnored;
+ pathState = LLPathfindingLinkset::kIgnored;
llassert(0);
break;
}
@@ -1385,19 +734,19 @@ PathfindingLinkset::EPathState LLFloaterPathfindingLinksets::getPathState() cons
return pathState;
}
-void LLFloaterPathfindingLinksets::setPathState(PathfindingLinkset::EPathState pPathState)
+void LLFloaterPathfindingLinksets::setPathState(LLPathfindingLinkset::EPathState pPathState)
{
LLSD radioGroupValue;
switch (pPathState)
{
- case PathfindingLinkset::kWalkable :
+ case LLPathfindingLinkset::kWalkable :
radioGroupValue = XUI_PATH_STATE_WALKABLE;
break;
- case PathfindingLinkset::kObstacle :
+ case LLPathfindingLinkset::kObstacle :
radioGroupValue = XUI_PATH_STATE_OBSTACLE;
break;
- case PathfindingLinkset::kIgnored :
+ case LLPathfindingLinkset::kIgnored :
radioGroupValue = XUI_PATH_STATE_IGNORED;
break;
default :
@@ -1413,48 +762,64 @@ void LLFloaterPathfindingLinksets::setPathState(PathfindingLinkset::EPathState p
// NavMeshDataGetResponder
//---------------------------------------------------------------------------
-NavMeshDataGetResponder::NavMeshDataGetResponder(const std::string& pNavMeshDataGetURL, LLFloaterPathfindingLinksets *pLinksetsFloater)
+NavMeshDataGetResponder::NavMeshDataGetResponder(const std::string& pNavMeshDataGetURL,
+ const LLHandle<LLFloaterPathfindingLinksets> &pLinksetsHandle)
: mNavMeshDataGetURL(pNavMeshDataGetURL),
- mLinksetsFloater(pLinksetsFloater)
+ mLinksetsFloaterHandle(pLinksetsHandle)
{
}
NavMeshDataGetResponder::~NavMeshDataGetResponder()
{
- mLinksetsFloater = NULL;
}
void NavMeshDataGetResponder::result(const LLSD& pContent)
{
- mLinksetsFloater->handleNavMeshDataGetReply(pContent);
+ LLFloaterPathfindingLinksets *linksetsFloater = mLinksetsFloaterHandle.get();
+ if (linksetsFloater != NULL)
+ {
+ linksetsFloater->handleNavMeshDataGetReply(pContent);
+ }
}
void NavMeshDataGetResponder::error(U32 status, const std::string& reason)
{
- mLinksetsFloater->handleNavMeshDataGetError(mNavMeshDataGetURL, reason);
+ LLFloaterPathfindingLinksets *linksetsFloater = mLinksetsFloaterHandle.get();
+ if (linksetsFloater != NULL)
+ {
+ linksetsFloater->handleNavMeshDataGetError(mNavMeshDataGetURL, reason);
+ }
}
//---------------------------------------------------------------------------
// NavMeshDataPutResponder
//---------------------------------------------------------------------------
-NavMeshDataPutResponder::NavMeshDataPutResponder(const std::string& pNavMeshDataPutURL, LLFloaterPathfindingLinksets *pLinksetsFloater)
+NavMeshDataPutResponder::NavMeshDataPutResponder(const std::string& pNavMeshDataPutURL,
+ const LLHandle<LLFloaterPathfindingLinksets> &pLinksetsHandle)
: mNavMeshDataPutURL(pNavMeshDataPutURL),
- mLinksetsFloater(pLinksetsFloater)
+ mLinksetsFloaterHandle(pLinksetsHandle)
{
}
NavMeshDataPutResponder::~NavMeshDataPutResponder()
{
- mLinksetsFloater = NULL;
}
void NavMeshDataPutResponder::result(const LLSD& pContent)
{
- mLinksetsFloater->handleNavMeshDataPutReply(pContent);
+ LLFloaterPathfindingLinksets *linksetsFloater = mLinksetsFloaterHandle.get();
+ if (linksetsFloater != NULL)
+ {
+ linksetsFloater->handleNavMeshDataPutReply(pContent);
+ }
}
void NavMeshDataPutResponder::error(U32 status, const std::string& reason)
{
- mLinksetsFloater->handleNavMeshDataPutError(mNavMeshDataPutURL, reason);
+ LLFloaterPathfindingLinksets *linksetsFloater = mLinksetsFloaterHandle.get();
+ if (linksetsFloater != NULL)
+ {
+ linksetsFloater->handleNavMeshDataPutError(mNavMeshDataPutURL, reason);
+ }
}
diff --git a/indra/newview/llfloaterpathfindinglinksets.h b/indra/newview/llfloaterpathfindinglinksets.h
index 976eaa355f..250625c72a 100644
--- a/indra/newview/llfloaterpathfindinglinksets.h
+++ b/indra/newview/llfloaterpathfindinglinksets.h
@@ -28,15 +28,13 @@
#ifndef LL_LLFLOATERPATHFINDINGLINKSETS_H
#define LL_LLFLOATERPATHFINDINGLINKSETS_H
-#include "llsd.h"
-#include "v3math.h"
+#include "llhandle.h"
#include "llfloater.h"
#include "lluuid.h"
+#include "llpathfindinglinkset.h"
+#include "llfilteredpathfindinglinksets.h"
-// This is a reminder to remove the code regarding the changing of the data type for the
-// walkability coefficients from F32 to S32 representing the percentage from 0-100.
-#define XXX_STINSON_WALKABILITY_COEFFICIENTS_TYPE_CHANGE
-
+class LLSD;
class LLTextBase;
class LLScrollListCtrl;
class LLLineEditor;
@@ -44,142 +42,6 @@ class LLCheckBoxCtrl;
class LLRadioGroup;
class LLButton;
-class PathfindingLinkset
-{
-public:
- typedef enum
- {
- kWalkable,
- kObstacle,
- kIgnored
- } EPathState;
-
- PathfindingLinkset(const std::string &pUUID, const LLSD &pNavMeshItem);
- PathfindingLinkset(const PathfindingLinkset& pOther);
- virtual ~PathfindingLinkset();
-
- PathfindingLinkset& operator = (const PathfindingLinkset& pOther);
-
- const LLUUID& getUUID() const;
- const std::string& getName() const;
- const std::string& getDescription() const;
- U32 getLandImpact() const;
- const LLVector3& getPositionAgent() const;
-
- EPathState getPathState() const;
- void setPathState(EPathState pPathState);
- static EPathState getPathState(bool pIsPermanent, bool pIsWalkable);
- static BOOL isPermanent(EPathState pPathState);
- static BOOL isWalkable(EPathState pPathState);
-
- BOOL isPhantom() const;
- void setPhantom(BOOL pIsPhantom);
-
- S32 getA() const;
- void setA(S32 pA);
-
- S32 getB() const;
- void setB(S32 pB);
-
- S32 getC() const;
- void setC(S32 pC);
-
- S32 getD() const;
- void setD(S32 pD);
-
- LLSD getAlteredFields(EPathState pPathState, S32 pA, S32 pB, S32 pC, S32 pD, BOOL pIsPhantom) const;
-
-protected:
-
-private:
- static const S32 MIN_WALKABILITY_VALUE;
- static const S32 MAX_WALKABILITY_VALUE;
-
- LLUUID mUUID;
- std::string mName;
- std::string mDescription;
- U32 mLandImpact;
- LLVector3 mLocation;
- EPathState mPathState;
- BOOL mIsPhantom;
-#ifdef XXX_STINSON_WALKABILITY_COEFFICIENTS_TYPE_CHANGE
- BOOL mIsWalkabilityCoefficientsF32;
-#endif // XXX_STINSON_WALKABILITY_COEFFICIENTS_TYPE_CHANGE
- S32 mA;
- S32 mB;
- S32 mC;
- S32 mD;
-};
-
-class FilterString
-{
-public:
- FilterString();
- FilterString(const std::string& pFilter);
- FilterString(const FilterString& pOther);
- virtual ~FilterString();
-
- const std::string& get() const;
- bool set(const std::string& pFilter);
- void clear();
-
- bool isActive() const;
- bool doesMatch(const std::string& pTestString) const;
-
-protected:
-
-private:
- std::string mFilter;
- std::string mUpperFilter;
-};
-
-class PathfindingLinksets
-{
-public:
- typedef std::map<std::string, PathfindingLinkset> PathfindingLinksetMap;
-
- PathfindingLinksets();
- PathfindingLinksets(const LLSD& pNavMeshData);
- PathfindingLinksets(const PathfindingLinksets& pOther);
- virtual ~PathfindingLinksets();
-
- void setNavMeshData(const LLSD& pNavMeshData);
- void updateNavMeshData(const LLSD& pNavMeshData);
- void clearLinksets();
-
- const PathfindingLinksetMap& getAllLinksets() const;
- const PathfindingLinksetMap& getFilteredLinksets();
-
- BOOL isFiltersActive() const;
- void setNameFilter(const std::string& pNameFilter);
- const std::string& getNameFilter() const;
- void setDescriptionFilter(const std::string& pDescriptionFilter);
- const std::string& getDescriptionFilter() const;
- void setWalkableFilter(BOOL pWalkableFilter);
- BOOL isWalkableFilter() const;
- void setObstacleFilter(BOOL pObstacleFilter);
- BOOL isObstacleFilter() const;
- void setIgnoredFilter(BOOL pIgnoredFilter);
- BOOL isIgnoredFilter() const;
- void clearFilters();
-
-protected:
-
-private:
- PathfindingLinksetMap mAllLinksets;
- PathfindingLinksetMap mFilteredLinksets;
-
- bool mIsFiltersDirty;
- FilterString mNameFilter;
- FilterString mDescriptionFilter;
- BOOL mIsWalkableFilter;
- BOOL mIsObstacleFilter;
- BOOL mIsIgnoredFilter;
-
- void applyFilters();
- BOOL doesMatchFilters(const PathfindingLinkset& pLinkset) const;
-};
-
class LLFloaterPathfindingLinksets
: public LLFloater
{
@@ -214,30 +76,31 @@ public:
protected:
private:
- PathfindingLinksets mPathfindingLinksets;
- EMessagingState mMessagingState;
- LLScrollListCtrl *mLinksetsScrollList;
- LLTextBase *mLinksetsStatus;
- LLLineEditor *mFilterByName;
- LLLineEditor *mFilterByDescription;
- LLCheckBoxCtrl *mFilterByWalkable;
- LLCheckBoxCtrl *mFilterByObstacle;
- LLCheckBoxCtrl *mFilterByIgnored;
- LLRadioGroup *mEditPathState;
- LLUICtrl *mEditPathStateWalkable;
- LLUICtrl *mEditPathStateObstacle;
- LLUICtrl *mEditPathStateIgnored;
- LLTextBase *mLabelWalkabilityCoefficients;
- LLTextBase *mLabelEditA;
- LLTextBase *mLabelEditB;
- LLTextBase *mLabelEditC;
- LLTextBase *mLabelEditD;
- LLLineEditor *mEditA;
- LLLineEditor *mEditB;
- LLLineEditor *mEditC;
- LLLineEditor *mEditD;
- LLCheckBoxCtrl *mEditPhantom;
- LLButton *mApplyEdits;
+ LLRootHandle<LLFloaterPathfindingLinksets> mSelfHandle;
+ LLFilteredPathfindingLinksets mPathfindingLinksets;
+ EMessagingState mMessagingState;
+ LLScrollListCtrl *mLinksetsScrollList;
+ LLTextBase *mLinksetsStatus;
+ LLLineEditor *mFilterByName;
+ LLLineEditor *mFilterByDescription;
+ LLCheckBoxCtrl *mFilterByWalkable;
+ LLCheckBoxCtrl *mFilterByObstacle;
+ LLCheckBoxCtrl *mFilterByIgnored;
+ LLRadioGroup *mEditPathState;
+ LLUICtrl *mEditPathStateWalkable;
+ LLUICtrl *mEditPathStateObstacle;
+ LLUICtrl *mEditPathStateIgnored;
+ LLTextBase *mLabelWalkabilityCoefficients;
+ LLTextBase *mLabelEditA;
+ LLTextBase *mLabelEditB;
+ LLTextBase *mLabelEditC;
+ LLTextBase *mLabelEditD;
+ LLLineEditor *mEditA;
+ LLLineEditor *mEditB;
+ LLLineEditor *mEditC;
+ LLLineEditor *mEditD;
+ LLCheckBoxCtrl *mEditPhantom;
+ LLButton *mApplyEdits;
// Does its own instance management, so clients not allowed
// to allocate or destroy.
@@ -277,8 +140,8 @@ private:
void applyEditFields();
void setEnableEditFields(BOOL pEnabled);
- PathfindingLinkset::EPathState getPathState() const;
- void setPathState(PathfindingLinkset::EPathState pPathState);
+ LLPathfindingLinkset::EPathState getPathState() const;
+ void setPathState(LLPathfindingLinkset::EPathState pPathState);
};
#endif // LL_LLFLOATERPATHFINDINGLINKSETS_H
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index a97e256c89..c64479f589 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -498,9 +498,11 @@ void LLMeshRepoThread::run()
LODRequest req = mLODReqQ.front();
mLODReqQ.pop();
mMutex->unlock();
- if (fetchMeshLOD(req.mMeshParams, req.mLOD))
+ if (!fetchMeshLOD(req.mMeshParams, req.mLOD, count))//failed, resubmit
{
- count++;
+ mMutex->lock();
+ mLODReqQ.push(req) ;
+ mMutex->unlock();
}
}
}
@@ -512,9 +514,11 @@ void LLMeshRepoThread::run()
HeaderRequest req = mHeaderReqQ.front();
mHeaderReqQ.pop();
mMutex->unlock();
- if (fetchMeshHeader(req.mMeshParams))
+ if (!fetchMeshHeader(req.mMeshParams, count))//failed, resubmit
{
- count++;
+ mMutex->lock();
+ mHeaderReqQ.push(req) ;
+ mMutex->unlock();
}
}
}
@@ -658,6 +662,7 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id)
return false;
}
+ bool ret = true ;
U32 header_size = mMeshHeaderSize[mesh_id];
if (header_size > 0)
@@ -673,7 +678,7 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id)
//check VFS for mesh skin info
LLVFile file(gVFS, mesh_id, LLAssetType::AT_MESH);
if (file.getSize() >= offset+size)
- {
+ {
LLMeshRepository::sCacheBytesRead += size;
file.seek(offset);
U8* buffer = new U8[size];
@@ -689,7 +694,7 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id)
if (!zero)
{ //attempt to parse
if (skinInfoReceived(mesh_id, buffer, size))
- {
+ {
delete[] buffer;
return true;
}
@@ -704,11 +709,14 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id)
std::string http_url = constructUrl(mesh_id);
if (!http_url.empty())
- {
- ++sActiveLODRequests;
- LLMeshRepository::sHTTPRequestCount++;
- mCurlRequest->getByteRange(constructUrl(mesh_id), headers, offset, size,
+ {
+ ret = mCurlRequest->getByteRange(http_url, headers, offset, size,
new LLMeshSkinInfoResponder(mesh_id, offset, size));
+ if(ret)
+ {
+ ++sActiveLODRequests;
+ LLMeshRepository::sHTTPRequestCount++;
+ }
}
}
}
@@ -718,7 +726,7 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id)
}
//early out was not hit, effectively fetched
- return true;
+ return ret;
}
bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id)
@@ -732,7 +740,8 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id)
}
U32 header_size = mMeshHeaderSize[mesh_id];
-
+ bool ret = true ;
+
if (header_size > 0)
{
S32 version = mMeshHeader[mesh_id]["version"].asInteger();
@@ -748,6 +757,7 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id)
if (file.getSize() >= offset+size)
{
LLMeshRepository::sCacheBytesRead += size;
+
file.seek(offset);
U8* buffer = new U8[size];
file.read(buffer, size);
@@ -777,11 +787,14 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id)
std::string http_url = constructUrl(mesh_id);
if (!http_url.empty())
- {
- ++sActiveLODRequests;
- LLMeshRepository::sHTTPRequestCount++;
- mCurlRequest->getByteRange(http_url, headers, offset, size,
+ {
+ ret = mCurlRequest->getByteRange(http_url, headers, offset, size,
new LLMeshDecompositionResponder(mesh_id, offset, size));
+ if(ret)
+ {
+ ++sActiveLODRequests;
+ LLMeshRepository::sHTTPRequestCount++;
+ }
}
}
}
@@ -791,7 +804,7 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id)
}
//early out was not hit, effectively fetched
- return true;
+ return ret;
}
bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id)
@@ -805,6 +818,7 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id)
}
U32 header_size = mMeshHeaderSize[mesh_id];
+ bool ret = true ;
if (header_size > 0)
{
@@ -850,11 +864,15 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id)
std::string http_url = constructUrl(mesh_id);
if (!http_url.empty())
- {
- ++sActiveLODRequests;
- LLMeshRepository::sHTTPRequestCount++;
- mCurlRequest->getByteRange(http_url, headers, offset, size,
+ {
+ ret = mCurlRequest->getByteRange(http_url, headers, offset, size,
new LLMeshPhysicsShapeResponder(mesh_id, offset, size));
+
+ if(ret)
+ {
+ ++sActiveLODRequests;
+ LLMeshRepository::sHTTPRequestCount++;
+ }
}
}
else
@@ -868,13 +886,12 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id)
}
//early out was not hit, effectively fetched
- return true;
+ return ret;
}
-bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params)
+//return false if failed to get header
+bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params, U32& count)
{
- bool retval = false;
-
{
//look for mesh in asset in vfs
LLVFile file(gVFS, mesh_params.getSculptID(), LLAssetType::AT_MESH);
@@ -889,36 +906,40 @@ bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params)
file.read(buffer, bytes);
if (headerReceived(mesh_params, buffer, bytes))
{ //did not do an HTTP request, return false
- return false;
+ return true;
}
}
}
- //either cache entry doesn't exist or is corrupt, request header from simulator
-
+ //either cache entry doesn't exist or is corrupt, request header from simulator
+ bool retval = true ;
std::vector<std::string> headers;
headers.push_back("Accept: application/octet-stream");
std::string http_url = constructUrl(mesh_params.getSculptID());
if (!http_url.empty())
{
- ++sActiveHeaderRequests;
- retval = true;
//grab first 4KB if we're going to bother with a fetch. Cache will prevent future fetches if a full mesh fits
//within the first 4KB
- //NOTE -- this will break of headers ever exceed 4KB
- LLMeshRepository::sHTTPRequestCount++;
- mCurlRequest->getByteRange(http_url, headers, 0, 4096, new LLMeshHeaderResponder(mesh_params));
+ //NOTE -- this will break of headers ever exceed 4KB
+ retval = mCurlRequest->getByteRange(http_url, headers, 0, 4096, new LLMeshHeaderResponder(mesh_params));
+ if(retval)
+ {
+ ++sActiveHeaderRequests;
+ LLMeshRepository::sHTTPRequestCount++;
+ }
+ count++;
}
return retval;
}
-bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod)
+//return false if failed to get mesh lod.
+bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod, U32& count)
{ //protected by mMutex
mHeaderMutex->lock();
- bool retval = false;
+ bool retval = true;
LLUUID mesh_id = mesh_params.getSculptID();
@@ -955,7 +976,7 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod)
if (lodReceived(mesh_params, lod, buffer, size))
{
delete[] buffer;
- return false;
+ return true;
}
}
@@ -968,12 +989,16 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod)
std::string http_url = constructUrl(mesh_id);
if (!http_url.empty())
- {
- ++sActiveLODRequests;
- retval = true;
- LLMeshRepository::sHTTPRequestCount++;
- mCurlRequest->getByteRange(constructUrl(mesh_id), headers, offset, size,
+ {
+ retval = mCurlRequest->getByteRange(constructUrl(mesh_id), headers, offset, size,
new LLMeshLODResponder(mesh_params, lod, offset, size));
+
+ if(retval)
+ {
+ ++sActiveLODRequests;
+ LLMeshRepository::sHTTPRequestCount++;
+ }
+ count++;
}
else
{
@@ -1540,8 +1565,17 @@ void LLMeshUploadThread::doWholeModelUpload()
LLSD body = full_model_data["asset_resources"];
dump_llsd_to_file(body,make_dump_name("whole_model_body_",dump_num));
LLCurlRequest::headers_t headers;
- mCurlRequest->post(mWholeModelUploadURL, headers, body,
- new LLWholeModelUploadResponder(this, full_model_data, mUploadObserverHandle), mMeshUploadTimeOut);
+
+ {
+ LLCurl::ResponderPtr responder = new LLWholeModelUploadResponder(this, full_model_data, mUploadObserverHandle) ;
+
+ while(!mCurlRequest->post(mWholeModelUploadURL, headers, body, responder, mMeshUploadTimeOut))
+ {
+ //sleep for 10ms to prevent eating a whole core
+ apr_sleep(10000);
+ }
+ }
+
do
{
mCurlRequest->process();
@@ -1571,8 +1605,15 @@ void LLMeshUploadThread::requestWholeModelFee()
mPendingUploads++;
LLCurlRequest::headers_t headers;
- mCurlRequest->post(mWholeModelFeeCapability, headers, model_data,
- new LLWholeModelFeeResponder(this,model_data, mFeeObserverHandle), mMeshUploadTimeOut);
+
+ {
+ LLCurl::ResponderPtr responder = new LLWholeModelFeeResponder(this,model_data, mFeeObserverHandle) ;
+ while(!mCurlRequest->post(mWholeModelFeeCapability, headers, model_data, responder, mMeshUploadTimeOut))
+ {
+ //sleep for 10ms to prevent eating a whole core
+ apr_sleep(10000);
+ }
+ }
do
{
diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h
index 27e8aef57c..1b7954d4bd 100644
--- a/indra/newview/llmeshrepository.h
+++ b/indra/newview/llmeshrepository.h
@@ -323,8 +323,8 @@ public:
virtual void run();
void loadMeshLOD(const LLVolumeParams& mesh_params, S32 lod);
- bool fetchMeshHeader(const LLVolumeParams& mesh_params);
- bool fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod);
+ bool fetchMeshHeader(const LLVolumeParams& mesh_params, U32& count);
+ bool fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod, U32& count);
bool headerReceived(const LLVolumeParams& mesh_params, U8* data, S32 data_size);
bool lodReceived(const LLVolumeParams& mesh_params, S32 lod, U8* data, S32 data_size);
bool skinInfoReceived(const LLUUID& mesh_id, U8* data, S32 data_size);
diff --git a/indra/newview/llpathfindinglinkset.cpp b/indra/newview/llpathfindinglinkset.cpp
new file mode 100644
index 0000000000..daa308f862
--- /dev/null
+++ b/indra/newview/llpathfindinglinkset.cpp
@@ -0,0 +1,356 @@
+/**
+ * @file llpathfindinglinksets.cpp
+ * @author William Todd Stinson
+ * @brief Definition of a pathfinding linkset that contains various properties required for havok pathfinding.
+ *
+ * $LicenseInfo:firstyear=2002&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$
+ */
+
+#include "llviewerprecompiledheaders.h"
+#include "llpathfindinglinkset.h"
+#include "llsd.h"
+#include "v3math.h"
+#include "lluuid.h"
+
+#define LINKSET_NAME_FIELD "name"
+#define LINKSET_DESCRIPTION_FIELD "description"
+#define LINKSET_LAND_IMPACT_FIELD "landimpact"
+#define LINKSET_PERMANENT_FIELD "permanent"
+#define LINKSET_WALKABLE_FIELD "walkable"
+#define LINKSET_PHANTOM_FIELD "phantom"
+#define LINKSET_WALKABILITY_A_FIELD "A"
+#define LINKSET_WALKABILITY_B_FIELD "B"
+#define LINKSET_WALKABILITY_C_FIELD "C"
+#define LINKSET_WALKABILITY_D_FIELD "D"
+#define LINKSET_POSITION_FIELD "position"
+
+//---------------------------------------------------------------------------
+// LLPathfindingLinkset
+//---------------------------------------------------------------------------
+
+const S32 LLPathfindingLinkset::MIN_WALKABILITY_VALUE(0);
+const S32 LLPathfindingLinkset::MAX_WALKABILITY_VALUE(100);
+
+LLPathfindingLinkset::LLPathfindingLinkset(const std::string &pUUID, const LLSD& pLinksetItem)
+ : mUUID(pUUID),
+ mName(),
+ mDescription(),
+ mLandImpact(0U),
+ mLocation(),
+ mPathState(kIgnored),
+ mIsPhantom(false),
+#ifdef XXX_STINSON_WALKABILITY_COEFFICIENTS_TYPE_CHANGE
+ mIsWalkabilityCoefficientsF32(false),
+#endif // XXX_STINSON_WALKABILITY_COEFFICIENTS_TYPE_CHANGE
+ mWalkabilityCoefficientA(MIN_WALKABILITY_VALUE),
+ mWalkabilityCoefficientB(MIN_WALKABILITY_VALUE),
+ mWalkabilityCoefficientC(MIN_WALKABILITY_VALUE),
+ mWalkabilityCoefficientD(MIN_WALKABILITY_VALUE)
+{
+ llassert(pLinksetItem.has(LINKSET_NAME_FIELD));
+ llassert(pLinksetItem.get(LINKSET_NAME_FIELD).isString());
+ mName = pLinksetItem.get(LINKSET_NAME_FIELD).asString();
+
+ llassert(pLinksetItem.has(LINKSET_DESCRIPTION_FIELD));
+ llassert(pLinksetItem.get(LINKSET_DESCRIPTION_FIELD).isString());
+ mDescription = pLinksetItem.get(LINKSET_DESCRIPTION_FIELD).asString();
+
+ llassert(pLinksetItem.has(LINKSET_LAND_IMPACT_FIELD));
+ llassert(pLinksetItem.get(LINKSET_LAND_IMPACT_FIELD).isInteger());
+ llassert(pLinksetItem.get(LINKSET_LAND_IMPACT_FIELD).asInteger() >= 0);
+ mLandImpact = pLinksetItem.get(LINKSET_LAND_IMPACT_FIELD).asInteger();
+
+ llassert(pLinksetItem.has(LINKSET_PERMANENT_FIELD));
+ llassert(pLinksetItem.get(LINKSET_PERMANENT_FIELD).isBoolean());
+ bool isPermanent = pLinksetItem.get(LINKSET_PERMANENT_FIELD).asBoolean();
+
+ llassert(pLinksetItem.has(LINKSET_WALKABLE_FIELD));
+ llassert(pLinksetItem.get(LINKSET_WALKABLE_FIELD).isBoolean());
+ bool isWalkable = pLinksetItem.get(LINKSET_WALKABLE_FIELD).asBoolean();
+
+ mPathState = getPathState(isPermanent, isWalkable);
+
+ llassert(pLinksetItem.has(LINKSET_PHANTOM_FIELD));
+ llassert(pLinksetItem.get(LINKSET_PHANTOM_FIELD).isBoolean());
+ mIsPhantom = pLinksetItem.get(LINKSET_PHANTOM_FIELD).asBoolean();
+
+ llassert(pLinksetItem.has(LINKSET_WALKABILITY_A_FIELD));
+#ifdef XXX_STINSON_WALKABILITY_COEFFICIENTS_TYPE_CHANGE
+ mIsWalkabilityCoefficientsF32 = pLinksetItem.get(LINKSET_WALKABILITY_A_FIELD).isReal();
+ if (mIsWalkabilityCoefficientsF32)
+ {
+ // Old server-side storage was real
+ mWalkabilityCoefficientA = llround(pLinksetItem.get(LINKSET_WALKABILITY_A_FIELD).asReal() * 100.0f);
+
+ llassert(pLinksetItem.has(LINKSET_WALKABILITY_B_FIELD));
+ llassert(pLinksetItem.get(LINKSET_WALKABILITY_B_FIELD).isReal());
+ mWalkabilityCoefficientB = llround(pLinksetItem.get(LINKSET_WALKABILITY_B_FIELD).asReal() * 100.0f);
+
+ llassert(pLinksetItem.has(LINKSET_WALKABILITY_C_FIELD));
+ llassert(pLinksetItem.get(LINKSET_WALKABILITY_C_FIELD).isReal());
+ mWalkabilityCoefficientC = llround(pLinksetItem.get(LINKSET_WALKABILITY_C_FIELD).asReal() * 100.0f);
+
+ llassert(pLinksetItem.has(LINKSET_WALKABILITY_D_FIELD));
+ llassert(pLinksetItem.get(LINKSET_WALKABILITY_D_FIELD).isReal());
+ mWalkabilityCoefficientD = llround(pLinksetItem.get(LINKSET_WALKABILITY_D_FIELD).asReal() * 100.0f);
+ }
+ else
+ {
+ // New server-side storage will be integer
+ llassert(pLinksetItem.get(LINKSET_WALKABILITY_A_FIELD).isInteger());
+ mWalkabilityCoefficientA = pLinksetItem.get(LINKSET_WALKABILITY_A_FIELD).asInteger();
+ llassert(mWalkabilityCoefficientA >= MIN_WALKABILITY_VALUE);
+ llassert(mWalkabilityCoefficientA <= MAX_WALKABILITY_VALUE);
+
+ llassert(pLinksetItem.has(LINKSET_WALKABILITY_B_FIELD));
+ llassert(pLinksetItem.get(LINKSET_WALKABILITY_B_FIELD).isInteger());
+ mWalkabilityCoefficientB = pLinksetItem.get(LINKSET_WALKABILITY_B_FIELD).asInteger();
+ llassert(mWalkabilityCoefficientB >= MIN_WALKABILITY_VALUE);
+ llassert(mWalkabilityCoefficientB <= MAX_WALKABILITY_VALUE);
+
+ llassert(pLinksetItem.has(LINKSET_WALKABILITY_C_FIELD));
+ llassert(pLinksetItem.get(LINKSET_WALKABILITY_C_FIELD).isInteger());
+ mWalkabilityCoefficientC = pLinksetItem.get(LINKSET_WALKABILITY_C_FIELD).asInteger();
+ llassert(mWalkabilityCoefficientC >= MIN_WALKABILITY_VALUE);
+ llassert(mWalkabilityCoefficientC <= MAX_WALKABILITY_VALUE);
+
+ llassert(pLinksetItem.has(LINKSET_WALKABILITY_D_FIELD));
+ llassert(pLinksetItem.get(LINKSET_WALKABILITY_D_FIELD).isInteger());
+ mWalkabilityCoefficientD = pLinksetItem.get(LINKSET_WALKABILITY_D_FIELD).asInteger();
+ llassert(mWalkabilityCoefficientD >= MIN_WALKABILITY_VALUE);
+ llassert(mWalkabilityCoefficientD <= MAX_WALKABILITY_VALUE);
+ }
+#else // XXX_STINSON_WALKABILITY_COEFFICIENTS_TYPE_CHANGE
+ llassert(pLinksetItem.get(LINKSET_WALKABILITY_A_FIELD).isInteger());
+ mWalkabilityCoefficientA = pLinksetItem.get(LINKSET_WALKABILITY_A_FIELD).asInteger();
+ llassert(mWalkabilityCoefficientA >= MIN_WALKABILITY_VALUE);
+ llassert(mWalkabilityCoefficientA <= MAX_WALKABILITY_VALUE);
+
+ llassert(pLinksetItem.has(LINKSET_WALKABILITY_B_FIELD));
+ llassert(pLinksetItem.get(LINKSET_WALKABILITY_B_FIELD).isInteger());
+ mWalkabilityCoefficientB = pLinksetItem.get(LINKSET_WALKABILITY_B_FIELD).asInteger();
+ llassert(mWalkabilityCoefficientB >= MIN_WALKABILITY_VALUE);
+ llassert(mWalkabilityCoefficientB <= MAX_WALKABILITY_VALUE);
+
+ llassert(pLinksetItem.has(LINKSET_WALKABILITY_C_FIELD));
+ llassert(pLinksetItem.get(LINKSET_WALKABILITY_C_FIELD).isInteger());
+ mWalkabilityCoefficientC = pLinksetItem.get(LINKSET_WALKABILITY_C_FIELD).asInteger();
+ llassert(mWalkabilityCoefficientC >= MIN_WALKABILITY_VALUE);
+ llassert(mWalkabilityCoefficientC <= MAX_WALKABILITY_VALUE);
+
+ llassert(pLinksetItem.has(LINKSET_WALKABILITY_D_FIELD));
+ llassert(pLinksetItem.get(LINKSET_WALKABILITY_D_FIELD).isInteger());
+ mWalkabilityCoefficientD = pLinksetItem.get(LINKSET_WALKABILITY_D_FIELD).asInteger();
+ llassert(mWalkabilityCoefficientD >= MIN_WALKABILITY_VALUE);
+ llassert(mWalkabilityCoefficientD <= MAX_WALKABILITY_VALUE);
+#endif // XXX_STINSON_WALKABILITY_COEFFICIENTS_TYPE_CHANGE
+
+ llassert(pLinksetItem.has(LINKSET_POSITION_FIELD));
+ llassert(pLinksetItem.get(LINKSET_POSITION_FIELD).isArray());
+ mLocation.setValue(pLinksetItem.get(LINKSET_POSITION_FIELD));
+}
+
+LLPathfindingLinkset::LLPathfindingLinkset(const LLPathfindingLinkset& pOther)
+ : mUUID(pOther.mUUID),
+ mName(pOther.mName),
+ mDescription(pOther.mDescription),
+ mLandImpact(pOther.mLandImpact),
+ mLocation(pOther.mLocation),
+ mPathState(pOther.mPathState),
+ mIsPhantom(pOther.mIsPhantom),
+#ifdef XXX_STINSON_WALKABILITY_COEFFICIENTS_TYPE_CHANGE
+ mIsWalkabilityCoefficientsF32(pOther.mIsWalkabilityCoefficientsF32),
+#endif // XXX_STINSON_WALKABILITY_COEFFICIENTS_TYPE_CHANGE
+ mWalkabilityCoefficientA(pOther.mWalkabilityCoefficientA),
+ mWalkabilityCoefficientB(pOther.mWalkabilityCoefficientB),
+ mWalkabilityCoefficientC(pOther.mWalkabilityCoefficientC),
+ mWalkabilityCoefficientD(pOther.mWalkabilityCoefficientD)
+{
+}
+
+LLPathfindingLinkset::~LLPathfindingLinkset()
+{
+}
+
+LLPathfindingLinkset& LLPathfindingLinkset::operator =(const LLPathfindingLinkset& pOther)
+{
+ mUUID = pOther.mUUID;
+ mName = pOther.mName;
+ mDescription = pOther.mDescription;
+ mLandImpact = pOther.mLandImpact;
+ mLocation = pOther.mLocation;
+ mPathState = pOther.mPathState;
+ mIsPhantom = pOther.mIsPhantom;
+#ifdef XXX_STINSON_WALKABILITY_COEFFICIENTS_TYPE_CHANGE
+ mIsWalkabilityCoefficientsF32 = pOther.mIsWalkabilityCoefficientsF32;
+#endif // XXX_STINSON_WALKABILITY_COEFFICIENTS_TYPE_CHANGE
+ mWalkabilityCoefficientA = pOther.mWalkabilityCoefficientA;
+ mWalkabilityCoefficientB = pOther.mWalkabilityCoefficientB;
+ mWalkabilityCoefficientC = pOther.mWalkabilityCoefficientC;
+ mWalkabilityCoefficientD = pOther.mWalkabilityCoefficientD;
+
+ return *this;
+}
+
+
+LLPathfindingLinkset::EPathState LLPathfindingLinkset::getPathState(bool pIsPermanent, bool pIsWalkable)
+{
+ return (pIsPermanent ? (pIsWalkable ? kWalkable : kObstacle) : kIgnored);
+}
+
+BOOL LLPathfindingLinkset::isPermanent(EPathState pPathState)
+{
+ BOOL retVal;
+
+ switch (pPathState)
+ {
+ case kWalkable :
+ case kObstacle :
+ retVal = true;
+ break;
+ case kIgnored :
+ retVal = false;
+ break;
+ default :
+ retVal = false;
+ llassert(0);
+ break;
+ }
+
+ return retVal;
+}
+
+BOOL LLPathfindingLinkset::isWalkable(EPathState pPathState)
+{
+ BOOL retVal;
+
+ switch (pPathState)
+ {
+ case kWalkable :
+ retVal = true;
+ break;
+ case kObstacle :
+ case kIgnored :
+ retVal = false;
+ break;
+ default :
+ retVal = false;
+ llassert(0);
+ break;
+ }
+
+ return retVal;
+}
+
+void LLPathfindingLinkset::setWalkabilityCoefficientA(S32 pA)
+{
+ mWalkabilityCoefficientA = llclamp(pA, MIN_WALKABILITY_VALUE, MAX_WALKABILITY_VALUE);
+}
+
+void LLPathfindingLinkset::setWalkabilityCoefficientB(S32 pB)
+{
+ mWalkabilityCoefficientB = llclamp(pB, MIN_WALKABILITY_VALUE, MAX_WALKABILITY_VALUE);
+}
+
+void LLPathfindingLinkset::setWalkabilityCoefficientC(S32 pC)
+{
+ mWalkabilityCoefficientC = llclamp(pC, MIN_WALKABILITY_VALUE, MAX_WALKABILITY_VALUE);
+}
+
+void LLPathfindingLinkset::setWalkabilityCoefficientD(S32 pD)
+{
+ mWalkabilityCoefficientD = llclamp(pD, MIN_WALKABILITY_VALUE, MAX_WALKABILITY_VALUE);
+}
+
+LLSD LLPathfindingLinkset::encodeAlteredFields(EPathState pPathState, S32 pA, S32 pB, S32 pC, S32 pD, BOOL pIsPhantom) const
+{
+ LLSD itemData;
+
+ if (mPathState != pPathState)
+ {
+ itemData[LINKSET_PERMANENT_FIELD] = static_cast<bool>(LLPathfindingLinkset::isPermanent(pPathState));
+ itemData[LINKSET_WALKABLE_FIELD] = static_cast<bool>(LLPathfindingLinkset::isWalkable(pPathState));
+ }
+#ifdef XXX_STINSON_WALKABILITY_COEFFICIENTS_TYPE_CHANGE
+ if (mIsWalkabilityCoefficientsF32)
+ {
+ if (mWalkabilityCoefficientA != pA)
+ {
+ itemData[LINKSET_WALKABILITY_A_FIELD] = llclamp(static_cast<F32>(pA) / 100.0f, 0.0f, 1.0f);
+ }
+ if (mWalkabilityCoefficientB != pB)
+ {
+ itemData[LINKSET_WALKABILITY_B_FIELD] = llclamp(static_cast<F32>(pB) / 100.0f, 0.0f, 1.0f);
+ }
+ if (mWalkabilityCoefficientC != pC)
+ {
+ itemData[LINKSET_WALKABILITY_C_FIELD] = llclamp(static_cast<F32>(pC) / 100.0f, 0.0f, 1.0f);
+ }
+ if (mWalkabilityCoefficientD != pD)
+ {
+ itemData[LINKSET_WALKABILITY_D_FIELD] = llclamp(static_cast<F32>(pD) / 100.0f, 0.0f, 1.0f);
+ }
+ }
+ else
+ {
+ if (mWalkabilityCoefficientA != pA)
+ {
+ itemData[LINKSET_WALKABILITY_A_FIELD] = llclamp(pA, MIN_WALKABILITY_VALUE, MAX_WALKABILITY_VALUE);
+ }
+ if (mWalkabilityCoefficientB != pB)
+ {
+ itemData[LINKSET_WALKABILITY_B_FIELD] = llclamp(pB, MIN_WALKABILITY_VALUE, MAX_WALKABILITY_VALUE);
+ }
+ if (mWalkabilityCoefficientC != pC)
+ {
+ itemData[LINKSET_WALKABILITY_C_FIELD] = llclamp(pC, MIN_WALKABILITY_VALUE, MAX_WALKABILITY_VALUE);
+ }
+ if (mWalkabilityCoefficientD != pD)
+ {
+ itemData[LINKSET_WALKABILITY_D_FIELD] = llclamp(pD, MIN_WALKABILITY_VALUE, MAX_WALKABILITY_VALUE);
+ }
+ }
+#else // XXX_STINSON_WALKABILITY_COEFFICIENTS_TYPE_CHANGE
+ if (mWalkabilityCoefficientA != pA)
+ {
+ itemData[LINKSET_WALKABILITY_A_FIELD] = llclamp(pA, MIN_WALKABILITY_VALUE, MAX_WALKABILITY_VALUE);
+ }
+ if (mWalkabilityCoefficientB != pB)
+ {
+ itemData[LINKSET_WALKABILITY_B_FIELD] = llclamp(pB, MIN_WALKABILITY_VALUE, MAX_WALKABILITY_VALUE);
+ }
+ if (mWalkabilityCoefficientC != pC)
+ {
+ itemData[LINKSET_WALKABILITY_C_FIELD] = llclamp(pC, MIN_WALKABILITY_VALUE, MAX_WALKABILITY_VALUE);
+ }
+ if (mWalkabilityCoefficientD != pD)
+ {
+ itemData[LINKSET_WALKABILITY_D_FIELD] = llclamp(pD, MIN_WALKABILITY_VALUE, MAX_WALKABILITY_VALUE);
+ }
+#endif // XXX_STINSON_WALKABILITY_COEFFICIENTS_TYPE_CHANGE
+ if (mIsPhantom != pIsPhantom)
+ {
+ itemData[LINKSET_PHANTOM_FIELD] = static_cast<bool>(pIsPhantom);
+ }
+
+ return itemData;
+}
diff --git a/indra/newview/llpathfindinglinkset.h b/indra/newview/llpathfindinglinkset.h
new file mode 100644
index 0000000000..d4e58874eb
--- /dev/null
+++ b/indra/newview/llpathfindinglinkset.h
@@ -0,0 +1,108 @@
+/**
+ * @file llpathfindinglinkset.h
+ * @author William Todd Stinson
+ * @brief Definition of a pathfinding linkset that contains various properties required for havok pathfinding.
+ *
+ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLPATHFINDINGLINKSET_H
+#define LL_LLPATHFINDINGLINKSET_H
+
+#include "v3math.h"
+#include "lluuid.h"
+
+// This is a reminder to remove the code regarding the changing of the data type for the
+// walkability coefficients from F32 to S32 representing the percentage from 0-100.
+#define XXX_STINSON_WALKABILITY_COEFFICIENTS_TYPE_CHANGE
+
+class LLSD;
+
+class LLPathfindingLinkset
+{
+public:
+ typedef enum
+ {
+ kWalkable,
+ kObstacle,
+ kIgnored
+ } EPathState;
+
+ LLPathfindingLinkset(const std::string &pUUID, const LLSD &pLinksetItem);
+ LLPathfindingLinkset(const LLPathfindingLinkset& pOther);
+ virtual ~LLPathfindingLinkset();
+
+ LLPathfindingLinkset& operator = (const LLPathfindingLinkset& pOther);
+
+ inline const LLUUID& getUUID() const {return mUUID;};
+ inline const std::string& getName() const {return mName;};
+ inline const std::string& getDescription() const {return mDescription;};
+ inline U32 getLandImpact() const {return mLandImpact;};
+ inline const LLVector3& getLocation() const {return mLocation;};
+
+ inline EPathState getPathState() const {return mPathState;};
+ inline void setPathState(EPathState pPathState) {mPathState = pPathState;};
+
+ static EPathState getPathState(bool pIsPermanent, bool pIsWalkable);
+ static BOOL isPermanent(EPathState pPathState);
+ static BOOL isWalkable(EPathState pPathState);
+
+ inline BOOL isPhantom() const {return mIsPhantom;};
+ inline void setPhantom(BOOL pIsPhantom) {mIsPhantom = pIsPhantom;};
+
+ inline S32 getWalkabilityCoefficientA() const {return mWalkabilityCoefficientA;};
+ void setWalkabilityCoefficientA(S32 pA);
+
+ inline S32 getWalkabilityCoefficientB() const {return mWalkabilityCoefficientB;};
+ void setWalkabilityCoefficientB(S32 pB);
+
+ inline S32 getWalkabilityCoefficientC() const {return mWalkabilityCoefficientC;};
+ void setWalkabilityCoefficientC(S32 pC);
+
+ inline S32 getWalkabilityCoefficientD() const {return mWalkabilityCoefficientD;};
+ void setWalkabilityCoefficientD(S32 pD);
+
+ LLSD encodeAlteredFields(EPathState pPathState, S32 pA, S32 pB, S32 pC, S32 pD, BOOL pIsPhantom) const;
+
+protected:
+
+private:
+ static const S32 MIN_WALKABILITY_VALUE;
+ static const S32 MAX_WALKABILITY_VALUE;
+
+ LLUUID mUUID;
+ std::string mName;
+ std::string mDescription;
+ U32 mLandImpact;
+ LLVector3 mLocation;
+ EPathState mPathState;
+ BOOL mIsPhantom;
+#ifdef XXX_STINSON_WALKABILITY_COEFFICIENTS_TYPE_CHANGE
+ BOOL mIsWalkabilityCoefficientsF32;
+#endif // XXX_STINSON_WALKABILITY_COEFFICIENTS_TYPE_CHANGE
+ S32 mWalkabilityCoefficientA;
+ S32 mWalkabilityCoefficientB;
+ S32 mWalkabilityCoefficientC;
+ S32 mWalkabilityCoefficientD;
+};
+
+#endif // LL_LLPATHFINDINGLINKSET_H
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index e8029293fc..3e21334cd4 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -885,7 +885,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
LLAppViewer::instance()->pingMainloopTimeout("Display:RenderGeom");
bool exclusiveDraw = false;
BOOL allowRenderables = false;
- BOOL allowPathToBeDrawn = false;
if (!(LLAppViewer::instance()->logoutRequestSent() && LLAppViewer::instance()->hasSavedFinalSnapshot())
&& !gRestoreGL)
{
@@ -899,38 +898,31 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
else
{
//Render any navmesh geometry
- if ( LLPathingLib::getInstance() )
+ LLPathingLib *llPathingLibInstance = LLPathingLib::getInstance();
+ if ( llPathingLibInstance != NULL )
{
//Determine if we can should overlay the navmesh ontop of the scenes typical renderables
- LLFloaterPathfindingConsole* pFloater = LLFloaterReg::getTypedInstance<LLFloaterPathfindingConsole>("pathfinding_console");
- if ( pFloater && pFloater->allowAllRenderables() )
- {
- allowRenderables = true;
- }
- //Determine if we should also draw a user supplied path on top of the scene
- if ( pFloater && pFloater->getShowPathToggle() )
- {
- allowPathToBeDrawn = true;
- }
+ allowRenderables = llPathingLibInstance->getRenderOverlayMode();
+
//NavMesh
- if ( LLPathingLib::getInstance()->getRenderNavMeshState() )
+ if ( llPathingLibInstance->getRenderNavMeshState() )
{
glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
glEnable(GL_DEPTH_TEST);
gGL.setAmbientLightColor( LLColor4::white );
- LLPathingLib::getInstance()->renderNavMesh( allowRenderables );
+ llPathingLibInstance->renderNavMesh();
exclusiveDraw = true;
}
//physics/exclusion shapes
- if ( LLPathingLib::getInstance()->getRenderShapeState() )
+ if ( llPathingLibInstance->getRenderShapesState() )
{
- LLPathingLib::getInstance()->renderNavMeshShapesVBO();
+ llPathingLibInstance->renderNavMeshShapesVBO();
exclusiveDraw = true;
}
//User designated path
- if ( allowPathToBeDrawn )
+ if ( llPathingLibInstance->getRenderPathState() )
{
- LLPathingLib::getInstance()->renderPath();
+ llPathingLibInstance->renderPath();
}
}
}
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 7f2aefcc2b..ab03463bbc 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -1984,33 +1984,42 @@ void LLViewerWindow::shutdownViews()
// clean up warning logger
LLError::removeRecorder(RecordToChatConsole::getInstance());
+ llinfos << "Warning logger is cleaned." << llendl ;
+
delete mDebugText;
mDebugText = NULL;
+ llinfos << "DebugText deleted." << llendl ;
+
// Cleanup global views
if (gMorphView)
{
gMorphView->setVisible(FALSE);
}
+ llinfos << "Global views cleaned." << llendl ;
// DEV-40930: Clear sModalStack. Otherwise, any LLModalDialog left open
// will crump with LL_ERRS.
LLModalDialog::shutdownModals();
-
+ llinfos << "LLModalDialog shut down." << llendl;
+
// destroy the nav bar, not currently part of gViewerWindow
// *TODO: Make LLNavigationBar part of gViewerWindow
if (LLNavigationBar::instanceExists())
{
delete LLNavigationBar::getInstance();
}
+ llinfos << "LLNavigationBar destroyed." << llendl ;
// destroy menus after instantiating navbar above, as it needs
// access to gMenuHolder
cleanup_menus();
+ llinfos << "menus destroyed." << llendl ;
// Delete all child views.
delete mRootView;
mRootView = NULL;
+ llinfos << "RootView deleted." << llendl ;
// Automatically deleted as children of mRootView. Fix the globals.
gStatusBar = NULL;
diff --git a/indra/newview/llxmlrpctransaction.cpp b/indra/newview/llxmlrpctransaction.cpp
index 920a9a3752..0da70d398b 100644
--- a/indra/newview/llxmlrpctransaction.cpp
+++ b/indra/newview/llxmlrpctransaction.cpp
@@ -305,6 +305,15 @@ void LLXMLRPCTransaction::Impl::init(XMLRPC_REQUEST request, bool useGzip)
{
mCurlRequest = new LLCurlEasyRequest();
}
+ if(!mCurlRequest->isValid())
+ {
+ llwarns << "mCurlRequest is invalid." << llendl ;
+
+ delete mCurlRequest ;
+ mCurlRequest = NULL ;
+ return ;
+ }
+
mErrorCert = NULL;
// mCurlRequest->setopt(CURLOPT_VERBOSE, 1); // useful for debugging
@@ -357,10 +366,20 @@ LLXMLRPCTransaction::Impl::~Impl()
}
delete mCurlRequest;
+ mCurlRequest = NULL ;
}
bool LLXMLRPCTransaction::Impl::process()
{
+ if(!mCurlRequest || !mCurlRequest->isValid())
+ {
+ llwarns << "transaction failed." << llendl ;
+
+ delete mCurlRequest ;
+ mCurlRequest = NULL ;
+ return true ; //failed, quit.
+ }
+
switch(mStatus)
{
case LLXMLRPCTransaction::StatusComplete:
diff --git a/indra/newview/skins/default/xui/en/floater_pathfinding_linksets.xml b/indra/newview/skins/default/xui/en/floater_pathfinding_linksets.xml
index e5d06481e5..65c0bf3cca 100644
--- a/indra/newview/skins/default/xui/en/floater_pathfinding_linksets.xml
+++ b/indra/newview/skins/default/xui/en/floater_pathfinding_linksets.xml
@@ -94,7 +94,7 @@
width="106" />
<check_box
height="19"
- initial_value="1"
+ initial_value="true"
label="Walkable"
layout="topleft"
left="481"
@@ -103,7 +103,7 @@
width="90" />
<check_box
height="19"
- initial_value="1"
+ initial_value="true"
label="Obstacle"
layout="topleft"
left="577"
@@ -112,7 +112,7 @@
width="90" />
<check_box
height="19"
- initial_value="1"
+ initial_value="true"
label="Ignored"
layout="topleft"
left="674"
diff --git a/indra/viewer_components/updater/llupdatedownloader.cpp b/indra/viewer_components/updater/llupdatedownloader.cpp
index e88d1bf811..19ac418e9e 100644
--- a/indra/viewer_components/updater/llupdatedownloader.cpp
+++ b/indra/viewer_components/updater/llupdatedownloader.cpp
@@ -39,7 +39,7 @@
#include "llsdserialize.h"
#include "llthread.h"
#include "llupdaterservice.h"
-
+#include "llcurl.h"
class LLUpdateDownloader::Implementation:
public LLThread
@@ -198,13 +198,19 @@ LLUpdateDownloader::Implementation::Implementation(LLUpdateDownloader::Client &
LLUpdateDownloader::Implementation::~Implementation()
{
- if(isDownloading()) {
+ if(isDownloading())
+ {
cancel();
shutdown();
- } else {
+ }
+ else
+ {
; // No op.
}
- if(mCurl) curl_easy_cleanup(mCurl);
+ if(mCurl)
+ {
+ LLCurl::deleteEasyHandle(mCurl);
+ }
}
@@ -406,9 +412,12 @@ void LLUpdateDownloader::Implementation::run(void)
void LLUpdateDownloader::Implementation::initializeCurlGet(std::string const & url, bool processHeader)
{
- if(mCurl == 0) {
- mCurl = curl_easy_init();
- } else {
+ if(mCurl == 0)
+ {
+ mCurl = LLCurl::newEasyHandle();
+ }
+ else
+ {
curl_easy_reset(mCurl);
}