207 lines
7.1 KiB
C++
Executable File
207 lines
7.1 KiB
C++
Executable File
/**
|
|
* @file LLAccountingQuotaManager.cpp
|
|
* @ Handles the setting and accessing for costs associated with mesh
|
|
*
|
|
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
|
|
* Second Life Viewer Source Code
|
|
* Copyright (C) 2011, Linden Research, Inc.
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation;
|
|
* version 2.1 of the License only.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*
|
|
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
|
* $/LicenseInfo$
|
|
*/
|
|
|
|
#include "llviewerprecompiledheaders.h"
|
|
#include "llaccountingcostmanager.h"
|
|
#include "llagent.h"
|
|
#include "httpcommon.h"
|
|
#include "llcoros.h"
|
|
#include "lleventcoro.h"
|
|
#include "llcorehttputil.h"
|
|
|
|
//===============================================================================
|
|
LLAccountingCostManager::LLAccountingCostManager():
|
|
mHttpRequest(),
|
|
mHttpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID)
|
|
{
|
|
mHttpRequest = LLCore::HttpRequest::ptr_t(new LLCore::HttpRequest());
|
|
//mHttpPolicy = LLCore::HttpRequest::DEFAULT_POLICY_ID;
|
|
|
|
}
|
|
|
|
// Coroutine for sending and processing avatar name cache requests.
|
|
// Do not call directly. See documentation in lleventcoro.h and llcoro.h for
|
|
// further explanation.
|
|
void LLAccountingCostManager::accountingCostCoro(LLCoros::self& self, std::string url,
|
|
eSelectionType selectionType, const LLHandle<LLAccountingCostObserver> observerHandle)
|
|
{
|
|
LL_DEBUGS("LLAccountingCostManager") << "Entering coroutine " << LLCoros::instance().getName(self)
|
|
<< " with url '" << url << LL_ENDL;
|
|
|
|
try
|
|
{
|
|
LLSD objectList;
|
|
U32 objectIndex = 0;
|
|
|
|
IDIt IDIter = mObjectList.begin();
|
|
IDIt IDIterEnd = mObjectList.end();
|
|
|
|
for (; IDIter != IDIterEnd; ++IDIter)
|
|
{
|
|
// Check to see if a request for this object has already been made.
|
|
if (mPendingObjectQuota.find(*IDIter) == mPendingObjectQuota.end())
|
|
{
|
|
mPendingObjectQuota.insert(*IDIter);
|
|
objectList[objectIndex++] = *IDIter;
|
|
}
|
|
}
|
|
|
|
mObjectList.clear();
|
|
|
|
//Post results
|
|
if (objectList.size() == 0)
|
|
return;
|
|
|
|
std::string keystr;
|
|
if (selectionType == Roots)
|
|
{
|
|
keystr = "selected_roots";
|
|
}
|
|
else if (selectionType == Prims)
|
|
{
|
|
keystr = "selected_prims";
|
|
}
|
|
else
|
|
{
|
|
LL_INFOS() << "Invalid selection type " << LL_ENDL;
|
|
mObjectList.clear();
|
|
mPendingObjectQuota.clear();
|
|
return;
|
|
}
|
|
|
|
LLSD dataToPost = LLSD::emptyMap();
|
|
dataToPost[keystr.c_str()] = objectList;
|
|
|
|
LLAccountingCostObserver* observer = observerHandle.get();
|
|
LLUUID transactionId = observer->getTransactionID();
|
|
observer = NULL;
|
|
|
|
LLCoreHttpUtil::HttpCoroutineAdapter httpAdapter("AccountingCost", mHttpPolicy);
|
|
|
|
LLSD results = httpAdapter.postAndYield(self, mHttpRequest, url, dataToPost);
|
|
|
|
LLSD httpResults;
|
|
httpResults = results["http_result"];
|
|
|
|
// do/while(false) allows error conditions to break out of following
|
|
// block while normal flow goes forward once.
|
|
do
|
|
{
|
|
observer = observerHandle.get();
|
|
if ((!observer) || (observer->getTransactionID() != transactionId))
|
|
{ // *TODO: Rider: I've noticed that getTransactionID() does not
|
|
// always match transactionId (the new transaction Id does not show a
|
|
// corresponding request.) (ask Vir)
|
|
if (!observer)
|
|
break;
|
|
LL_WARNS() << "Request transaction Id(" << transactionId
|
|
<< ") does not match observer's transaction Id("
|
|
<< observer->getTransactionID() << ")." << LL_ENDL;
|
|
break;
|
|
}
|
|
|
|
if (!httpResults["success"].asBoolean())
|
|
{
|
|
LL_WARNS() << "Error result from LLCoreHttpUtil::HttpCoroHandler. Code "
|
|
<< httpResults["status"] << ": '" << httpResults["message"] << "'" << LL_ENDL;
|
|
if (observer)
|
|
{
|
|
observer->setErrorStatus(httpResults["status"].asInteger(), httpResults["message"].asStringRef());
|
|
}
|
|
break;
|
|
}
|
|
|
|
if (!results.isMap() || results.has("error"))
|
|
{
|
|
LL_WARNS() << "Error on fetched data" << LL_ENDL;
|
|
observer->setErrorStatus(499, "Error on fetched data");
|
|
break;
|
|
}
|
|
|
|
if (results.has("selected"))
|
|
{
|
|
F32 physicsCost = 0.0f;
|
|
F32 networkCost = 0.0f;
|
|
F32 simulationCost = 0.0f;
|
|
|
|
physicsCost = results["selected"]["physics"].asReal();
|
|
networkCost = results["selected"]["streaming"].asReal();
|
|
simulationCost = results["selected"]["simulation"].asReal();
|
|
|
|
SelectionCost selectionCost( physicsCost, networkCost, simulationCost);
|
|
|
|
observer->onWeightsUpdate(selectionCost);
|
|
}
|
|
|
|
} while (false);
|
|
|
|
}
|
|
catch (std::exception e)
|
|
{
|
|
LL_WARNS() << "Caught exception '" << e.what() << "'" << LL_ENDL;
|
|
}
|
|
catch (...)
|
|
{
|
|
LL_WARNS() << "Caught unknown exception." << LL_ENDL;
|
|
}
|
|
|
|
mPendingObjectQuota.clear();
|
|
}
|
|
|
|
//===============================================================================
|
|
void LLAccountingCostManager::fetchCosts( eSelectionType selectionType,
|
|
const std::string& url,
|
|
const LLHandle<LLAccountingCostObserver>& observer_handle )
|
|
{
|
|
// Invoking system must have already determined capability availability
|
|
if ( !url.empty() )
|
|
{
|
|
std::string coroname =
|
|
LLCoros::instance().launch("LLAccountingCostManager::accountingCostCoro",
|
|
boost::bind(&LLAccountingCostManager::accountingCostCoro, this, _1, url, selectionType, observer_handle));
|
|
LL_DEBUGS() << coroname << " with url '" << url << LL_ENDL;
|
|
|
|
}
|
|
else
|
|
{
|
|
//url was empty - warn & continue
|
|
LL_WARNS()<<"Supplied url is empty "<<LL_ENDL;
|
|
mObjectList.clear();
|
|
mPendingObjectQuota.clear();
|
|
}
|
|
}
|
|
//===============================================================================
|
|
void LLAccountingCostManager::addObject( const LLUUID& objectID )
|
|
{
|
|
mObjectList.insert( objectID );
|
|
}
|
|
//===============================================================================
|
|
void LLAccountingCostManager::removePendingObject( const LLUUID& objectID )
|
|
{
|
|
mPendingObjectQuota.erase( objectID );
|
|
}
|
|
//===============================================================================
|