diff options
-rw-r--r-- | indra/llui/lltexteditor.h | 2 | ||||
-rw-r--r-- | indra/newview/llfloaterluadebug.cpp | 12 | ||||
-rw-r--r-- | indra/newview/llfloaterluadebug.h | 3 | ||||
-rw-r--r-- | indra/newview/llluamanager.cpp | 91 | ||||
-rw-r--r-- | indra/newview/skins/default/xui/en/floater_lua_debug.xml | 1 |
5 files changed, 82 insertions, 27 deletions
diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h index f3939248c2..ec2b9a4b7d 100644 --- a/indra/llui/lltexteditor.h +++ b/indra/llui/lltexteditor.h @@ -241,7 +241,9 @@ protected: // Undoable operations void addChar(llwchar c); // at mCursorPos S32 addChar(S32 pos, llwchar wc); +public: void addLineBreakChar(BOOL group_together = FALSE); +protected: S32 overwriteChar(S32 pos, llwchar wc); void removeChar(); S32 removeChar(S32 pos); diff --git a/indra/newview/llfloaterluadebug.cpp b/indra/newview/llfloaterluadebug.cpp index 9ca554d4ad..44454d7be0 100644 --- a/indra/newview/llfloaterluadebug.cpp +++ b/indra/newview/llfloaterluadebug.cpp @@ -54,6 +54,14 @@ BOOL LLFloaterLUADebug::postBuild() mResultOutput = getChild<LLTextEditor>("result_text"); mLineInput = getChild<LLLineEditor>("lua_cmd"); mScriptPath = getChild<LLLineEditor>("script_path"); + mOutConnection = LLEventPumps::instance().obtain("lua output") + .listen("LLFloaterLUADebug", + [mResultOutput=mResultOutput](const LLSD& data) + { + mResultOutput->insertText(data.asString()); + mResultOutput->addLineBreakChar(true); + return false; + }); getChild<LLButton>("execute_btn")->setClickedCallback(boost::bind(&LLFloaterLUADebug::onExecuteClicked, this)); getChild<LLButton>("browse_btn")->setClickedCallback(boost::bind(&LLFloaterLUADebug::onBtnBrowse, this)); @@ -77,7 +85,7 @@ void LLFloaterLUADebug::onExecuteClicked() std::string cmd = mLineInput->getText(); LLLUAmanager::runScriptLine(cmd, [this](std::string msg) { - mResultOutput->setText(msg); + mResultOutput->insertText(msg); }); } @@ -107,7 +115,7 @@ void LLFloaterLUADebug::runSelectedScript(const std::vector<std::string> &filena mScriptPath->setText(filepath); LLLUAmanager::runScriptFile(filepath, [this](std::string msg) { - mResultOutput->setText(msg); + mResultOutput->insertText(msg); }); } } diff --git a/indra/newview/llfloaterluadebug.h b/indra/newview/llfloaterluadebug.h index 300d954aea..fd61e29ebe 100644 --- a/indra/newview/llfloaterluadebug.h +++ b/indra/newview/llfloaterluadebug.h @@ -26,6 +26,7 @@ #ifndef LL_LLFLOATERLUADEBUG_H #define LL_LLFLOATERLUADEBUG_H +#include "llevents.h" #include "llfloater.h" extern "C" @@ -54,6 +55,8 @@ class LLFloaterLUADebug : void runSelectedScript(const std::vector<std::string> &filenames); private: + LLTempBoundListener mOutConnection; + LLTextEditor* mResultOutput; LLLineEditor* mLineInput; LLLineEditor* mScriptPath; diff --git a/indra/newview/llluamanager.cpp b/indra/newview/llluamanager.cpp index b18708bd84..2cc809ff0f 100644 --- a/indra/newview/llluamanager.cpp +++ b/indra/newview/llluamanager.cpp @@ -66,6 +66,7 @@ extern "C" #include <cstring> // std::memcpy() #include <map> #include <memory> // std::unique_ptr +#include <sstream> #include <string_view> #include <vector> @@ -109,8 +110,10 @@ public: super(getUniqueKey()), mState(L), mReplyPump(LLUUID::generateNewID().asString()), - mListener(new LLLeapListener(std::bind(&LuaListener::connect, this, - std::placeholders::_1, std::placeholders::_2))) + mListener( + new LLLeapListener( + [this](LLEventPump& pump, const std::string& listener) + { return connect(pump, listener); })) { mReplyConnection = connect(mReplyPump, "LuaListener"); } @@ -136,13 +139,15 @@ private: LLBoundListener connect(LLEventPump& pump, const std::string& listener) { - return pump.listen(listener, - std::bind(&LuaListener::call_lua, mState, pump.getName(), - std::placeholders::_1)); + return pump.listen( + listener, + [mState=mState, pumpname=pump.getName()](const LLSD& data) + { return call_lua(mState, pumpname, data); }); } static bool call_lua(lua_State* L, const std::string& pump, const LLSD& data) { + LL_INFOS("Lua") << "LuaListener::call_lua('" << pump << "', " << data << ")" << LL_ENDL; if (! lua_checkstack(L, 3)) { LL_WARNS("Lua") << "Cannot extend Lua stack to call listen_events() callback" @@ -275,28 +280,63 @@ int name##_::call(lua_State* L) // ... supply method body here, referencing 'L' ... // } -lua_function(print_debug) +// This function consumes ALL Lua stack arguments and returns concatenated +// message string +std::string lua_print_msg(lua_State* L, const std::string_view& level) { + // On top of existing Lua arguments, push 'where' info + luaL_checkstack(L, 1, nullptr); luaL_where(L, 1); - LL_DEBUGS("Lua") << lua_tostring(L, 2) << ": " << lua_tostring(L, 1) << LL_ENDL; - lua_pop(L, 2); + // start with the 'where' info at the top of the stack + std::ostringstream out; + out << lua_tostring(L, -1); + lua_pop(L, 1); + const char* sep = ""; // 'where' info ends with ": " + // now iterate over arbitrary args, calling Lua tostring() on each and + // concatenating with separators + for (int p = 1; p <= lua_gettop(L); ++p) + { + out << sep; + sep = " "; + // push Lua tostring() function -- note, semantically different from + // lua_tostring()! + lua_getglobal(L, "tostring"); + // Now the stack is arguments 1 .. N, plus tostring(). + // Rotate downwards, producing stack args 2 .. N, tostring(), arg1. + lua_rotate(L, 1, -1); + // pop tostring() and arg1, pushing tostring(arg1) + // (ignore potential error code from lua_pcall() because, if there was + // an error, we expect the stack top to be an error message -- which + // we'll print) + lua_pcall(L, 1, 1, 0); + // stack now holds args 2 .. N, tostring(arg1) + out << lua_tostring(L, -1); + } + // pop everything + lua_settop(L, 0); + // capture message string + std::string msg{ out.str() }; + // put message out there for any interested party (*koff* LLFloaterLUADebug *koff*) + LLEventPumps::instance().obtain("lua output").post(stringize(level, ": ", msg)); + return msg; +} + +lua_function(print_debug) +{ + LL_DEBUGS("Lua") << lua_print_msg(L, "DEBUG") << LL_ENDL; return 0; } // also used for print(); see LuaState constructor lua_function(print_info) { - luaL_where(L, 1); - LL_INFOS("Lua") << lua_tostring(L, 2) << ": " << lua_tostring(L, 1) << LL_ENDL; - lua_pop(L, 2); + LL_INFOS("Lua") << lua_print_msg(L, "INFO") << LL_ENDL; return 0; } lua_function(print_warning) { - luaL_where(L, 1); - LL_WARNS("Lua") << lua_tostring(L, 2) << ": " << lua_tostring(L, 1) << LL_ENDL; - lua_pop(L, 2); + LL_WARNS("Lua") << lua_print_msg(L, "WARN") << LL_ENDL; return 0; } @@ -421,7 +461,7 @@ lua_function(get_avatar_name) { std::string name = gAgentAvatarp->getFullname(); luaL_checkstack(L, 1, nullptr); - lua_pushstring(L, name.c_str()); + lua_pushstdstring(L, name); return 1; } @@ -513,7 +553,7 @@ lua_function(show_notification) LLNotificationsUtil::add(notification); } - lua_pop(L, lua_gettop(L)); + lua_settop(L, 0); return 0; } @@ -540,7 +580,7 @@ lua_function(add_menu_item) gMenuBarView->findChildMenuByName(menu, true)->append(menu_item); } - lua_pop(L, lua_gettop(L)); + lua_settop(L, 0); return 0; } @@ -568,7 +608,7 @@ lua_function(add_menu) gMenuBarView->appendMenu(menu); } - lua_pop(L, lua_gettop(L)); + lua_settop(L, 0); return 0; } @@ -588,7 +628,7 @@ lua_function(add_branch) gMenuBarView->findChildMenuByName(menu, true)->appendMenu(branch); } - lua_pop(L, lua_gettop(L)); + lua_settop(L, 0); return 0; } @@ -610,7 +650,7 @@ lua_function(rez_prim) LL_INFOS() << "Rezing a prim: type " << LLPrimitive::pCodeToString(type) << ", coordinates: " << obj_pos << " Success: " << res << LL_ENDL; - lua_pop(L, lua_gettop(L)); + lua_settop(L, 0); return 0; } @@ -664,7 +704,7 @@ lua_function(move_by) } move_to_dest(dest, L, response_cb); - lua_pop(L, lua_gettop(L)); + lua_settop(L, 0); return 0; } @@ -690,7 +730,7 @@ lua_function(move_to) } move_to_dest(dest, L, response_cb); - lua_pop(L, lua_gettop(L)); + lua_settop(L, 0); return 0; } @@ -716,15 +756,16 @@ lua_function(run_ui_command) } sUIListener.call(event); - lua_pop(L, top); + lua_settop(L, 0); return 0; } lua_function(post_on) { - std::string pumpname{ lua_tostring(L, 1) }; + std::string pumpname{ lua_tostdstring(L, 1) }; LLSD data{ lua_tollsd(L, 2) }; lua_pop(L, 2); + LL_INFOS("Lua") << "post_on('" << pumpname << "', " << data << ")" << LL_ENDL; LLEventPumps::instance().obtain(pumpname).post(data); return 0; } @@ -804,7 +845,7 @@ lua_function(await_event) auto timeout{ lua_tonumber(L, 2) }; // with no 3rd argument, should be LLSD() auto dftval{ lua_tollsd(L, 3) }; - lua_pop(L, lua_gettop(L)); + lua_settop(L, 0); result = llcoro::suspendUntilEventOnWithTimeout(pumpname, timeout, dftval); } else diff --git a/indra/newview/skins/default/xui/en/floater_lua_debug.xml b/indra/newview/skins/default/xui/en/floater_lua_debug.xml index 0de26161e7..f03739f7c2 100644 --- a/indra/newview/skins/default/xui/en/floater_lua_debug.xml +++ b/indra/newview/skins/default/xui/en/floater_lua_debug.xml @@ -55,6 +55,7 @@ layout="topleft" name="result_text" follows="left|top" + max_length="65536" width="515" top_delta="40" word_wrap="true" /> |