diff options
Diffstat (limited to 'indra/newview/llpathfindingmanager.cpp')
| -rw-r--r-- | indra/newview/llpathfindingmanager.cpp | 1836 |
1 files changed, 918 insertions, 918 deletions
diff --git a/indra/newview/llpathfindingmanager.cpp b/indra/newview/llpathfindingmanager.cpp index dc1c749126..ed141d3920 100644 --- a/indra/newview/llpathfindingmanager.cpp +++ b/indra/newview/llpathfindingmanager.cpp @@ -1,918 +1,918 @@ -/** -* @file llpathfindingmanager.cpp -* @brief Implementation of llpathfindingmanager -* @author Stinson@lindenlab.com -* -* $LicenseInfo:firstyear=2012&license=viewerlgpl$ -* Second Life Viewer Source Code -* Copyright (C) 2012, Linden Research, Inc. -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation; -* version 2.1 of the License only. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -* Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General Public -* License along with this library; if not, write to the Free Software -* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -* -* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA -* $/LicenseInfo$ -*/ - - -#include "llviewerprecompiledheaders.h" - -#include "llpathfindingmanager.h" - -#include <string> -#include <map> - -#include <boost/bind.hpp> -#include <boost/function.hpp> -#include <boost/shared_ptr.hpp> -#include <boost/signals2.hpp> - -#include "llagent.h" -#include "llhttpnode.h" -#include "llnotificationsutil.h" -#include "llpathfindingcharacterlist.h" -#include "llpathfindinglinkset.h" -#include "llpathfindinglinksetlist.h" -#include "llpathfindingnavmesh.h" -#include "llpathfindingnavmeshstatus.h" -#include "llpathfindingobject.h" -#include "llpathinglib.h" -#include "llsingleton.h" -#include "llsd.h" -#include "lltrans.h" -#include "lluuid.h" -#include "llviewerregion.h" -#include "llweb.h" -#include "llcorehttputil.h" -#include "llworld.h" - -#define CAP_SERVICE_RETRIEVE_NAVMESH "RetrieveNavMeshSrc" - -#define CAP_SERVICE_NAVMESH_STATUS "NavMeshGenerationStatus" - -#define CAP_SERVICE_GET_OBJECT_LINKSETS "RegionObjects" -#define CAP_SERVICE_SET_OBJECT_LINKSETS "ObjectNavMeshProperties" -#define CAP_SERVICE_TERRAIN_LINKSETS "TerrainNavMeshProperties" - -#define CAP_SERVICE_CHARACTERS "CharacterProperties" - -#define SIM_MESSAGE_NAVMESH_STATUS_UPDATE "/message/NavMeshStatusUpdate" -#define SIM_MESSAGE_AGENT_STATE_UPDATE "/message/AgentStateUpdate" -#define SIM_MESSAGE_BODY_FIELD "body" - -#define CAP_SERVICE_AGENT_STATE "AgentState" - -#define AGENT_STATE_CAN_REBAKE_REGION_FIELD "can_modify_navmesh" - -//--------------------------------------------------------------------------- -// LLNavMeshSimStateChangeNode -//--------------------------------------------------------------------------- - -class LLNavMeshSimStateChangeNode : public LLHTTPNode -{ -public: - virtual void post(ResponsePtr pResponse, const LLSD &pContext, const LLSD &pInput) const; -}; - -LLHTTPRegistration<LLNavMeshSimStateChangeNode> gHTTPRegistrationNavMeshSimStateChangeNode(SIM_MESSAGE_NAVMESH_STATUS_UPDATE); - - -//--------------------------------------------------------------------------- -// LLAgentStateChangeNode -//--------------------------------------------------------------------------- -class LLAgentStateChangeNode : public LLHTTPNode -{ -public: - virtual void post(ResponsePtr pResponse, const LLSD &pContext, const LLSD &pInput) const; -}; - -LLHTTPRegistration<LLAgentStateChangeNode> gHTTPRegistrationAgentStateChangeNode(SIM_MESSAGE_AGENT_STATE_UPDATE); - -//--------------------------------------------------------------------------- -// LinksetsResponder -//--------------------------------------------------------------------------- - -class LinksetsResponder -{ -public: - LinksetsResponder(LLPathfindingManager::request_id_t pRequestId, LLPathfindingManager::object_request_callback_t pLinksetsCallback, bool pIsObjectRequested, bool pIsTerrainRequested); - virtual ~LinksetsResponder(); - - void handleObjectLinksetsResult(const LLSD &pContent); - void handleObjectLinksetsError(); - void handleTerrainLinksetsResult(const LLSD &pContent); - void handleTerrainLinksetsError(); - - typedef std::shared_ptr<LinksetsResponder> ptr_t; - -protected: - -private: - void sendCallback(); - - typedef enum - { - kNotRequested, - kWaiting, - kReceivedGood, - kReceivedError - } EMessagingState; - - LLPathfindingManager::request_id_t mRequestId; - LLPathfindingManager::object_request_callback_t mLinksetsCallback; - - EMessagingState mObjectMessagingState; - EMessagingState mTerrainMessagingState; - - LLPathfindingObjectListPtr mObjectLinksetListPtr; - LLPathfindingObjectPtr mTerrainLinksetPtr; -}; - -typedef std::shared_ptr<LinksetsResponder> LinksetsResponderPtr; - -//--------------------------------------------------------------------------- -// LLPathfindingManager -//--------------------------------------------------------------------------- - -LLPathfindingManager::LLPathfindingManager(): - mNavMeshMap(), - mAgentStateSignal() -{ -} - -LLPathfindingManager::~LLPathfindingManager() -{ - quitSystem(); -} - -void LLPathfindingManager::initSystem() -{ - if (LLPathingLib::getInstance() == NULL) - { - LLPathingLib::initSystem(); - } -} - -void LLPathfindingManager::quitSystem() -{ - if (LLPathingLib::getInstance() != NULL) - { - LLPathingLib::quitSystem(); - } -} - -bool LLPathfindingManager::isPathfindingViewEnabled() const -{ - return (LLPathingLib::getInstance() != NULL); -} - -bool LLPathfindingManager::isPathfindingEnabledForCurrentRegion() const -{ - return isPathfindingEnabledForRegion(getCurrentRegion()); -} - -bool LLPathfindingManager::isPathfindingEnabledForRegion(LLViewerRegion *pRegion) const -{ - std::string retrieveNavMeshURL = getRetrieveNavMeshURLForRegion(pRegion); - return !retrieveNavMeshURL.empty(); -} - -bool LLPathfindingManager::isAllowViewTerrainProperties() const -{ - LLViewerRegion* region = getCurrentRegion(); - return (gAgent.isGodlike() || ((region != NULL) && region->canManageEstate())); -} - -LLPathfindingNavMesh::navmesh_slot_t LLPathfindingManager::registerNavMeshListenerForRegion(LLViewerRegion *pRegion, LLPathfindingNavMesh::navmesh_callback_t pNavMeshCallback) -{ - LLPathfindingNavMeshPtr navMeshPtr = getNavMeshForRegion(pRegion); - return navMeshPtr->registerNavMeshListener(pNavMeshCallback); -} - -void LLPathfindingManager::requestGetNavMeshForRegion(LLViewerRegion *pRegion, bool pIsGetStatusOnly) -{ - LLPathfindingNavMeshPtr navMeshPtr = getNavMeshForRegion(pRegion); - - if (pRegion == NULL) - { - navMeshPtr->handleNavMeshNotEnabled(); - } - else if (!pRegion->capabilitiesReceived()) - { - navMeshPtr->handleNavMeshWaitForRegionLoad(); - pRegion->setCapabilitiesReceivedCallback(boost::bind(&LLPathfindingManager::handleDeferredGetNavMeshForRegion, this, _1, pIsGetStatusOnly)); - } - else if (!isPathfindingEnabledForRegion(pRegion)) - { - navMeshPtr->handleNavMeshNotEnabled(); - } - else - { - std::string navMeshStatusURL = getNavMeshStatusURLForRegion(pRegion); - llassert(!navMeshStatusURL.empty()); - navMeshPtr->handleNavMeshCheckVersion(); - - U64 regionHandle = pRegion->getHandle(); - std::string coroname = LLCoros::instance().launch("LLPathfindingManager::navMeshStatusRequestCoro", - boost::bind(&LLPathfindingManager::navMeshStatusRequestCoro, this, navMeshStatusURL, regionHandle, pIsGetStatusOnly)); - } -} - -void LLPathfindingManager::requestGetLinksets(request_id_t pRequestId, object_request_callback_t pLinksetsCallback) const -{ - LLPathfindingObjectListPtr emptyLinksetListPtr; - LLViewerRegion *currentRegion = getCurrentRegion(); - - if (currentRegion == NULL) - { - pLinksetsCallback(pRequestId, kRequestNotEnabled, emptyLinksetListPtr); - } - else if (!currentRegion->capabilitiesReceived()) - { - pLinksetsCallback(pRequestId, kRequestStarted, emptyLinksetListPtr); - currentRegion->setCapabilitiesReceivedCallback(boost::bind(&LLPathfindingManager::handleDeferredGetLinksetsForRegion, this, _1, pRequestId, pLinksetsCallback)); - } - else - { - std::string objectLinksetsURL = getRetrieveObjectLinksetsURLForCurrentRegion(); - std::string terrainLinksetsURL = getTerrainLinksetsURLForCurrentRegion(); - if (objectLinksetsURL.empty() || terrainLinksetsURL.empty()) - { - pLinksetsCallback(pRequestId, kRequestNotEnabled, emptyLinksetListPtr); - } - else - { - pLinksetsCallback(pRequestId, kRequestStarted, emptyLinksetListPtr); - - bool doRequestTerrain = isAllowViewTerrainProperties(); - LinksetsResponder::ptr_t linksetsResponderPtr(new LinksetsResponder(pRequestId, pLinksetsCallback, true, doRequestTerrain)); - - std::string coroname = LLCoros::instance().launch("LLPathfindingManager::linksetObjectsCoro", - boost::bind(&LLPathfindingManager::linksetObjectsCoro, this, objectLinksetsURL, linksetsResponderPtr, LLSD())); - - if (doRequestTerrain) - { - std::string coroname = LLCoros::instance().launch("LLPathfindingManager::linksetTerrainCoro", - boost::bind(&LLPathfindingManager::linksetTerrainCoro, this, terrainLinksetsURL, linksetsResponderPtr, LLSD())); - } - } - } -} - -void LLPathfindingManager::requestSetLinksets(request_id_t pRequestId, const LLPathfindingObjectListPtr &pLinksetListPtr, LLPathfindingLinkset::ELinksetUse pLinksetUse, S32 pA, S32 pB, S32 pC, S32 pD, object_request_callback_t pLinksetsCallback) const -{ - LLPathfindingObjectListPtr emptyLinksetListPtr; - - std::string objectLinksetsURL = getChangeObjectLinksetsURLForCurrentRegion(); - std::string terrainLinksetsURL = getTerrainLinksetsURLForCurrentRegion(); - if (objectLinksetsURL.empty() || terrainLinksetsURL.empty()) - { - pLinksetsCallback(pRequestId, kRequestNotEnabled, emptyLinksetListPtr); - } - else if ((pLinksetListPtr == NULL) || pLinksetListPtr->isEmpty()) - { - pLinksetsCallback(pRequestId, kRequestCompleted, emptyLinksetListPtr); - } - else - { - const LLPathfindingLinksetList *linksetList = dynamic_cast<const LLPathfindingLinksetList *>(pLinksetListPtr.get()); - - LLSD objectPostData = linksetList->encodeObjectFields(pLinksetUse, pA, pB, pC, pD); - LLSD terrainPostData; - if (isAllowViewTerrainProperties()) - { - terrainPostData = linksetList->encodeTerrainFields(pLinksetUse, pA, pB, pC, pD); - } - - if (objectPostData.isUndefined() && terrainPostData.isUndefined()) - { - pLinksetsCallback(pRequestId, kRequestCompleted, emptyLinksetListPtr); - } - else - { - pLinksetsCallback(pRequestId, kRequestStarted, emptyLinksetListPtr); - - LinksetsResponder::ptr_t linksetsResponderPtr(new LinksetsResponder(pRequestId, pLinksetsCallback, !objectPostData.isUndefined(), !terrainPostData.isUndefined())); - - if (!objectPostData.isUndefined()) - { - std::string coroname = LLCoros::instance().launch("LLPathfindingManager::linksetObjectsCoro", - boost::bind(&LLPathfindingManager::linksetObjectsCoro, this, objectLinksetsURL, linksetsResponderPtr, objectPostData)); - } - - if (!terrainPostData.isUndefined()) - { - std::string coroname = LLCoros::instance().launch("LLPathfindingManager::linksetTerrainCoro", - boost::bind(&LLPathfindingManager::linksetTerrainCoro, this, terrainLinksetsURL, linksetsResponderPtr, terrainPostData)); - } - } - } -} - -void LLPathfindingManager::requestGetCharacters(request_id_t pRequestId, object_request_callback_t pCharactersCallback) const -{ - LLPathfindingObjectListPtr emptyCharacterListPtr; - - LLViewerRegion *currentRegion = getCurrentRegion(); - - if (currentRegion == NULL) - { - pCharactersCallback(pRequestId, kRequestNotEnabled, emptyCharacterListPtr); - } - else if (!currentRegion->capabilitiesReceived()) - { - pCharactersCallback(pRequestId, kRequestStarted, emptyCharacterListPtr); - currentRegion->setCapabilitiesReceivedCallback(boost::bind(&LLPathfindingManager::handleDeferredGetCharactersForRegion, this, _1, pRequestId, pCharactersCallback)); - } - else - { - std::string charactersURL = getCharactersURLForCurrentRegion(); - if (charactersURL.empty()) - { - pCharactersCallback(pRequestId, kRequestNotEnabled, emptyCharacterListPtr); - } - else - { - pCharactersCallback(pRequestId, kRequestStarted, emptyCharacterListPtr); - - std::string coroname = LLCoros::instance().launch("LLPathfindingManager::charactersCoro", - boost::bind(&LLPathfindingManager::charactersCoro, this, charactersURL, pRequestId, pCharactersCallback)); - } - } -} - -LLPathfindingManager::agent_state_slot_t LLPathfindingManager::registerAgentStateListener(agent_state_callback_t pAgentStateCallback) -{ - return mAgentStateSignal.connect(pAgentStateCallback); -} - -void LLPathfindingManager::requestGetAgentState() -{ - LLViewerRegion *currentRegion = getCurrentRegion(); - - if (currentRegion == NULL) - { - mAgentStateSignal(false); - } - else - { - if (!currentRegion->capabilitiesReceived()) - { - currentRegion->setCapabilitiesReceivedCallback(boost::bind(&LLPathfindingManager::handleDeferredGetAgentStateForRegion, this, _1)); - } - else if (!isPathfindingEnabledForRegion(currentRegion)) - { - mAgentStateSignal(false); - } - else - { - std::string agentStateURL = getAgentStateURLForRegion(currentRegion); - llassert(!agentStateURL.empty()); - - std::string coroname = LLCoros::instance().launch("LLPathfindingManager::navAgentStateRequestCoro", - boost::bind(&LLPathfindingManager::navAgentStateRequestCoro, this, agentStateURL)); - } - } -} - -void LLPathfindingManager::requestRebakeNavMesh(rebake_navmesh_callback_t pRebakeNavMeshCallback) -{ - LLViewerRegion *currentRegion = getCurrentRegion(); - - if (currentRegion == NULL) - { - pRebakeNavMeshCallback(false); - } - else if (!isPathfindingEnabledForRegion(currentRegion)) - { - pRebakeNavMeshCallback(false); - } - else - { - std::string navMeshStatusURL = getNavMeshStatusURLForCurrentRegion(); - llassert(!navMeshStatusURL.empty()); - - std::string coroname = LLCoros::instance().launch("LLPathfindingManager::navMeshRebakeCoro", - boost::bind(&LLPathfindingManager::navMeshRebakeCoro, this, navMeshStatusURL, pRebakeNavMeshCallback)); - } -} - -void LLPathfindingManager::handleDeferredGetAgentStateForRegion(const LLUUID &pRegionUUID) -{ - LLViewerRegion *currentRegion = getCurrentRegion(); - - if ((currentRegion != NULL) && (currentRegion->getRegionID() == pRegionUUID)) - { - requestGetAgentState(); - } -} - -void LLPathfindingManager::handleDeferredGetNavMeshForRegion(const LLUUID &pRegionUUID, bool pIsGetStatusOnly) -{ - LLViewerRegion *currentRegion = getCurrentRegion(); - - if ((currentRegion != NULL) && (currentRegion->getRegionID() == pRegionUUID)) - { - requestGetNavMeshForRegion(currentRegion, pIsGetStatusOnly); - } -} - -void LLPathfindingManager::handleDeferredGetLinksetsForRegion(const LLUUID &pRegionUUID, request_id_t pRequestId, object_request_callback_t pLinksetsCallback) const -{ - LLViewerRegion *currentRegion = getCurrentRegion(); - - if ((currentRegion != NULL) && (currentRegion->getRegionID() == pRegionUUID)) - { - requestGetLinksets(pRequestId, pLinksetsCallback); - } -} - -void LLPathfindingManager::handleDeferredGetCharactersForRegion(const LLUUID &pRegionUUID, request_id_t pRequestId, object_request_callback_t pCharactersCallback) const -{ - LLViewerRegion *currentRegion = getCurrentRegion(); - - if ((currentRegion != NULL) && (currentRegion->getRegionID() == pRegionUUID)) - { - requestGetCharacters(pRequestId, pCharactersCallback); - } -} - -void LLPathfindingManager::navMeshStatusRequestCoro(std::string url, U64 regionHandle, bool isGetStatusOnly) -{ - LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); - LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t - httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("NavMeshStatusRequest", httpPolicy)); - LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); - - LLViewerRegion *region = LLWorld::getInstance()->getRegionFromHandle(regionHandle); - if (!region) - { - LL_WARNS("PathfindingManager") << "Attempting to retrieve navmesh status for region that has gone away." << LL_ENDL; - return; - } - LLUUID regionUUID = region->getRegionID(); - - region = NULL; - LLSD result = httpAdapter->getAndSuspend(httpRequest, url); - - region = LLWorld::getInstance()->getRegionFromHandle(regionHandle); - - LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; - LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); - - LLPathfindingNavMeshStatus navMeshStatus(regionUUID); - if (!status) - { - LL_WARNS("PathfindingManager") << "HTTP status, " << status.toTerseString() << - ". Building using empty status." << LL_ENDL; - } - else - { - result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS); - navMeshStatus = LLPathfindingNavMeshStatus(regionUUID, result); - } - - LLPathfindingNavMeshPtr navMeshPtr = getNavMeshForRegion(regionUUID); - - if (!navMeshStatus.isValid()) - { - navMeshPtr->handleNavMeshError(); - return; - } - else if (navMeshPtr->hasNavMeshVersion(navMeshStatus)) - { - navMeshPtr->handleRefresh(navMeshStatus); - return; - } - else if (isGetStatusOnly) - { - navMeshPtr->handleNavMeshNewVersion(navMeshStatus); - return; - } - - if ((!region) || !region->isAlive()) - { - LL_WARNS("PathfindingManager") << "About to update navmesh status for region that has gone away." << LL_ENDL; - navMeshPtr->handleNavMeshNotEnabled(); - return; - } - - std::string navMeshURL = getRetrieveNavMeshURLForRegion(region); - - if (navMeshURL.empty()) - { - navMeshPtr->handleNavMeshNotEnabled(); - return; - } - - navMeshPtr->handleNavMeshStart(navMeshStatus); - - LLSD postData; - result = httpAdapter->postAndSuspend(httpRequest, navMeshURL, postData); - - U32 navMeshVersion = navMeshStatus.getVersion(); - - if (!status) - { - LL_WARNS("PathfindingManager") << "HTTP status, " << status.toTerseString() << - ". reporting error." << LL_ENDL; - navMeshPtr->handleNavMeshError(navMeshVersion); - } - else - { - result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS); - navMeshPtr->handleNavMeshResult(result, navMeshVersion); - - } - -} - -void LLPathfindingManager::navAgentStateRequestCoro(std::string url) -{ - LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); - LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t - httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("NavAgentStateRequest", httpPolicy)); - LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); - - LLSD result = httpAdapter->getAndSuspend(httpRequest, url); - - LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; - LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); - - bool canRebake = false; - if (!status) - { - LL_WARNS("PathfindingManager") << "HTTP status, " << status.toTerseString() << - ". Building using empty status." << LL_ENDL; - } - else - { - llassert(result.has(AGENT_STATE_CAN_REBAKE_REGION_FIELD)); - llassert(result.get(AGENT_STATE_CAN_REBAKE_REGION_FIELD).isBoolean()); - canRebake = result.get(AGENT_STATE_CAN_REBAKE_REGION_FIELD).asBoolean(); - } - - handleAgentState(canRebake); -} - -void LLPathfindingManager::navMeshRebakeCoro(std::string url, rebake_navmesh_callback_t rebakeNavMeshCallback) -{ - LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); - LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t - httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("NavMeshRebake", httpPolicy)); - LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); - - - LLSD postData = LLSD::emptyMap(); - postData["command"] = "rebuild"; - - LLSD result = httpAdapter->postAndSuspend(httpRequest, url, postData); - - LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; - LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); - - bool success = true; - if (!status) - { - LL_WARNS("PathfindingManager") << "HTTP status, " << status.toTerseString() << - ". Rebake failed." << LL_ENDL; - success = false; - } - - rebakeNavMeshCallback(success); -} - -// If called with putData undefined this coroutine will issue a get. If there -// is data in putData it will be PUT to the URL. -void LLPathfindingManager::linksetObjectsCoro(std::string url, LinksetsResponder::ptr_t linksetsResponsderPtr, LLSD putData) const -{ - LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); - LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t - httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("LinksetObjects", httpPolicy)); - LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); - - LLSD result; - - if (putData.isUndefined()) - { - result = httpAdapter->getAndSuspend(httpRequest, url); - } - else - { - result = httpAdapter->putAndSuspend(httpRequest, url, putData); - } - - LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; - LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); - - if (!status) - { - LL_WARNS("PathfindingManager") << "HTTP status, " << status.toTerseString() << - ". linksetObjects failed." << LL_ENDL; - linksetsResponsderPtr->handleObjectLinksetsError(); - } - else - { - result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS); - linksetsResponsderPtr->handleObjectLinksetsResult(result); - } -} - -// If called with putData undefined this coroutine will issue a GET. If there -// is data in putData it will be PUT to the URL. -void LLPathfindingManager::linksetTerrainCoro(std::string url, LinksetsResponder::ptr_t linksetsResponsderPtr, LLSD putData) const -{ - LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); - LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t - httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("LinksetTerrain", httpPolicy)); - LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); - - LLSD result; - - if (putData.isUndefined()) - { - result = httpAdapter->getAndSuspend(httpRequest, url); - } - else - { - result = httpAdapter->putAndSuspend(httpRequest, url, putData); - } - - LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; - LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); - - if (!status) - { - LL_WARNS("PathfindingManager") << "HTTP status, " << status.toTerseString() << - ". linksetTerrain failed." << LL_ENDL; - linksetsResponsderPtr->handleTerrainLinksetsError(); - } - else - { - result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS); - linksetsResponsderPtr->handleTerrainLinksetsResult(result); - } - -} - -void LLPathfindingManager::charactersCoro(std::string url, request_id_t requestId, object_request_callback_t callback) const -{ - LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); - LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t - httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("LinksetTerrain", httpPolicy)); - LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); - - LLSD result = httpAdapter->getAndSuspend(httpRequest, url); - - LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; - LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); - - if (!status) - { - LL_WARNS("PathfindingManager") << "HTTP status, " << status.toTerseString() << - ". characters failed." << LL_ENDL; - - LLPathfindingObjectListPtr characterListPtr = LLPathfindingObjectListPtr(new LLPathfindingCharacterList()); - callback(requestId, LLPathfindingManager::kRequestError, characterListPtr); - } - else - { - result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS); - LLPathfindingObjectListPtr characterListPtr = LLPathfindingObjectListPtr(new LLPathfindingCharacterList(result)); - callback(requestId, LLPathfindingManager::kRequestCompleted, characterListPtr); - } -} - -void LLPathfindingManager::handleNavMeshStatusUpdate(const LLPathfindingNavMeshStatus &pNavMeshStatus) -{ - LLPathfindingNavMeshPtr navMeshPtr = getNavMeshForRegion(pNavMeshStatus.getRegionUUID()); - - if (!pNavMeshStatus.isValid()) - { - navMeshPtr->handleNavMeshError(); - } - else - { - navMeshPtr->handleNavMeshNewVersion(pNavMeshStatus); - } -} - -void LLPathfindingManager::handleAgentState(bool pCanRebakeRegion) -{ - mAgentStateSignal(pCanRebakeRegion); -} - -LLPathfindingNavMeshPtr LLPathfindingManager::getNavMeshForRegion(const LLUUID &pRegionUUID) -{ - LLPathfindingNavMeshPtr navMeshPtr; - NavMeshMap::iterator navMeshIter = mNavMeshMap.find(pRegionUUID); - if (navMeshIter == mNavMeshMap.end()) - { - navMeshPtr = LLPathfindingNavMeshPtr(new LLPathfindingNavMesh(pRegionUUID)); - mNavMeshMap.insert(std::pair<LLUUID, LLPathfindingNavMeshPtr>(pRegionUUID, navMeshPtr)); - } - else - { - navMeshPtr = navMeshIter->second; - } - - return navMeshPtr; -} - -LLPathfindingNavMeshPtr LLPathfindingManager::getNavMeshForRegion(LLViewerRegion *pRegion) -{ - LLUUID regionUUID; - if (pRegion != NULL) - { - regionUUID = pRegion->getRegionID(); - } - - return getNavMeshForRegion(regionUUID); -} - -std::string LLPathfindingManager::getNavMeshStatusURLForCurrentRegion() const -{ - return getNavMeshStatusURLForRegion(getCurrentRegion()); -} - -std::string LLPathfindingManager::getNavMeshStatusURLForRegion(LLViewerRegion *pRegion) const -{ - return getCapabilityURLForRegion(pRegion, CAP_SERVICE_NAVMESH_STATUS); -} - -std::string LLPathfindingManager::getRetrieveNavMeshURLForRegion(LLViewerRegion *pRegion) const -{ - return getCapabilityURLForRegion(pRegion, CAP_SERVICE_RETRIEVE_NAVMESH); -} - -std::string LLPathfindingManager::getRetrieveObjectLinksetsURLForCurrentRegion() const -{ - return getCapabilityURLForCurrentRegion(CAP_SERVICE_GET_OBJECT_LINKSETS); -} - -std::string LLPathfindingManager::getChangeObjectLinksetsURLForCurrentRegion() const -{ - return getCapabilityURLForCurrentRegion(CAP_SERVICE_SET_OBJECT_LINKSETS); -} - -std::string LLPathfindingManager::getTerrainLinksetsURLForCurrentRegion() const -{ - return getCapabilityURLForCurrentRegion(CAP_SERVICE_TERRAIN_LINKSETS); -} - -std::string LLPathfindingManager::getCharactersURLForCurrentRegion() const -{ - return getCapabilityURLForCurrentRegion(CAP_SERVICE_CHARACTERS); -} - -std::string LLPathfindingManager::getAgentStateURLForRegion(LLViewerRegion *pRegion) const -{ - return getCapabilityURLForRegion(pRegion, CAP_SERVICE_AGENT_STATE); -} - -std::string LLPathfindingManager::getCapabilityURLForCurrentRegion(const std::string &pCapabilityName) const -{ - return getCapabilityURLForRegion(getCurrentRegion(), pCapabilityName); -} - -std::string LLPathfindingManager::getCapabilityURLForRegion(LLViewerRegion *pRegion, const std::string &pCapabilityName) const -{ - std::string capabilityURL(""); - - if (pRegion != NULL) - { - capabilityURL = pRegion->getCapability(pCapabilityName); - } - - if (capabilityURL.empty()) - { - LL_WARNS() << "cannot find capability '" << pCapabilityName << "' for current region '" - << ((pRegion != NULL) ? pRegion->getName() : "<null>") << "'" << LL_ENDL; - } - - return capabilityURL; -} - -LLViewerRegion *LLPathfindingManager::getCurrentRegion() const -{ - return gAgent.getRegion(); -} - -//--------------------------------------------------------------------------- -// LLNavMeshSimStateChangeNode -//--------------------------------------------------------------------------- - -void LLNavMeshSimStateChangeNode::post(ResponsePtr pResponse, const LLSD &pContext, const LLSD &pInput) const -{ - llassert(pInput.has(SIM_MESSAGE_BODY_FIELD)); - llassert(pInput.get(SIM_MESSAGE_BODY_FIELD).isMap()); - LLPathfindingNavMeshStatus navMeshStatus(pInput.get(SIM_MESSAGE_BODY_FIELD)); - LLPathfindingManager::getInstance()->handleNavMeshStatusUpdate(navMeshStatus); -} - -//--------------------------------------------------------------------------- -// LLAgentStateChangeNode -//--------------------------------------------------------------------------- - -void LLAgentStateChangeNode::post(ResponsePtr pResponse, const LLSD &pContext, const LLSD &pInput) const -{ - llassert(pInput.has(SIM_MESSAGE_BODY_FIELD)); - llassert(pInput.get(SIM_MESSAGE_BODY_FIELD).isMap()); - llassert(pInput.get(SIM_MESSAGE_BODY_FIELD).has(AGENT_STATE_CAN_REBAKE_REGION_FIELD)); - llassert(pInput.get(SIM_MESSAGE_BODY_FIELD).get(AGENT_STATE_CAN_REBAKE_REGION_FIELD).isBoolean()); - bool canRebakeRegion = pInput.get(SIM_MESSAGE_BODY_FIELD).get(AGENT_STATE_CAN_REBAKE_REGION_FIELD).asBoolean(); - - LLPathfindingManager::getInstance()->handleAgentState(canRebakeRegion); -} - -//--------------------------------------------------------------------------- -// LinksetsResponder -//--------------------------------------------------------------------------- -LinksetsResponder::LinksetsResponder(LLPathfindingManager::request_id_t pRequestId, LLPathfindingManager::object_request_callback_t pLinksetsCallback, bool pIsObjectRequested, bool pIsTerrainRequested) - : mRequestId(pRequestId), - mLinksetsCallback(pLinksetsCallback), - mObjectMessagingState(pIsObjectRequested ? kWaiting : kNotRequested), - mTerrainMessagingState(pIsTerrainRequested ? kWaiting : kNotRequested), - mObjectLinksetListPtr(), - mTerrainLinksetPtr() -{ -} - -LinksetsResponder::~LinksetsResponder() -{ -} - -void LinksetsResponder::handleObjectLinksetsResult(const LLSD &pContent) -{ - mObjectLinksetListPtr = LLPathfindingObjectListPtr(new LLPathfindingLinksetList(pContent)); - - mObjectMessagingState = kReceivedGood; - if (mTerrainMessagingState != kWaiting) - { - sendCallback(); - } -} - -void LinksetsResponder::handleObjectLinksetsError() -{ - LL_WARNS() << "LinksetsResponder object linksets error" << LL_ENDL; - mObjectMessagingState = kReceivedError; - if (mTerrainMessagingState != kWaiting) - { - sendCallback(); - } -} - -void LinksetsResponder::handleTerrainLinksetsResult(const LLSD &pContent) -{ - mTerrainLinksetPtr = LLPathfindingObjectPtr(new LLPathfindingLinkset(pContent)); - - mTerrainMessagingState = kReceivedGood; - if (mObjectMessagingState != kWaiting) - { - sendCallback(); - } -} - -void LinksetsResponder::handleTerrainLinksetsError() -{ - LL_WARNS() << "LinksetsResponder terrain linksets error" << LL_ENDL; - mTerrainMessagingState = kReceivedError; - if (mObjectMessagingState != kWaiting) - { - sendCallback(); - } -} - -void LinksetsResponder::sendCallback() -{ - llassert(mObjectMessagingState != kWaiting); - llassert(mTerrainMessagingState != kWaiting); - LLPathfindingManager::ERequestStatus requestStatus = - ((((mObjectMessagingState == kReceivedGood) || (mObjectMessagingState == kNotRequested)) && - ((mTerrainMessagingState == kReceivedGood) || (mTerrainMessagingState == kNotRequested))) ? - LLPathfindingManager::kRequestCompleted : LLPathfindingManager::kRequestError); - - if (mObjectMessagingState != kReceivedGood) - { - mObjectLinksetListPtr = LLPathfindingObjectListPtr(new LLPathfindingLinksetList()); - } - - if (mTerrainMessagingState == kReceivedGood) - { - mObjectLinksetListPtr->update(mTerrainLinksetPtr); - } - - mLinksetsCallback(mRequestId, requestStatus, mObjectLinksetListPtr); -} +/**
+* @file llpathfindingmanager.cpp
+* @brief Implementation of llpathfindingmanager
+* @author Stinson@lindenlab.com
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, Linden Research, Inc.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+* $/LicenseInfo$
+*/
+
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llpathfindingmanager.h"
+
+#include <string>
+#include <map>
+
+#include <boost/bind.hpp>
+#include <boost/function.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/signals2.hpp>
+
+#include "llagent.h"
+#include "llhttpnode.h"
+#include "llnotificationsutil.h"
+#include "llpathfindingcharacterlist.h"
+#include "llpathfindinglinkset.h"
+#include "llpathfindinglinksetlist.h"
+#include "llpathfindingnavmesh.h"
+#include "llpathfindingnavmeshstatus.h"
+#include "llpathfindingobject.h"
+#include "llpathinglib.h"
+#include "llsingleton.h"
+#include "llsd.h"
+#include "lltrans.h"
+#include "lluuid.h"
+#include "llviewerregion.h"
+#include "llweb.h"
+#include "llcorehttputil.h"
+#include "llworld.h"
+
+#define CAP_SERVICE_RETRIEVE_NAVMESH "RetrieveNavMeshSrc"
+
+#define CAP_SERVICE_NAVMESH_STATUS "NavMeshGenerationStatus"
+
+#define CAP_SERVICE_GET_OBJECT_LINKSETS "RegionObjects"
+#define CAP_SERVICE_SET_OBJECT_LINKSETS "ObjectNavMeshProperties"
+#define CAP_SERVICE_TERRAIN_LINKSETS "TerrainNavMeshProperties"
+
+#define CAP_SERVICE_CHARACTERS "CharacterProperties"
+
+#define SIM_MESSAGE_NAVMESH_STATUS_UPDATE "/message/NavMeshStatusUpdate"
+#define SIM_MESSAGE_AGENT_STATE_UPDATE "/message/AgentStateUpdate"
+#define SIM_MESSAGE_BODY_FIELD "body"
+
+#define CAP_SERVICE_AGENT_STATE "AgentState"
+
+#define AGENT_STATE_CAN_REBAKE_REGION_FIELD "can_modify_navmesh"
+
+//---------------------------------------------------------------------------
+// LLNavMeshSimStateChangeNode
+//---------------------------------------------------------------------------
+
+class LLNavMeshSimStateChangeNode : public LLHTTPNode
+{
+public:
+ virtual void post(ResponsePtr pResponse, const LLSD &pContext, const LLSD &pInput) const;
+};
+
+LLHTTPRegistration<LLNavMeshSimStateChangeNode> gHTTPRegistrationNavMeshSimStateChangeNode(SIM_MESSAGE_NAVMESH_STATUS_UPDATE);
+
+
+//---------------------------------------------------------------------------
+// LLAgentStateChangeNode
+//---------------------------------------------------------------------------
+class LLAgentStateChangeNode : public LLHTTPNode
+{
+public:
+ virtual void post(ResponsePtr pResponse, const LLSD &pContext, const LLSD &pInput) const;
+};
+
+LLHTTPRegistration<LLAgentStateChangeNode> gHTTPRegistrationAgentStateChangeNode(SIM_MESSAGE_AGENT_STATE_UPDATE);
+
+//---------------------------------------------------------------------------
+// LinksetsResponder
+//---------------------------------------------------------------------------
+
+class LinksetsResponder
+{
+public:
+ LinksetsResponder(LLPathfindingManager::request_id_t pRequestId, LLPathfindingManager::object_request_callback_t pLinksetsCallback, bool pIsObjectRequested, bool pIsTerrainRequested);
+ virtual ~LinksetsResponder();
+
+ void handleObjectLinksetsResult(const LLSD &pContent);
+ void handleObjectLinksetsError();
+ void handleTerrainLinksetsResult(const LLSD &pContent);
+ void handleTerrainLinksetsError();
+
+ typedef std::shared_ptr<LinksetsResponder> ptr_t;
+
+protected:
+
+private:
+ void sendCallback();
+
+ typedef enum
+ {
+ kNotRequested,
+ kWaiting,
+ kReceivedGood,
+ kReceivedError
+ } EMessagingState;
+
+ LLPathfindingManager::request_id_t mRequestId;
+ LLPathfindingManager::object_request_callback_t mLinksetsCallback;
+
+ EMessagingState mObjectMessagingState;
+ EMessagingState mTerrainMessagingState;
+
+ LLPathfindingObjectListPtr mObjectLinksetListPtr;
+ LLPathfindingObjectPtr mTerrainLinksetPtr;
+};
+
+typedef std::shared_ptr<LinksetsResponder> LinksetsResponderPtr;
+
+//---------------------------------------------------------------------------
+// LLPathfindingManager
+//---------------------------------------------------------------------------
+
+LLPathfindingManager::LLPathfindingManager():
+ mNavMeshMap(),
+ mAgentStateSignal()
+{
+}
+
+LLPathfindingManager::~LLPathfindingManager()
+{
+ quitSystem();
+}
+
+void LLPathfindingManager::initSystem()
+{
+ if (LLPathingLib::getInstance() == NULL)
+ {
+ LLPathingLib::initSystem();
+ }
+}
+
+void LLPathfindingManager::quitSystem()
+{
+ if (LLPathingLib::getInstance() != NULL)
+ {
+ LLPathingLib::quitSystem();
+ }
+}
+
+bool LLPathfindingManager::isPathfindingViewEnabled() const
+{
+ return (LLPathingLib::getInstance() != NULL);
+}
+
+bool LLPathfindingManager::isPathfindingEnabledForCurrentRegion() const
+{
+ return isPathfindingEnabledForRegion(getCurrentRegion());
+}
+
+bool LLPathfindingManager::isPathfindingEnabledForRegion(LLViewerRegion *pRegion) const
+{
+ std::string retrieveNavMeshURL = getRetrieveNavMeshURLForRegion(pRegion);
+ return !retrieveNavMeshURL.empty();
+}
+
+bool LLPathfindingManager::isAllowViewTerrainProperties() const
+{
+ LLViewerRegion* region = getCurrentRegion();
+ return (gAgent.isGodlike() || ((region != NULL) && region->canManageEstate()));
+}
+
+LLPathfindingNavMesh::navmesh_slot_t LLPathfindingManager::registerNavMeshListenerForRegion(LLViewerRegion *pRegion, LLPathfindingNavMesh::navmesh_callback_t pNavMeshCallback)
+{
+ LLPathfindingNavMeshPtr navMeshPtr = getNavMeshForRegion(pRegion);
+ return navMeshPtr->registerNavMeshListener(pNavMeshCallback);
+}
+
+void LLPathfindingManager::requestGetNavMeshForRegion(LLViewerRegion *pRegion, bool pIsGetStatusOnly)
+{
+ LLPathfindingNavMeshPtr navMeshPtr = getNavMeshForRegion(pRegion);
+
+ if (pRegion == NULL)
+ {
+ navMeshPtr->handleNavMeshNotEnabled();
+ }
+ else if (!pRegion->capabilitiesReceived())
+ {
+ navMeshPtr->handleNavMeshWaitForRegionLoad();
+ pRegion->setCapabilitiesReceivedCallback(boost::bind(&LLPathfindingManager::handleDeferredGetNavMeshForRegion, this, _1, pIsGetStatusOnly));
+ }
+ else if (!isPathfindingEnabledForRegion(pRegion))
+ {
+ navMeshPtr->handleNavMeshNotEnabled();
+ }
+ else
+ {
+ std::string navMeshStatusURL = getNavMeshStatusURLForRegion(pRegion);
+ llassert(!navMeshStatusURL.empty());
+ navMeshPtr->handleNavMeshCheckVersion();
+
+ U64 regionHandle = pRegion->getHandle();
+ std::string coroname = LLCoros::instance().launch("LLPathfindingManager::navMeshStatusRequestCoro",
+ boost::bind(&LLPathfindingManager::navMeshStatusRequestCoro, this, navMeshStatusURL, regionHandle, pIsGetStatusOnly));
+ }
+}
+
+void LLPathfindingManager::requestGetLinksets(request_id_t pRequestId, object_request_callback_t pLinksetsCallback) const
+{
+ LLPathfindingObjectListPtr emptyLinksetListPtr;
+ LLViewerRegion *currentRegion = getCurrentRegion();
+
+ if (currentRegion == NULL)
+ {
+ pLinksetsCallback(pRequestId, kRequestNotEnabled, emptyLinksetListPtr);
+ }
+ else if (!currentRegion->capabilitiesReceived())
+ {
+ pLinksetsCallback(pRequestId, kRequestStarted, emptyLinksetListPtr);
+ currentRegion->setCapabilitiesReceivedCallback(boost::bind(&LLPathfindingManager::handleDeferredGetLinksetsForRegion, this, _1, pRequestId, pLinksetsCallback));
+ }
+ else
+ {
+ std::string objectLinksetsURL = getRetrieveObjectLinksetsURLForCurrentRegion();
+ std::string terrainLinksetsURL = getTerrainLinksetsURLForCurrentRegion();
+ if (objectLinksetsURL.empty() || terrainLinksetsURL.empty())
+ {
+ pLinksetsCallback(pRequestId, kRequestNotEnabled, emptyLinksetListPtr);
+ }
+ else
+ {
+ pLinksetsCallback(pRequestId, kRequestStarted, emptyLinksetListPtr);
+
+ bool doRequestTerrain = isAllowViewTerrainProperties();
+ LinksetsResponder::ptr_t linksetsResponderPtr(new LinksetsResponder(pRequestId, pLinksetsCallback, true, doRequestTerrain));
+
+ std::string coroname = LLCoros::instance().launch("LLPathfindingManager::linksetObjectsCoro",
+ boost::bind(&LLPathfindingManager::linksetObjectsCoro, this, objectLinksetsURL, linksetsResponderPtr, LLSD()));
+
+ if (doRequestTerrain)
+ {
+ std::string coroname = LLCoros::instance().launch("LLPathfindingManager::linksetTerrainCoro",
+ boost::bind(&LLPathfindingManager::linksetTerrainCoro, this, terrainLinksetsURL, linksetsResponderPtr, LLSD()));
+ }
+ }
+ }
+}
+
+void LLPathfindingManager::requestSetLinksets(request_id_t pRequestId, const LLPathfindingObjectListPtr &pLinksetListPtr, LLPathfindingLinkset::ELinksetUse pLinksetUse, S32 pA, S32 pB, S32 pC, S32 pD, object_request_callback_t pLinksetsCallback) const
+{
+ LLPathfindingObjectListPtr emptyLinksetListPtr;
+
+ std::string objectLinksetsURL = getChangeObjectLinksetsURLForCurrentRegion();
+ std::string terrainLinksetsURL = getTerrainLinksetsURLForCurrentRegion();
+ if (objectLinksetsURL.empty() || terrainLinksetsURL.empty())
+ {
+ pLinksetsCallback(pRequestId, kRequestNotEnabled, emptyLinksetListPtr);
+ }
+ else if ((pLinksetListPtr == NULL) || pLinksetListPtr->isEmpty())
+ {
+ pLinksetsCallback(pRequestId, kRequestCompleted, emptyLinksetListPtr);
+ }
+ else
+ {
+ const LLPathfindingLinksetList *linksetList = dynamic_cast<const LLPathfindingLinksetList *>(pLinksetListPtr.get());
+
+ LLSD objectPostData = linksetList->encodeObjectFields(pLinksetUse, pA, pB, pC, pD);
+ LLSD terrainPostData;
+ if (isAllowViewTerrainProperties())
+ {
+ terrainPostData = linksetList->encodeTerrainFields(pLinksetUse, pA, pB, pC, pD);
+ }
+
+ if (objectPostData.isUndefined() && terrainPostData.isUndefined())
+ {
+ pLinksetsCallback(pRequestId, kRequestCompleted, emptyLinksetListPtr);
+ }
+ else
+ {
+ pLinksetsCallback(pRequestId, kRequestStarted, emptyLinksetListPtr);
+
+ LinksetsResponder::ptr_t linksetsResponderPtr(new LinksetsResponder(pRequestId, pLinksetsCallback, !objectPostData.isUndefined(), !terrainPostData.isUndefined()));
+
+ if (!objectPostData.isUndefined())
+ {
+ std::string coroname = LLCoros::instance().launch("LLPathfindingManager::linksetObjectsCoro",
+ boost::bind(&LLPathfindingManager::linksetObjectsCoro, this, objectLinksetsURL, linksetsResponderPtr, objectPostData));
+ }
+
+ if (!terrainPostData.isUndefined())
+ {
+ std::string coroname = LLCoros::instance().launch("LLPathfindingManager::linksetTerrainCoro",
+ boost::bind(&LLPathfindingManager::linksetTerrainCoro, this, terrainLinksetsURL, linksetsResponderPtr, terrainPostData));
+ }
+ }
+ }
+}
+
+void LLPathfindingManager::requestGetCharacters(request_id_t pRequestId, object_request_callback_t pCharactersCallback) const
+{
+ LLPathfindingObjectListPtr emptyCharacterListPtr;
+
+ LLViewerRegion *currentRegion = getCurrentRegion();
+
+ if (currentRegion == NULL)
+ {
+ pCharactersCallback(pRequestId, kRequestNotEnabled, emptyCharacterListPtr);
+ }
+ else if (!currentRegion->capabilitiesReceived())
+ {
+ pCharactersCallback(pRequestId, kRequestStarted, emptyCharacterListPtr);
+ currentRegion->setCapabilitiesReceivedCallback(boost::bind(&LLPathfindingManager::handleDeferredGetCharactersForRegion, this, _1, pRequestId, pCharactersCallback));
+ }
+ else
+ {
+ std::string charactersURL = getCharactersURLForCurrentRegion();
+ if (charactersURL.empty())
+ {
+ pCharactersCallback(pRequestId, kRequestNotEnabled, emptyCharacterListPtr);
+ }
+ else
+ {
+ pCharactersCallback(pRequestId, kRequestStarted, emptyCharacterListPtr);
+
+ std::string coroname = LLCoros::instance().launch("LLPathfindingManager::charactersCoro",
+ boost::bind(&LLPathfindingManager::charactersCoro, this, charactersURL, pRequestId, pCharactersCallback));
+ }
+ }
+}
+
+LLPathfindingManager::agent_state_slot_t LLPathfindingManager::registerAgentStateListener(agent_state_callback_t pAgentStateCallback)
+{
+ return mAgentStateSignal.connect(pAgentStateCallback);
+}
+
+void LLPathfindingManager::requestGetAgentState()
+{
+ LLViewerRegion *currentRegion = getCurrentRegion();
+
+ if (currentRegion == NULL)
+ {
+ mAgentStateSignal(false);
+ }
+ else
+ {
+ if (!currentRegion->capabilitiesReceived())
+ {
+ currentRegion->setCapabilitiesReceivedCallback(boost::bind(&LLPathfindingManager::handleDeferredGetAgentStateForRegion, this, _1));
+ }
+ else if (!isPathfindingEnabledForRegion(currentRegion))
+ {
+ mAgentStateSignal(false);
+ }
+ else
+ {
+ std::string agentStateURL = getAgentStateURLForRegion(currentRegion);
+ llassert(!agentStateURL.empty());
+
+ std::string coroname = LLCoros::instance().launch("LLPathfindingManager::navAgentStateRequestCoro",
+ boost::bind(&LLPathfindingManager::navAgentStateRequestCoro, this, agentStateURL));
+ }
+ }
+}
+
+void LLPathfindingManager::requestRebakeNavMesh(rebake_navmesh_callback_t pRebakeNavMeshCallback)
+{
+ LLViewerRegion *currentRegion = getCurrentRegion();
+
+ if (currentRegion == NULL)
+ {
+ pRebakeNavMeshCallback(false);
+ }
+ else if (!isPathfindingEnabledForRegion(currentRegion))
+ {
+ pRebakeNavMeshCallback(false);
+ }
+ else
+ {
+ std::string navMeshStatusURL = getNavMeshStatusURLForCurrentRegion();
+ llassert(!navMeshStatusURL.empty());
+
+ std::string coroname = LLCoros::instance().launch("LLPathfindingManager::navMeshRebakeCoro",
+ boost::bind(&LLPathfindingManager::navMeshRebakeCoro, this, navMeshStatusURL, pRebakeNavMeshCallback));
+ }
+}
+
+void LLPathfindingManager::handleDeferredGetAgentStateForRegion(const LLUUID &pRegionUUID)
+{
+ LLViewerRegion *currentRegion = getCurrentRegion();
+
+ if ((currentRegion != NULL) && (currentRegion->getRegionID() == pRegionUUID))
+ {
+ requestGetAgentState();
+ }
+}
+
+void LLPathfindingManager::handleDeferredGetNavMeshForRegion(const LLUUID &pRegionUUID, bool pIsGetStatusOnly)
+{
+ LLViewerRegion *currentRegion = getCurrentRegion();
+
+ if ((currentRegion != NULL) && (currentRegion->getRegionID() == pRegionUUID))
+ {
+ requestGetNavMeshForRegion(currentRegion, pIsGetStatusOnly);
+ }
+}
+
+void LLPathfindingManager::handleDeferredGetLinksetsForRegion(const LLUUID &pRegionUUID, request_id_t pRequestId, object_request_callback_t pLinksetsCallback) const
+{
+ LLViewerRegion *currentRegion = getCurrentRegion();
+
+ if ((currentRegion != NULL) && (currentRegion->getRegionID() == pRegionUUID))
+ {
+ requestGetLinksets(pRequestId, pLinksetsCallback);
+ }
+}
+
+void LLPathfindingManager::handleDeferredGetCharactersForRegion(const LLUUID &pRegionUUID, request_id_t pRequestId, object_request_callback_t pCharactersCallback) const
+{
+ LLViewerRegion *currentRegion = getCurrentRegion();
+
+ if ((currentRegion != NULL) && (currentRegion->getRegionID() == pRegionUUID))
+ {
+ requestGetCharacters(pRequestId, pCharactersCallback);
+ }
+}
+
+void LLPathfindingManager::navMeshStatusRequestCoro(std::string url, U64 regionHandle, bool isGetStatusOnly)
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("NavMeshStatusRequest", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+ LLViewerRegion *region = LLWorld::getInstance()->getRegionFromHandle(regionHandle);
+ if (!region)
+ {
+ LL_WARNS("PathfindingManager") << "Attempting to retrieve navmesh status for region that has gone away." << LL_ENDL;
+ return;
+ }
+ LLUUID regionUUID = region->getRegionID();
+
+ region = NULL;
+ LLSD result = httpAdapter->getAndSuspend(httpRequest, url);
+
+ region = LLWorld::getInstance()->getRegionFromHandle(regionHandle);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ LLPathfindingNavMeshStatus navMeshStatus(regionUUID);
+ if (!status)
+ {
+ LL_WARNS("PathfindingManager") << "HTTP status, " << status.toTerseString() <<
+ ". Building using empty status." << LL_ENDL;
+ }
+ else
+ {
+ result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
+ navMeshStatus = LLPathfindingNavMeshStatus(regionUUID, result);
+ }
+
+ LLPathfindingNavMeshPtr navMeshPtr = getNavMeshForRegion(regionUUID);
+
+ if (!navMeshStatus.isValid())
+ {
+ navMeshPtr->handleNavMeshError();
+ return;
+ }
+ else if (navMeshPtr->hasNavMeshVersion(navMeshStatus))
+ {
+ navMeshPtr->handleRefresh(navMeshStatus);
+ return;
+ }
+ else if (isGetStatusOnly)
+ {
+ navMeshPtr->handleNavMeshNewVersion(navMeshStatus);
+ return;
+ }
+
+ if ((!region) || !region->isAlive())
+ {
+ LL_WARNS("PathfindingManager") << "About to update navmesh status for region that has gone away." << LL_ENDL;
+ navMeshPtr->handleNavMeshNotEnabled();
+ return;
+ }
+
+ std::string navMeshURL = getRetrieveNavMeshURLForRegion(region);
+
+ if (navMeshURL.empty())
+ {
+ navMeshPtr->handleNavMeshNotEnabled();
+ return;
+ }
+
+ navMeshPtr->handleNavMeshStart(navMeshStatus);
+
+ LLSD postData;
+ result = httpAdapter->postAndSuspend(httpRequest, navMeshURL, postData);
+
+ U32 navMeshVersion = navMeshStatus.getVersion();
+
+ if (!status)
+ {
+ LL_WARNS("PathfindingManager") << "HTTP status, " << status.toTerseString() <<
+ ". reporting error." << LL_ENDL;
+ navMeshPtr->handleNavMeshError(navMeshVersion);
+ }
+ else
+ {
+ result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
+ navMeshPtr->handleNavMeshResult(result, navMeshVersion);
+
+ }
+
+}
+
+void LLPathfindingManager::navAgentStateRequestCoro(std::string url)
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("NavAgentStateRequest", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+ LLSD result = httpAdapter->getAndSuspend(httpRequest, url);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ bool canRebake = false;
+ if (!status)
+ {
+ LL_WARNS("PathfindingManager") << "HTTP status, " << status.toTerseString() <<
+ ". Building using empty status." << LL_ENDL;
+ }
+ else
+ {
+ llassert(result.has(AGENT_STATE_CAN_REBAKE_REGION_FIELD));
+ llassert(result.get(AGENT_STATE_CAN_REBAKE_REGION_FIELD).isBoolean());
+ canRebake = result.get(AGENT_STATE_CAN_REBAKE_REGION_FIELD).asBoolean();
+ }
+
+ handleAgentState(canRebake);
+}
+
+void LLPathfindingManager::navMeshRebakeCoro(std::string url, rebake_navmesh_callback_t rebakeNavMeshCallback)
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("NavMeshRebake", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+
+ LLSD postData = LLSD::emptyMap();
+ postData["command"] = "rebuild";
+
+ LLSD result = httpAdapter->postAndSuspend(httpRequest, url, postData);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ bool success = true;
+ if (!status)
+ {
+ LL_WARNS("PathfindingManager") << "HTTP status, " << status.toTerseString() <<
+ ". Rebake failed." << LL_ENDL;
+ success = false;
+ }
+
+ rebakeNavMeshCallback(success);
+}
+
+// If called with putData undefined this coroutine will issue a get. If there
+// is data in putData it will be PUT to the URL.
+void LLPathfindingManager::linksetObjectsCoro(std::string url, LinksetsResponder::ptr_t linksetsResponsderPtr, LLSD putData) const
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("LinksetObjects", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+ LLSD result;
+
+ if (putData.isUndefined())
+ {
+ result = httpAdapter->getAndSuspend(httpRequest, url);
+ }
+ else
+ {
+ result = httpAdapter->putAndSuspend(httpRequest, url, putData);
+ }
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (!status)
+ {
+ LL_WARNS("PathfindingManager") << "HTTP status, " << status.toTerseString() <<
+ ". linksetObjects failed." << LL_ENDL;
+ linksetsResponsderPtr->handleObjectLinksetsError();
+ }
+ else
+ {
+ result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
+ linksetsResponsderPtr->handleObjectLinksetsResult(result);
+ }
+}
+
+// If called with putData undefined this coroutine will issue a GET. If there
+// is data in putData it will be PUT to the URL.
+void LLPathfindingManager::linksetTerrainCoro(std::string url, LinksetsResponder::ptr_t linksetsResponsderPtr, LLSD putData) const
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("LinksetTerrain", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+ LLSD result;
+
+ if (putData.isUndefined())
+ {
+ result = httpAdapter->getAndSuspend(httpRequest, url);
+ }
+ else
+ {
+ result = httpAdapter->putAndSuspend(httpRequest, url, putData);
+ }
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (!status)
+ {
+ LL_WARNS("PathfindingManager") << "HTTP status, " << status.toTerseString() <<
+ ". linksetTerrain failed." << LL_ENDL;
+ linksetsResponsderPtr->handleTerrainLinksetsError();
+ }
+ else
+ {
+ result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
+ linksetsResponsderPtr->handleTerrainLinksetsResult(result);
+ }
+
+}
+
+void LLPathfindingManager::charactersCoro(std::string url, request_id_t requestId, object_request_callback_t callback) const
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("LinksetTerrain", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+ LLSD result = httpAdapter->getAndSuspend(httpRequest, url);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (!status)
+ {
+ LL_WARNS("PathfindingManager") << "HTTP status, " << status.toTerseString() <<
+ ". characters failed." << LL_ENDL;
+
+ LLPathfindingObjectListPtr characterListPtr = LLPathfindingObjectListPtr(new LLPathfindingCharacterList());
+ callback(requestId, LLPathfindingManager::kRequestError, characterListPtr);
+ }
+ else
+ {
+ result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
+ LLPathfindingObjectListPtr characterListPtr = LLPathfindingObjectListPtr(new LLPathfindingCharacterList(result));
+ callback(requestId, LLPathfindingManager::kRequestCompleted, characterListPtr);
+ }
+}
+
+void LLPathfindingManager::handleNavMeshStatusUpdate(const LLPathfindingNavMeshStatus &pNavMeshStatus)
+{
+ LLPathfindingNavMeshPtr navMeshPtr = getNavMeshForRegion(pNavMeshStatus.getRegionUUID());
+
+ if (!pNavMeshStatus.isValid())
+ {
+ navMeshPtr->handleNavMeshError();
+ }
+ else
+ {
+ navMeshPtr->handleNavMeshNewVersion(pNavMeshStatus);
+ }
+}
+
+void LLPathfindingManager::handleAgentState(bool pCanRebakeRegion)
+{
+ mAgentStateSignal(pCanRebakeRegion);
+}
+
+LLPathfindingNavMeshPtr LLPathfindingManager::getNavMeshForRegion(const LLUUID &pRegionUUID)
+{
+ LLPathfindingNavMeshPtr navMeshPtr;
+ NavMeshMap::iterator navMeshIter = mNavMeshMap.find(pRegionUUID);
+ if (navMeshIter == mNavMeshMap.end())
+ {
+ navMeshPtr = LLPathfindingNavMeshPtr(new LLPathfindingNavMesh(pRegionUUID));
+ mNavMeshMap.insert(std::pair<LLUUID, LLPathfindingNavMeshPtr>(pRegionUUID, navMeshPtr));
+ }
+ else
+ {
+ navMeshPtr = navMeshIter->second;
+ }
+
+ return navMeshPtr;
+}
+
+LLPathfindingNavMeshPtr LLPathfindingManager::getNavMeshForRegion(LLViewerRegion *pRegion)
+{
+ LLUUID regionUUID;
+ if (pRegion != NULL)
+ {
+ regionUUID = pRegion->getRegionID();
+ }
+
+ return getNavMeshForRegion(regionUUID);
+}
+
+std::string LLPathfindingManager::getNavMeshStatusURLForCurrentRegion() const
+{
+ return getNavMeshStatusURLForRegion(getCurrentRegion());
+}
+
+std::string LLPathfindingManager::getNavMeshStatusURLForRegion(LLViewerRegion *pRegion) const
+{
+ return getCapabilityURLForRegion(pRegion, CAP_SERVICE_NAVMESH_STATUS);
+}
+
+std::string LLPathfindingManager::getRetrieveNavMeshURLForRegion(LLViewerRegion *pRegion) const
+{
+ return getCapabilityURLForRegion(pRegion, CAP_SERVICE_RETRIEVE_NAVMESH);
+}
+
+std::string LLPathfindingManager::getRetrieveObjectLinksetsURLForCurrentRegion() const
+{
+ return getCapabilityURLForCurrentRegion(CAP_SERVICE_GET_OBJECT_LINKSETS);
+}
+
+std::string LLPathfindingManager::getChangeObjectLinksetsURLForCurrentRegion() const
+{
+ return getCapabilityURLForCurrentRegion(CAP_SERVICE_SET_OBJECT_LINKSETS);
+}
+
+std::string LLPathfindingManager::getTerrainLinksetsURLForCurrentRegion() const
+{
+ return getCapabilityURLForCurrentRegion(CAP_SERVICE_TERRAIN_LINKSETS);
+}
+
+std::string LLPathfindingManager::getCharactersURLForCurrentRegion() const
+{
+ return getCapabilityURLForCurrentRegion(CAP_SERVICE_CHARACTERS);
+}
+
+std::string LLPathfindingManager::getAgentStateURLForRegion(LLViewerRegion *pRegion) const
+{
+ return getCapabilityURLForRegion(pRegion, CAP_SERVICE_AGENT_STATE);
+}
+
+std::string LLPathfindingManager::getCapabilityURLForCurrentRegion(const std::string &pCapabilityName) const
+{
+ return getCapabilityURLForRegion(getCurrentRegion(), pCapabilityName);
+}
+
+std::string LLPathfindingManager::getCapabilityURLForRegion(LLViewerRegion *pRegion, const std::string &pCapabilityName) const
+{
+ std::string capabilityURL("");
+
+ if (pRegion != NULL)
+ {
+ capabilityURL = pRegion->getCapability(pCapabilityName);
+ }
+
+ if (capabilityURL.empty())
+ {
+ LL_WARNS() << "cannot find capability '" << pCapabilityName << "' for current region '"
+ << ((pRegion != NULL) ? pRegion->getName() : "<null>") << "'" << LL_ENDL;
+ }
+
+ return capabilityURL;
+}
+
+LLViewerRegion *LLPathfindingManager::getCurrentRegion() const
+{
+ return gAgent.getRegion();
+}
+
+//---------------------------------------------------------------------------
+// LLNavMeshSimStateChangeNode
+//---------------------------------------------------------------------------
+
+void LLNavMeshSimStateChangeNode::post(ResponsePtr pResponse, const LLSD &pContext, const LLSD &pInput) const
+{
+ llassert(pInput.has(SIM_MESSAGE_BODY_FIELD));
+ llassert(pInput.get(SIM_MESSAGE_BODY_FIELD).isMap());
+ LLPathfindingNavMeshStatus navMeshStatus(pInput.get(SIM_MESSAGE_BODY_FIELD));
+ LLPathfindingManager::getInstance()->handleNavMeshStatusUpdate(navMeshStatus);
+}
+
+//---------------------------------------------------------------------------
+// LLAgentStateChangeNode
+//---------------------------------------------------------------------------
+
+void LLAgentStateChangeNode::post(ResponsePtr pResponse, const LLSD &pContext, const LLSD &pInput) const
+{
+ llassert(pInput.has(SIM_MESSAGE_BODY_FIELD));
+ llassert(pInput.get(SIM_MESSAGE_BODY_FIELD).isMap());
+ llassert(pInput.get(SIM_MESSAGE_BODY_FIELD).has(AGENT_STATE_CAN_REBAKE_REGION_FIELD));
+ llassert(pInput.get(SIM_MESSAGE_BODY_FIELD).get(AGENT_STATE_CAN_REBAKE_REGION_FIELD).isBoolean());
+ bool canRebakeRegion = pInput.get(SIM_MESSAGE_BODY_FIELD).get(AGENT_STATE_CAN_REBAKE_REGION_FIELD).asBoolean();
+
+ LLPathfindingManager::getInstance()->handleAgentState(canRebakeRegion);
+}
+
+//---------------------------------------------------------------------------
+// LinksetsResponder
+//---------------------------------------------------------------------------
+LinksetsResponder::LinksetsResponder(LLPathfindingManager::request_id_t pRequestId, LLPathfindingManager::object_request_callback_t pLinksetsCallback, bool pIsObjectRequested, bool pIsTerrainRequested)
+ : mRequestId(pRequestId),
+ mLinksetsCallback(pLinksetsCallback),
+ mObjectMessagingState(pIsObjectRequested ? kWaiting : kNotRequested),
+ mTerrainMessagingState(pIsTerrainRequested ? kWaiting : kNotRequested),
+ mObjectLinksetListPtr(),
+ mTerrainLinksetPtr()
+{
+}
+
+LinksetsResponder::~LinksetsResponder()
+{
+}
+
+void LinksetsResponder::handleObjectLinksetsResult(const LLSD &pContent)
+{
+ mObjectLinksetListPtr = LLPathfindingObjectListPtr(new LLPathfindingLinksetList(pContent));
+
+ mObjectMessagingState = kReceivedGood;
+ if (mTerrainMessagingState != kWaiting)
+ {
+ sendCallback();
+ }
+}
+
+void LinksetsResponder::handleObjectLinksetsError()
+{
+ LL_WARNS() << "LinksetsResponder object linksets error" << LL_ENDL;
+ mObjectMessagingState = kReceivedError;
+ if (mTerrainMessagingState != kWaiting)
+ {
+ sendCallback();
+ }
+}
+
+void LinksetsResponder::handleTerrainLinksetsResult(const LLSD &pContent)
+{
+ mTerrainLinksetPtr = LLPathfindingObjectPtr(new LLPathfindingLinkset(pContent));
+
+ mTerrainMessagingState = kReceivedGood;
+ if (mObjectMessagingState != kWaiting)
+ {
+ sendCallback();
+ }
+}
+
+void LinksetsResponder::handleTerrainLinksetsError()
+{
+ LL_WARNS() << "LinksetsResponder terrain linksets error" << LL_ENDL;
+ mTerrainMessagingState = kReceivedError;
+ if (mObjectMessagingState != kWaiting)
+ {
+ sendCallback();
+ }
+}
+
+void LinksetsResponder::sendCallback()
+{
+ llassert(mObjectMessagingState != kWaiting);
+ llassert(mTerrainMessagingState != kWaiting);
+ LLPathfindingManager::ERequestStatus requestStatus =
+ ((((mObjectMessagingState == kReceivedGood) || (mObjectMessagingState == kNotRequested)) &&
+ ((mTerrainMessagingState == kReceivedGood) || (mTerrainMessagingState == kNotRequested))) ?
+ LLPathfindingManager::kRequestCompleted : LLPathfindingManager::kRequestError);
+
+ if (mObjectMessagingState != kReceivedGood)
+ {
+ mObjectLinksetListPtr = LLPathfindingObjectListPtr(new LLPathfindingLinksetList());
+ }
+
+ if (mTerrainMessagingState == kReceivedGood)
+ {
+ mObjectLinksetListPtr->update(mTerrainLinksetPtr);
+ }
+
+ mLinksetsCallback(mRequestId, requestStatus, mObjectLinksetListPtr);
+}
|
