diff options
Diffstat (limited to 'indra/newview')
-rw-r--r-- | indra/newview/llfloaterregiondebugconsole.cpp | 175 | ||||
-rw-r--r-- | indra/newview/llfloaterregiondebugconsole.h | 8 | ||||
-rw-r--r-- | indra/newview/llviewerregion.cpp | 1 |
3 files changed, 149 insertions, 35 deletions
diff --git a/indra/newview/llfloaterregiondebugconsole.cpp b/indra/newview/llfloaterregiondebugconsole.cpp index 159dee7631..0e61fb8e0a 100644 --- a/indra/newview/llfloaterregiondebugconsole.cpp +++ b/indra/newview/llfloaterregiondebugconsole.cpp @@ -37,34 +37,113 @@ #include "llagent.h" #include "llhttpclient.h" +#include "llhttpnode.h" #include "lllineeditor.h" #include "lltexteditor.h" #include "llviewerregion.h" -class Responder : public LLHTTPClient::Responder { -public: - Responder(LLTextEditor *output) : mOutput(output) - { - } - - /*virtual*/ - void error(U32 status, const std::string& reason) - { - } - - /*virtual*/ - void result(const LLSD& content) - { - std::string text = content.asString() + "\n\n> "; - mOutput->appendText(text, false); - }; - - LLTextEditor * mOutput; -}; +// Two versions of the sim console API are supported. +// +// SimConsole capability (deprecated): +// This is the initial implementation that is supported by some versions of the +// simulator. It is simple and straight forward, just POST a command and the +// body of the response has the result. This API is deprecated because it +// doesn't allow the sim to use any asynchronous API. +// +// SimConsoleAsync capability: +// This capability replaces the original SimConsole capability. It is similar +// in that the command is POSTed to the SimConsoleAsync cap, but the response +// comes in through the event poll, which gives the simulator more flexibility +// and allows it to perform complex operations without blocking any frames. +// +// We will assume the SimConsoleAsync capability is available, and fall back to +// the SimConsole cap if it is not. The simulator will only support one or the +// other. + +namespace +{ + // Signal used to notify the floater of responses from the asynchronous + // API. + typedef boost::signals2::signal< + void (const std::string& output)> console_reply_signal_t; + console_reply_signal_t sConsoleReplySignal; + + const std::string PROMPT("\n\n> "); + const std::string UNABLE_TO_SEND_COMMAND( + "ERROR: The last command was not received by the server."); + const std::string CONSOLE_UNAVAILABLE( + "ERROR: No console available for this region/simulator."); + const std::string CONSOLE_NOT_SUPPORTED( + "This region does not support the simulator console."); + + // This responder handles the initial response. Unless error() is called + // we assume that the simulator has received our request. Error will be + // called if this request times out. + class AsyncConsoleResponder : public LLHTTPClient::Responder + { + public: + /* virtual */ + void error(U32 status, const std::string& reason) + { + sConsoleReplySignal(UNABLE_TO_SEND_COMMAND); + } + }; + + class ConsoleResponder : public LLHTTPClient::Responder + { + public: + ConsoleResponder(LLTextEditor *output) : mOutput(output) + { + } + + /*virtual*/ + void error(U32 status, const std::string& reason) + { + mOutput->appendText( + UNABLE_TO_SEND_COMMAND + PROMPT, + false); + } + + /*virtual*/ + void result(const LLSD& content) + { + mOutput->appendText(content.asString() + PROMPT, false); + } + + LLTextEditor * mOutput; + }; + + // This handles responses for console commands sent via the asynchronous + // API. + class ConsoleResponseNode : public LLHTTPNode + { + public: + /* virtual */ + void post( + LLHTTPNode::ResponsePtr reponse, + const LLSD& context, + const LLSD& input) const + { + llinfos << "Received response from the debug console: " + << input << llendl; + sConsoleReplySignal(input["body"].asString()); + } + }; +} LLFloaterRegionDebugConsole::LLFloaterRegionDebugConsole(LLSD const & key) : LLFloater(key), mOutput(NULL) { + mReplySignalConnection = sConsoleReplySignal.connect( + boost::bind( + &LLFloaterRegionDebugConsole::onReplyReceived, + this, + _1)); +} + +LLFloaterRegionDebugConsole::~LLFloaterRegionDebugConsole() +{ + mReplySignalConnection.disconnect(); } BOOL LLFloaterRegionDebugConsole::postBuild() @@ -77,17 +156,21 @@ BOOL LLFloaterRegionDebugConsole::postBuild() mOutput = getChild<LLTextEditor>("region_debug_console_output"); - std::string url = gAgent.getRegion()->getCapability("SimConsole"); - if ( url.size() == 0 ) + std::string url = gAgent.getRegion()->getCapability("SimConsoleAsync"); + if (url.empty()) { - mOutput->appendText("This region does not support the simulator console.\n\n> ", false); + // Fall back to see if the old API is supported. + url = gAgent.getRegion()->getCapability("SimConsole"); + if (url.empty()) + { + mOutput->appendText( + CONSOLE_NOT_SUPPORTED + PROMPT, + false); + return TRUE; + } } - else - { - mOutput->appendText("> ", false); - } - + mOutput->appendText("> ", false); return TRUE; } @@ -96,20 +179,42 @@ void LLFloaterRegionDebugConsole::onInput(LLUICtrl* ctrl, const LLSD& param) LLLineEditor* input = static_cast<LLLineEditor*>(ctrl); std::string text = input->getText() + "\n"; - - std::string url = gAgent.getRegion()->getCapability("SimConsole"); - - if ( url.size() > 0 ) + std::string url = gAgent.getRegion()->getCapability("SimConsoleAsync"); + if (url.empty()) { - LLHTTPClient::post(url, LLSD(input->getText()), new ::Responder(mOutput)); + // Fall back to the old API + url = gAgent.getRegion()->getCapability("SimConsole"); + if (url.empty()) + { + text += CONSOLE_UNAVAILABLE + PROMPT; + } + else + { + // Using SimConsole (deprecated) + LLHTTPClient::post( + url, + LLSD(input->getText()), + new ConsoleResponder(mOutput)); + } } else { - text += "\nError: No console available for this region/simulator.\n\n> "; + // Using SimConsoleAsync + LLHTTPClient::post( + url, + LLSD(input->getText()), + new AsyncConsoleResponder); } mOutput->appendText(text, false); - input->clear(); } +void LLFloaterRegionDebugConsole::onReplyReceived(const std::string& output) +{ + mOutput->appendText(output + PROMPT, false); +} + +LLHTTPRegistration<ConsoleResponseNode> + gHTTPRegistrationMessageDebugConsoleResponse( + "/message/SimConsoleResponse"); diff --git a/indra/newview/llfloaterregiondebugconsole.h b/indra/newview/llfloaterregiondebugconsole.h index 69d7773fec..4171a4da6b 100644 --- a/indra/newview/llfloaterregiondebugconsole.h +++ b/indra/newview/llfloaterregiondebugconsole.h @@ -34,6 +34,8 @@ #ifndef LL_LLFLOATERREGIONDEBUGCONSOLE_H #define LL_LLFLOATERREGIONDEBUGCONSOLE_H +#include <boost/signals2.hpp> + #include "llfloater.h" #include "llhttpclient.h" @@ -43,6 +45,7 @@ class LLFloaterRegionDebugConsole : public LLFloater, public LLHTTPClient::Respo { public: LLFloaterRegionDebugConsole(LLSD const & key); + virtual ~LLFloaterRegionDebugConsole(); // virtual BOOL postBuild(); @@ -50,6 +53,11 @@ public: void onInput(LLUICtrl* ctrl, const LLSD& param); LLTextEditor * mOutput; + + private: + void onReplyReceived(const std::string& output); + + boost::signals2::connection mReplySignalConnection; }; #endif // LL_LLFLOATERREGIONDEBUGCONSOLE_H diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index abae44953b..45a2acfeef 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -1400,6 +1400,7 @@ void LLViewerRegion::setSeedCapability(const std::string& url) capabilityNames.append("ServerReleaseNotes"); capabilityNames.append("SetDisplayName"); capabilityNames.append("SimConsole"); + capabilityNames.append("SimConsoleAsync"); capabilityNames.append("StartGroupProposal"); capabilityNames.append("TextureStats"); capabilityNames.append("UntrustedSimulatorMessage"); |