PageRenderTime 23ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/indra/newview/llfloaterregiondebugconsole.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 224 lines | 142 code | 24 blank | 58 comment | 6 complexity | 3d4123444144a9cc5577533e6c0f33c8 MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llfloaterregiondebugconsole.h
  3. * @author Brad Kittenbrink <brad@lindenlab.com>
  4. * @brief Quick and dirty console for region debug settings
  5. *
  6. * $LicenseInfo:firstyear=2010&license=viewerlgpl$
  7. * Second Life Viewer Source Code
  8. * Copyright (C) 2010, Linden Research, Inc.
  9. *
  10. * This library is free software; you can redistribute it and/or
  11. * modify it under the terms of the GNU Lesser General Public
  12. * License as published by the Free Software Foundation;
  13. * version 2.1 of the License only.
  14. *
  15. * This library is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  18. * Lesser General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU Lesser General Public
  21. * License along with this library; if not, write to the Free Software
  22. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  23. *
  24. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  25. * $/LicenseInfo$
  26. */
  27. #include "llviewerprecompiledheaders.h"
  28. #include "llfloaterregiondebugconsole.h"
  29. #include "llagent.h"
  30. #include "llhttpclient.h"
  31. #include "llhttpnode.h"
  32. #include "lllineeditor.h"
  33. #include "lltexteditor.h"
  34. #include "llviewerregion.h"
  35. // Two versions of the sim console API are supported.
  36. //
  37. // SimConsole capability (deprecated):
  38. // This is the initial implementation that is supported by some versions of the
  39. // simulator. It is simple and straight forward, just POST a command and the
  40. // body of the response has the result. This API is deprecated because it
  41. // doesn't allow the sim to use any asynchronous API.
  42. //
  43. // SimConsoleAsync capability:
  44. // This capability replaces the original SimConsole capability. It is similar
  45. // in that the command is POSTed to the SimConsoleAsync cap, but the response
  46. // comes in through the event poll, which gives the simulator more flexibility
  47. // and allows it to perform complex operations without blocking any frames.
  48. //
  49. // We will assume the SimConsoleAsync capability is available, and fall back to
  50. // the SimConsole cap if it is not. The simulator will only support one or the
  51. // other.
  52. namespace
  53. {
  54. // Signal used to notify the floater of responses from the asynchronous
  55. // API.
  56. console_reply_signal_t sConsoleReplySignal;
  57. const std::string PROMPT("\n\n> ");
  58. const std::string UNABLE_TO_SEND_COMMAND(
  59. "ERROR: The last command was not received by the server.");
  60. const std::string CONSOLE_UNAVAILABLE(
  61. "ERROR: No console available for this region/simulator.");
  62. const std::string CONSOLE_NOT_SUPPORTED(
  63. "This region does not support the simulator console.");
  64. // This responder handles the initial response. Unless error() is called
  65. // we assume that the simulator has received our request. Error will be
  66. // called if this request times out.
  67. class AsyncConsoleResponder : public LLHTTPClient::Responder
  68. {
  69. public:
  70. /* virtual */
  71. void error(U32 status, const std::string& reason)
  72. {
  73. sConsoleReplySignal(UNABLE_TO_SEND_COMMAND);
  74. }
  75. };
  76. class ConsoleResponder : public LLHTTPClient::Responder
  77. {
  78. public:
  79. ConsoleResponder(LLTextEditor *output) : mOutput(output)
  80. {
  81. }
  82. /*virtual*/
  83. void error(U32 status, const std::string& reason)
  84. {
  85. if (mOutput)
  86. {
  87. mOutput->appendText(
  88. UNABLE_TO_SEND_COMMAND + PROMPT,
  89. false);
  90. }
  91. }
  92. /*virtual*/
  93. void result(const LLSD& content)
  94. {
  95. if (mOutput)
  96. {
  97. mOutput->appendText(
  98. content.asString() + PROMPT, false);
  99. }
  100. }
  101. LLTextEditor * mOutput;
  102. };
  103. // This handles responses for console commands sent via the asynchronous
  104. // API.
  105. class ConsoleResponseNode : public LLHTTPNode
  106. {
  107. public:
  108. /* virtual */
  109. void post(
  110. LLHTTPNode::ResponsePtr reponse,
  111. const LLSD& context,
  112. const LLSD& input) const
  113. {
  114. llinfos << "Received response from the debug console: "
  115. << input << llendl;
  116. sConsoleReplySignal(input["body"].asString());
  117. }
  118. };
  119. }
  120. boost::signals2::connection LLFloaterRegionDebugConsole::setConsoleReplyCallback(const console_reply_signal_t::slot_type& cb)
  121. {
  122. return sConsoleReplySignal.connect(cb);
  123. }
  124. LLFloaterRegionDebugConsole::LLFloaterRegionDebugConsole(LLSD const & key)
  125. : LLFloater(key), mOutput(NULL)
  126. {
  127. mReplySignalConnection = sConsoleReplySignal.connect(
  128. boost::bind(
  129. &LLFloaterRegionDebugConsole::onReplyReceived,
  130. this,
  131. _1));
  132. }
  133. LLFloaterRegionDebugConsole::~LLFloaterRegionDebugConsole()
  134. {
  135. mReplySignalConnection.disconnect();
  136. }
  137. BOOL LLFloaterRegionDebugConsole::postBuild()
  138. {
  139. LLLineEditor* input = getChild<LLLineEditor>("region_debug_console_input");
  140. input->setEnableLineHistory(true);
  141. input->setCommitCallback(boost::bind(&LLFloaterRegionDebugConsole::onInput, this, _1, _2));
  142. input->setFocus(true);
  143. input->setCommitOnFocusLost(false);
  144. mOutput = getChild<LLTextEditor>("region_debug_console_output");
  145. std::string url = gAgent.getRegion()->getCapability("SimConsoleAsync");
  146. if (url.empty())
  147. {
  148. // Fall back to see if the old API is supported.
  149. url = gAgent.getRegion()->getCapability("SimConsole");
  150. if (url.empty())
  151. {
  152. mOutput->appendText(
  153. CONSOLE_NOT_SUPPORTED + PROMPT,
  154. false);
  155. return TRUE;
  156. }
  157. }
  158. mOutput->appendText("> ", false);
  159. return TRUE;
  160. }
  161. void LLFloaterRegionDebugConsole::onInput(LLUICtrl* ctrl, const LLSD& param)
  162. {
  163. LLLineEditor* input = static_cast<LLLineEditor*>(ctrl);
  164. std::string text = input->getText() + "\n";
  165. std::string url = gAgent.getRegion()->getCapability("SimConsoleAsync");
  166. if (url.empty())
  167. {
  168. // Fall back to the old API
  169. url = gAgent.getRegion()->getCapability("SimConsole");
  170. if (url.empty())
  171. {
  172. text += CONSOLE_UNAVAILABLE + PROMPT;
  173. }
  174. else
  175. {
  176. // Using SimConsole (deprecated)
  177. LLHTTPClient::post(
  178. url,
  179. LLSD(input->getText()),
  180. new ConsoleResponder(mOutput));
  181. }
  182. }
  183. else
  184. {
  185. // Using SimConsoleAsync
  186. LLHTTPClient::post(
  187. url,
  188. LLSD(input->getText()),
  189. new AsyncConsoleResponder);
  190. }
  191. mOutput->appendText(text, false);
  192. input->clear();
  193. }
  194. void LLFloaterRegionDebugConsole::onReplyReceived(const std::string& output)
  195. {
  196. mOutput->appendText(output + PROMPT, false);
  197. }
  198. LLHTTPRegistration<ConsoleResponseNode>
  199. gHTTPRegistrationMessageDebugConsoleResponse(
  200. "/message/SimConsoleResponse");