diff options
Diffstat (limited to 'indra/newview')
-rw-r--r-- | indra/newview/llappviewer.cpp | 26 | ||||
-rw-r--r-- | indra/newview/llluamanager.cpp | 62 | ||||
-rw-r--r-- | indra/newview/llluamanager.h | 22 | ||||
-rw-r--r-- | indra/newview/scripts/lua/frame_profile_quit.lua | 17 | ||||
-rw-r--r-- | indra/newview/scripts/lua/require/login.lua | 11 |
5 files changed, 75 insertions, 63 deletions
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index b4fe27f57a..295e22777e 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -1232,23 +1232,8 @@ bool LLAppViewer::init() "--luafile", "LuaScript", [](const LLSD& script) { - LLSD paths(gSavedSettings.getLLSD("LuaCommandPath")); - LL_DEBUGS("Lua") << "LuaCommandPath = " << paths << LL_ENDL; - for (const auto& path : llsd::inArray(paths)) - { - // if script path is already absolute, operator/() preserves it - auto abspath(fsyspath(gDirUtilp->getAppRODataDir()) / path.asString()); - auto absscript{ (abspath / script.asString()) }; - std::error_code ec; - if (std::filesystem::exists(absscript, ec)) - { - // no completion callback: we don't need to know - LLLUAmanager::runScriptFile(absscript.u8string()); - return; // from lambda - } - } - LL_WARNS("Lua") << "--luafile " << std::quoted(script.asString()) - << " not found on " << paths << LL_ENDL; + // no completion callback: we don't need to know + LLLUAmanager::runScriptFile(script); }); processComposeSwitch( "LuaAutorunPath", "LuaAutorunPath", @@ -1257,15 +1242,16 @@ bool LLAppViewer::init() // each directory can be relative to the viewer's install // directory -- if directory is already absolute, operator/() // preserves it - auto abspath(fsyspath(gDirUtilp->getAppRODataDir()) / directory.asString()); - std::string absdir(abspath.string()); + fsyspath abspath(fsyspath(gDirUtilp->getAppRODataDir()) / + fsyspath(directory.asString())); + std::string absdir(fsyspath(abspath).string()); LL_DEBUGS("InitInfo") << "LuaAutorunPath: " << absdir << LL_ENDL; LLDirIterator scripts(absdir, "*.lua"); std::string script; while (scripts.next(script)) { LL_DEBUGS("InitInfo") << "LuaAutorunPath: " << absdir << ": " << script << LL_ENDL; - LLLUAmanager::runScriptFile((abspath / script).string(), true); + LLLUAmanager::runScriptFile(fsyspath(abspath / fsyspath(script)).string(), true); } }); diff --git a/indra/newview/llluamanager.cpp b/indra/newview/llluamanager.cpp index 0bd21516bc..7fe5c1ece0 100644 --- a/indra/newview/llluamanager.cpp +++ b/indra/newview/llluamanager.cpp @@ -186,41 +186,44 @@ LLLUAmanager::script_result LLLUAmanager::waitScriptFile(const std::string& file } void LLLUAmanager::runScriptFile(const std::string &filename, bool autorun, - script_result_fn result_cb, script_finished_fn finished_cb) + script_result_fn result_cb) { // A script_result_fn will be called when LuaState::expr() completes. - LLCoros::instance().launch(filename, [filename, autorun, result_cb, finished_cb]() + LLCoros::instance().launch(filename, [filename, autorun, result_cb]() { ScriptObserver observer(LLCoros::getName(), filename); - llifstream in_file; - in_file.open(filename.c_str()); - - if (in_file.is_open()) + LLSD paths(gSavedSettings.getLLSD("LuaCommandPath")); + LL_DEBUGS("Lua") << "LuaCommandPath = " << paths << LL_ENDL; + // allow LuaCommandPath to be specified relative to install dir + ScriptCommand command(filename, paths, gDirUtilp->getAppRODataDir()); + auto error = command.error(); + if (! error.empty()) { - if (autorun) - { - sAutorunScriptCount++; - } - sScriptCount++; - - // A script_finished_fn is used to initialize the LuaState. - // It will be called when the LuaState is destroyed. - LuaState L(finished_cb); - std::string text{std::istreambuf_iterator<char>(in_file), {}}; - auto [count, result] = L.expr(filename, text); if (result_cb) { - result_cb(count, result); + result_cb(-1, error); } + return; + } + + llifstream in_file; + in_file.open(command.script); + // At this point, since ScriptCommand did not report an error, we + // should be able to assume that 'script' exists. If we can't open it, + // something else is wrong?! + llassert(in_file.is_open()); + if (autorun) + { + sAutorunScriptCount++; } - else + sScriptCount++; + + LuaState L; + std::string text{std::istreambuf_iterator<char>(in_file), {}}; + auto [count, result] = L.expr(command.script, text, command.args); + if (result_cb) { - auto msg{ stringize("unable to open script file '", filename, "'") }; - LL_WARNS("Lua") << msg << LL_ENDL; - if (result_cb) - { - result_cb(-1, msg); - } + result_cb(count, result); } }); } @@ -242,8 +245,7 @@ LLLUAmanager::script_result LLLUAmanager::waitScriptLine(const std::string& chun return startScriptLine(chunk).get(); } -void LLLUAmanager::runScriptLine(const std::string& chunk, script_result_fn result_cb, - script_finished_fn finished_cb) +void LLLUAmanager::runScriptLine(const std::string& chunk, script_result_fn result_cb) { // find a suitable abbreviation for the chunk string std::string shortchunk{ chunk }; @@ -255,11 +257,9 @@ void LLLUAmanager::runScriptLine(const std::string& chunk, script_result_fn resu shortchunk = stringize(shortchunk.substr(0, shortlen), "..."); std::string desc{ "lua: " + shortchunk }; - LLCoros::instance().launch(desc, [desc, chunk, result_cb, finished_cb]() + LLCoros::instance().launch(desc, [desc, chunk, result_cb]() { - // A script_finished_fn is used to initialize the LuaState. - // It will be called when the LuaState is destroyed. - LuaState L(finished_cb); + LuaState L; auto [count, result] = L.expr(desc, chunk); if (result_cb) { diff --git a/indra/newview/llluamanager.h b/indra/newview/llluamanager.h index df76ddd3e2..b98b5d4ef6 100644 --- a/indra/newview/llluamanager.h +++ b/indra/newview/llluamanager.h @@ -44,9 +44,6 @@ class LLLUAmanager friend class ScriptObserver; public: - // Pass a callback with this signature to obtain the error message, if - // any, from running a script or source string. Empty msg means success. - typedef std::function<void(std::string msg)> script_finished_fn; // Pass a callback with this signature to obtain the result, if any, of // running a script or source string. // count < 0 means error, and result.asString() is the error message. @@ -58,20 +55,31 @@ public: // same semantics as script_result_fn parameters typedef std::pair<int, LLSD> script_result; - static void runScriptFile(const std::string &filename, bool autorun = false, script_result_fn result_cb = {}, - script_finished_fn finished_cb = {}); + // Run the script specified by the command line passed as @a filename. + // This can be followed by some number of command-line arguments, which + // a Lua script can view using either '...' or predefined global 'arg'. + // The script pathname or its arguments can be quoted using 'single + // quotes' or "double quotes", or special characters can be \escaped. + // runScriptFile() recognizes the case in which the whole 'filename' + // string is a path containing spaces; if so no arguments are permitted. + // In either form, if the script pathname isn't absolute, it is sought on + // LuaCommandPath. + // If autorun is true, statistics will count this as an autorun script. + static void runScriptFile(const std::string &filename, bool autorun = false, + script_result_fn result_cb = {}); // Start running a Lua script file, returning an LLCoros::Future whose // get() method will pause the calling coroutine until it can deliver the // (count, result) pair described above. Between startScriptFile() and // Future::get(), the caller and the Lua script coroutine will run // concurrently. + // @a filename is as described for runScriptFile(). static LLCoros::Future<script_result> startScriptFile(const std::string& filename); // Run a Lua script file, and pause the calling coroutine until it completes. // The return value is the (count, result) pair described above. + // @a filename is as described for runScriptFile(). static script_result waitScriptFile(const std::string& filename); - static void runScriptLine(const std::string &chunk, script_result_fn result_cb = {}, - script_finished_fn finished_cb = {}); + static void runScriptLine(const std::string &chunk, script_result_fn result_cb = {}); // Start running a Lua chunk, returning an LLCoros::Future whose // get() method will pause the calling coroutine until it can deliver the // (count, result) pair described above. Between startScriptLine() and diff --git a/indra/newview/scripts/lua/frame_profile_quit.lua b/indra/newview/scripts/lua/frame_profile_quit.lua index e3177a3f67..ad136c86d2 100644 --- a/indra/newview/scripts/lua/frame_profile_quit.lua +++ b/indra/newview/scripts/lua/frame_profile_quit.lua @@ -1,5 +1,11 @@ -- Trigger Develop -> Render Tests -> Frame Profile and quit +assert(arg.n == 3, 'Usage: frame_profile_quit.lua x y z (for camera focus)') +-- Try coercing string arguments to numbers, using Lua's implicit conversion. +-- If the args passed as x, y, z won't convert nicely to numbers, better find +-- out now. +focus = {arg[1]+0, arg[2]+0, arg[3]+0} + LLAgent = require 'LLAgent' logout = require 'logout' startup = require 'startup' @@ -8,11 +14,14 @@ UI = require 'UI' startup.wait('STATE_STARTED') --- Assume we logged into http://maps.secondlife.com/secondlife/Bug%20Island/220/224/27 --- (see frame_profile bash script) +-- Figure out where we are +camera = LLAgent.getRegionPosition() +-- assume z is the agent's feet, add 2 meters +camera[2] += 2 + Timer(10, 'wait') -LLAgent.setCamera{camera_pos={220, 224, 26}, camera_locked=true, - focus_pos ={228, 232, 26}, focus_locked=true} +LLAgent.setCamera{camera_pos=camera, camera_locked=true, + focus_pos=focus, focus_locked=true} Timer(1, 'wait') -- This freezes the viewer for perceptible realtime UI.popup:tip('starting Render Tests -> Frame Profile') diff --git a/indra/newview/scripts/lua/require/login.lua b/indra/newview/scripts/lua/require/login.lua index 919434f3a5..37c9093a21 100644 --- a/indra/newview/scripts/lua/require/login.lua +++ b/indra/newview/scripts/lua/require/login.lua @@ -18,16 +18,25 @@ local function ensure_login_state(op) end end +local function fullgrid(grid) + if string.find(grid, '.', 1, true) then + return grid + else + return `util.{grid}.secondlife.com` + end +end + function login.login(...) ensure_login_state('login') local args = mapargs('username,grid,slurl', ...) args.op = 'login' + args.grid = fullgrid(args.grid) return leap.request('LLPanelLogin', args) end function login.savedLogins(grid) ensure_login_state('savedLogins') - return leap.request('LLPanelLogin', {op='savedLogins', grid=grid})['logins'] + return leap.request('LLPanelLogin', {op='savedLogins', grid=fullgrid(grid)})['logins'] end return login |