From 1757f3967874a2885b45e3324bf19f677e76f6bc Mon Sep 17 00:00:00 2001 From: Todd Stinson Date: Tue, 21 Feb 2012 18:40:40 -0800 Subject: PATH-296: Refining the behavior of the freeze/unfreeze functionality to support both basic and edit/test pathfinding floaters open at the same time. --- indra/newview/llfloaterpathfindingbasic.cpp | 54 ++++++----- indra/newview/llfloaterpathfindingbasic.h | 15 +-- indra/newview/llpathfindingmanager.cpp | 104 ++++++++++++++++----- indra/newview/llpathfindingmanager.h | 37 +++++--- .../default/xui/en/floater_pathfinding_basic.xml | 7 +- 5 files changed, 150 insertions(+), 67 deletions(-) (limited to 'indra') diff --git a/indra/newview/llfloaterpathfindingbasic.cpp b/indra/newview/llfloaterpathfindingbasic.cpp index af20a510c1..654189d4ef 100644 --- a/indra/newview/llfloaterpathfindingbasic.cpp +++ b/indra/newview/llfloaterpathfindingbasic.cpp @@ -25,8 +25,6 @@ * $/LicenseInfo$ */ -#include - #include "llviewerprecompiledheaders.h" #include "llfloaterpathfindingbasic.h" #include "llsd.h" @@ -34,6 +32,9 @@ #include "llbutton.h" #include "llpathfindingmanager.h" +#include +#include + //--------------------------------------------------------------------------- // LLFloaterPathfindingBasic //--------------------------------------------------------------------------- @@ -60,19 +61,25 @@ BOOL LLFloaterPathfindingBasic::postBuild() return LLFloater::postBuild(); } -void LLFloaterPathfindingBasic::onOpen(const LLSD& key) +void LLFloaterPathfindingBasic::onOpen(const LLSD& pKey) { - LLPathfindingManager *pathfindingManager = LLPathfindingManager::getInstance(); - if (pathfindingManager->isPathfindingEnabledForCurrentRegion()) + LLFloater::onOpen(pKey); + + if (!mAgentStateSlot.connected()) { - LLPathfindingManager::getInstance()->requestGetAgentState(boost::bind(&LLFloaterPathfindingBasic::onAgentStateCB, this, _1)); + mAgentStateSlot = LLPathfindingManager::getInstance()->registerAgentStateSignal(boost::bind(&LLFloaterPathfindingBasic::onAgentStateCB, this, _1)); } - else + setAgentState(LLPathfindingManager::getInstance()->getAgentState()); +} + +void LLFloaterPathfindingBasic::onClose(bool pIsAppQuitting) +{ + if (mAgentStateSlot.connected()) { - setAgentState(LLPathfindingManager::kAgentStateNotEnabled); + mAgentStateSlot.disconnect(); } - LLFloater::onOpen(key); + LLFloater::onClose(pIsAppQuitting); } LLFloaterPathfindingBasic::LLFloaterPathfindingBasic(const LLSD& pSeed) @@ -82,7 +89,7 @@ LLFloaterPathfindingBasic::LLFloaterPathfindingBasic(const LLSD& pSeed) mUnfreezeButton(NULL), mFreezeLabel(NULL), mFreezeButton(NULL), - mAgentState(LLPathfindingManager::kAgentStateInitialDefault) + mAgentStateSlot() { } @@ -93,13 +100,13 @@ LLFloaterPathfindingBasic::~LLFloaterPathfindingBasic() void LLFloaterPathfindingBasic::onUnfreezeClicked() { mUnfreezeButton->setEnabled(FALSE); - LLPathfindingManager::getInstance()->requestSetAgentState(LLPathfindingManager::kAgentStateUnfrozen, boost::bind(&LLFloaterPathfindingBasic::onAgentStateCB, this, _1)); + LLPathfindingManager::getInstance()->requestSetAgentState(LLPathfindingManager::kAgentStateUnfrozen); } void LLFloaterPathfindingBasic::onFreezeClicked() { mUnfreezeButton->setEnabled(FALSE); - LLPathfindingManager::getInstance()->requestSetAgentState(LLPathfindingManager::kAgentStateFrozen, boost::bind(&LLFloaterPathfindingBasic::onAgentStateCB, this, _1)); + LLPathfindingManager::getInstance()->requestSetAgentState(LLPathfindingManager::kAgentStateFrozen); } void LLFloaterPathfindingBasic::onAgentStateCB(LLPathfindingManager::EAgentState pAgentState) @@ -109,26 +116,33 @@ void LLFloaterPathfindingBasic::onAgentStateCB(LLPathfindingManager::EAgentState void LLFloaterPathfindingBasic::setAgentState(LLPathfindingManager::EAgentState pAgentState) { + static const LLColor4 warningColor = LLUIColorTable::instance().getColor("DrYellow"); + LLStyle::Params styleParams; + switch (pAgentState) { + case LLPathfindingManager::kAgentStateUnknown : + mStatusText->setVisible(TRUE); + mStatusText->setText((LLStringExplicit)getString("status_querying_state"), styleParams); + break; case LLPathfindingManager::kAgentStateNotEnabled : mStatusText->setVisible(TRUE); - mStatusText->setText((LLStringExplicit)getString("pathfinding_not_enabled")); - mAgentState = pAgentState; + styleParams.color = warningColor; + mStatusText->setText((LLStringExplicit)getString("status_pathfinding_not_enabled"), styleParams); break; case LLPathfindingManager::kAgentStateError : mStatusText->setVisible(TRUE); - mStatusText->setText((LLStringExplicit)getString("unable_to_change_state")); - // Do not actually change the current state in the error case allowing user to retry previous command + styleParams.color = warningColor; + mStatusText->setText((LLStringExplicit)getString("status_unable_to_change_state"), styleParams); break; default : mStatusText->setVisible(FALSE); - mAgentState = pAgentState; break; } - switch (mAgentState) + switch (LLPathfindingManager::getInstance()->getLastKnownNonErrorAgentState()) { + case LLPathfindingManager::kAgentStateUnknown : case LLPathfindingManager::kAgentStateNotEnabled : mUnfreezeLabel->setEnabled(FALSE); mUnfreezeButton->setEnabled(FALSE); @@ -147,12 +161,8 @@ void LLFloaterPathfindingBasic::setAgentState(LLPathfindingManager::EAgentState mFreezeLabel->setEnabled(TRUE); mFreezeButton->setEnabled(TRUE); break; - case LLPathfindingManager::kAgentStateError : - llassert(0); - break; default : llassert(0); break; } } - diff --git a/indra/newview/llfloaterpathfindingbasic.h b/indra/newview/llfloaterpathfindingbasic.h index 356a270ca0..f765917cd7 100644 --- a/indra/newview/llfloaterpathfindingbasic.h +++ b/indra/newview/llfloaterpathfindingbasic.h @@ -42,7 +42,8 @@ class LLFloaterPathfindingBasic public: virtual BOOL postBuild(); - virtual void onOpen(const LLSD& key); + virtual void onOpen(const LLSD& pKey); + virtual void onClose(bool pIsAppQuitting); protected: @@ -59,12 +60,12 @@ private: void setAgentState(LLPathfindingManager::EAgentState pAgentState); - LLTextBase *mStatusText; - LLTextBase *mUnfreezeLabel; - LLButton *mUnfreezeButton; - LLTextBase *mFreezeLabel; - LLButton *mFreezeButton; - LLPathfindingManager::EAgentState mAgentState; + LLTextBase *mStatusText; + LLTextBase *mUnfreezeLabel; + LLButton *mUnfreezeButton; + LLTextBase *mFreezeLabel; + LLButton *mFreezeButton; + LLPathfindingManager::agent_state_slot_t mAgentStateSlot; }; #endif // LL_LLFLOATERPATHFINDINGBASIC_H diff --git a/indra/newview/llpathfindingmanager.cpp b/indra/newview/llpathfindingmanager.cpp index e46ec0e171..3905e6d9f3 100644 --- a/indra/newview/llpathfindingmanager.cpp +++ b/indra/newview/llpathfindingmanager.cpp @@ -27,8 +27,6 @@ #include -#include - #include "llviewerprecompiledheaders.h" #include "llpathfindingmanager.h" #include "llsingleton.h" @@ -36,6 +34,9 @@ #include "llagent.h" #include "llviewerregion.h" +#include +#include + #define CAP_SERVICE_RETRIEVE_NAVMESH "RetrieveNavMeshSrc" #define CAP_SERVICE_AGENT_STATE "AgentPreferences" @@ -48,7 +49,7 @@ class AgentStateResponder : public LLHTTPClient::Responder { public: - AgentStateResponder(LLPathfindingManager::agent_state_callback_t pAgentStateCB, const std::string &pCapabilityURL); + AgentStateResponder(const std::string &pCapabilityURL, LLPathfindingManager::EAgentState pRequestedAgentState = LLPathfindingManager::kAgentStateUnknown); virtual ~AgentStateResponder(); virtual void result(const LLSD &pContent); @@ -57,8 +58,8 @@ public: protected: private: - LLPathfindingManager::agent_state_callback_t mAgentStateCB; - std::string mCapabilityURL; + std::string mCapabilityURL; + LLPathfindingManager::EAgentState mRequestedAgentState; }; //--------------------------------------------------------------------------- @@ -66,6 +67,10 @@ private: //--------------------------------------------------------------------------- LLPathfindingManager::LLPathfindingManager() + : LLSingleton(), + mAgentStateSignal(), + mAgentState(kAgentStateUnknown), + mLastKnownNonErrorAgentState(kAgentStateUnknown) { } @@ -79,52 +84,103 @@ bool LLPathfindingManager::isPathfindingEnabledForCurrentRegion() const return !retrieveNavMeshURL.empty(); } -void LLPathfindingManager::requestGetAgentState(agent_state_callback_t pAgentStateCB) const +LLPathfindingManager::agent_state_slot_t LLPathfindingManager::registerAgentStateSignal(agent_state_callback_t pAgentStateCallback) { - std::string agentStateURL = getAgentStateURLForCurrentRegion(); + return mAgentStateSignal.connect(pAgentStateCallback); +} - if (agentStateURL.empty()) +LLPathfindingManager::EAgentState LLPathfindingManager::getAgentState() +{ + if (!isPathfindingEnabledForCurrentRegion()) { - pAgentStateCB(kAgentStateError); + setAgentState(kAgentStateNotEnabled); } else { - LLHTTPClient::ResponderPtr responder = new AgentStateResponder(pAgentStateCB, agentStateURL); - LLHTTPClient::get(agentStateURL, responder); + if (!isValidAgentState(mAgentState)) + { + requestGetAgentState(); + } } + + return mAgentState; } -void LLPathfindingManager::requestSetAgentState(EAgentState pAgentState, agent_state_callback_t pAgentStateCB) const +LLPathfindingManager::EAgentState LLPathfindingManager::getLastKnownNonErrorAgentState() const { + return mLastKnownNonErrorAgentState; +} + +void LLPathfindingManager::requestSetAgentState(EAgentState pRequestedAgentState) +{ + llassert(isValidAgentState(pRequestedAgentState)); std::string agentStateURL = getAgentStateURLForCurrentRegion(); if (agentStateURL.empty()) { - pAgentStateCB(kAgentStateError); + setAgentState(kAgentStateNotEnabled); } else { LLSD request; - request[ALTER_PERMANENT_OBJECTS_FIELD] = static_cast(pAgentState == kAgentStateUnfrozen); + request[ALTER_PERMANENT_OBJECTS_FIELD] = static_cast(pRequestedAgentState == kAgentStateUnfrozen); - LLHTTPClient::ResponderPtr responder = new AgentStateResponder(pAgentStateCB, agentStateURL); + LLHTTPClient::ResponderPtr responder = new AgentStateResponder(agentStateURL, pRequestedAgentState); LLHTTPClient::post(agentStateURL, request, responder); } } -void LLPathfindingManager::handleAgentStateResult(const LLSD &pContent, agent_state_callback_t pAgentStateCB) const +bool LLPathfindingManager::isValidAgentState(EAgentState pAgentState) +{ + return ((pAgentState == kAgentStateFrozen) || (pAgentState == kAgentStateUnfrozen)); +} + +void LLPathfindingManager::requestGetAgentState() +{ + std::string agentStateURL = getAgentStateURLForCurrentRegion(); + + if (agentStateURL.empty()) + { + setAgentState(kAgentStateNotEnabled); + } + else + { + LLHTTPClient::ResponderPtr responder = new AgentStateResponder(agentStateURL); + LLHTTPClient::get(agentStateURL, responder); + } +} + +void LLPathfindingManager::setAgentState(EAgentState pAgentState) +{ + mAgentState = pAgentState; + + if (mAgentState != kAgentStateError) + { + mLastKnownNonErrorAgentState = mAgentState; + } + + mAgentStateSignal(mAgentState); +} + +void LLPathfindingManager::handleAgentStateResult(const LLSD &pContent, EAgentState pRequestedAgentState) { llassert(pContent.has(ALTER_PERMANENT_OBJECTS_FIELD)); llassert(pContent.get(ALTER_PERMANENT_OBJECTS_FIELD).isBoolean()); EAgentState agentState = (pContent.get(ALTER_PERMANENT_OBJECTS_FIELD).asBoolean() ? kAgentStateUnfrozen : kAgentStateFrozen); - pAgentStateCB(agentState); + if (isValidAgentState(pRequestedAgentState) && (agentState != pRequestedAgentState)) + { + agentState = kAgentStateError; + llassert(0); + } + + setAgentState(agentState); } -void LLPathfindingManager::handleAgentStateError(U32 pStatus, const std::string &pReason, const std::string &pURL, agent_state_callback_t pAgentStateCB) const +void LLPathfindingManager::handleAgentStateError(U32 pStatus, const std::string &pReason, const std::string &pURL) { llwarns << "error with request to URL '" << pURL << "' because " << pReason << " (statusCode:" << pStatus << ")" << llendl; - pAgentStateCB(kAgentStateError); + setAgentState(kAgentStateError); } std::string LLPathfindingManager::getRetrieveNavMeshURLForCurrentRegion() const @@ -160,9 +216,9 @@ std::string LLPathfindingManager::getCapabilityURLForCurrentRegion(const std::st // AgentStateResponder //--------------------------------------------------------------------------- -AgentStateResponder::AgentStateResponder(LLPathfindingManager::agent_state_callback_t pAgentStateCB, const std::string &pCapabilityURL) - : mAgentStateCB(pAgentStateCB), - mCapabilityURL(pCapabilityURL) +AgentStateResponder::AgentStateResponder(const std::string &pCapabilityURL, LLPathfindingManager::EAgentState pRequestedAgentState) + : mCapabilityURL(pCapabilityURL), + mRequestedAgentState(pRequestedAgentState) { } @@ -172,10 +228,10 @@ AgentStateResponder::~AgentStateResponder() void AgentStateResponder::result(const LLSD &pContent) { - LLPathfindingManager::getInstance()->handleAgentStateResult(pContent, mAgentStateCB); + LLPathfindingManager::getInstance()->handleAgentStateResult(pContent, mRequestedAgentState); } void AgentStateResponder::error(U32 pStatus, const std::string &pReason) { - LLPathfindingManager::getInstance()->handleAgentStateError(pStatus, pReason, mCapabilityURL, mAgentStateCB); + LLPathfindingManager::getInstance()->handleAgentStateError(pStatus, pReason, mCapabilityURL); } diff --git a/indra/newview/llpathfindingmanager.h b/indra/newview/llpathfindingmanager.h index e8aa8385cf..a9432f9077 100644 --- a/indra/newview/llpathfindingmanager.h +++ b/indra/newview/llpathfindingmanager.h @@ -31,6 +31,7 @@ #include #include +#include #include "llsingleton.h" @@ -38,35 +39,49 @@ class LLFloater; class LLPathfindingManager : public LLSingleton { + friend class AgentStateResponder; public: typedef enum { - kAgentStateNotEnabled = 0, - kAgentStateFrozen = 1, - kAgentStateUnfrozen = 2, - kAgentStateError = 3, - kAgentStateInitialDefault = kAgentStateUnfrozen + kAgentStateUnknown, + kAgentStateFrozen, + kAgentStateUnfrozen, + kAgentStateNotEnabled, + kAgentStateError } EAgentState; - typedef boost::function agent_state_callback_t; + typedef boost::function agent_state_callback_t; + typedef boost::signals2::signal agent_state_signal_t; + typedef boost::signals2::connection agent_state_slot_t; LLPathfindingManager(); virtual ~LLPathfindingManager(); bool isPathfindingEnabledForCurrentRegion() const; - void requestGetAgentState(agent_state_callback_t pAgentStateCB) const; - void requestSetAgentState(EAgentState, agent_state_callback_t pAgentStateCB) const; - - void handleAgentStateResult(const LLSD &pContent, agent_state_callback_t pAgentStateCB) const; - void handleAgentStateError(U32 pStatus, const std::string &pReason, const std::string &pURL, agent_state_callback_t pAgentStateCB) const; + agent_state_slot_t registerAgentStateSignal(agent_state_callback_t pAgentStateCallback); + EAgentState getAgentState(); + EAgentState getLastKnownNonErrorAgentState() const; + void requestSetAgentState(EAgentState pAgentState); protected: private: + static bool isValidAgentState(EAgentState pAgentState); + + void requestGetAgentState(); + void setAgentState(EAgentState pAgentState); + + void handleAgentStateResult(const LLSD &pContent, EAgentState pRequestedAgentState); + void handleAgentStateError(U32 pStatus, const std::string &pReason, const std::string &pURL); + std::string getRetrieveNavMeshURLForCurrentRegion() const; std::string getAgentStateURLForCurrentRegion() const; std::string getCapabilityURLForCurrentRegion(const std::string &pCapabilityName) const; + + agent_state_signal_t mAgentStateSignal; + EAgentState mAgentState; + EAgentState mLastKnownNonErrorAgentState; }; #endif // LL_LLPATHFINDINGMANAGER_H diff --git a/indra/newview/skins/default/xui/en/floater_pathfinding_basic.xml b/indra/newview/skins/default/xui/en/floater_pathfinding_basic.xml index f53d11bb1d..7af40bbff6 100644 --- a/indra/newview/skins/default/xui/en/floater_pathfinding_basic.xml +++ b/indra/newview/skins/default/xui/en/floater_pathfinding_basic.xml @@ -11,14 +11,15 @@ single_instance="true" title="Basic pathfinding setup" width="312"> - This region is not enabled for pathfinding. - Unable to change modes successfully. + This region is not enabled for pathfinding. + Unable to change modes successfully. + Checking status ...