summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/llfloaterluadebug.cpp8
-rw-r--r--indra/newview/llluamanager.cpp90
-rw-r--r--indra/newview/tests/llluamanager_test.cpp35
3 files changed, 39 insertions, 94 deletions
diff --git a/indra/newview/llfloaterluadebug.cpp b/indra/newview/llfloaterluadebug.cpp
index 2d9dc89340..b63600e0e6 100644
--- a/indra/newview/llfloaterluadebug.cpp
+++ b/indra/newview/llfloaterluadebug.cpp
@@ -58,7 +58,7 @@ BOOL LLFloaterLUADebug::postBuild()
.listen("LLFloaterLUADebug",
[mResultOutput=mResultOutput](const LLSD& data)
{
- mResultOutput->insertText(data.asString());
+ mResultOutput->pasteTextWithLinebreaks(data.asString());
mResultOutput->addLineBreakChar(true);
return false;
});
@@ -125,13 +125,13 @@ void LLFloaterLUADebug::completion(int count, const LLSD& result)
{
// error: show error message
mResultOutput->insertText("*** ");
- mResultOutput->insertText(result.asString());
+ mResultOutput->pasteTextWithLinebreaks(result.asString());
return;
}
if (count == 1)
{
// single result
- mResultOutput->insertText(stringize(result));
+ mResultOutput->pasteTextWithLinebreaks(stringize(result));
return;
}
// 0 or multiple results
@@ -139,7 +139,7 @@ void LLFloaterLUADebug::completion(int count, const LLSD& result)
for (const auto& item : llsd::inArray(result))
{
mResultOutput->insertText(sep);
- mResultOutput->insertText(stringize(item));
+ mResultOutput->pasteTextWithLinebreaks(stringize(item));
sep = ", ";
}
}
diff --git a/indra/newview/llluamanager.cpp b/indra/newview/llluamanager.cpp
index 4463fe65f5..0c39f6c8df 100644
--- a/indra/newview/llluamanager.cpp
+++ b/indra/newview/llluamanager.cpp
@@ -167,82 +167,34 @@ lua_function(post_on, "post_on(pumpname, data): post specified data to specified
return 0;
}
-lua_function(listen_events,
- "listen_events(callback): call callback(pumpname, data) with events received\n"
- "on this Lua chunk's replypump.\n"
- "Returns replypump, commandpump: names of LLEventPumps specific to this chunk.")
+lua_function(get_event_pumps,
+ "get_event_pumps():\n"
+ "Returns replypump, commandpump: names of LLEventPumps specific to this chunk.\n"
+ "Events posted to replypump are queued for get_event_next().\n"
+ "post_on(commandpump, ...) to engage LLEventAPI operations (see helpleap()).")
{
- if (! lua_isfunction(L, 1))
- {
- luaL_typeerror(L, 1, "function");
- return 0;
- }
luaL_checkstack(L, 2, nullptr);
-
-/*==========================================================================*|
- // Get the lua_State* for the main thread of this state, in case we were
- // called from a coroutine thread. We're going to make callbacks into Lua
- // code, and we want to do it on the main thread rather than a (possibly
- // suspended) coroutine thread.
- // Registry table is at pseudo-index LUA_REGISTRYINDEX
- // Main thread is at registry key LUA_RIDX_MAINTHREAD
- auto regtype {lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_MAINTHREAD)};
- // Not finding the main thread at the documented place isn't a user error,
- // it's a Problem
- llassert_always(regtype == LUA_TTHREAD);
- lua_State* mainthread{ lua_tothread(L, -1) };
- // pop the main thread
- lua_pop(L, 1);
-|*==========================================================================*/
- // Luau is based on Lua 5.1, and Lua 5.1 apparently provides no way to get
- // back to the main thread from a coroutine thread?
- lua_State* mainthread{ L };
-
- luaL_checkstack(mainthread, 1, nullptr);
- LuaListener::ptr_t listener;
- // Does the main thread already have a LuaListener stored in the registry?
- // That is, has this Lua chunk already called listen_events()?
- auto keytype{ lua_getfield(mainthread, LUA_REGISTRYINDEX, "event.listener") };
- llassert(keytype == LUA_TNIL || keytype == LUA_TNUMBER);
- if (keytype == LUA_TNUMBER)
- {
- // We do already have a LuaListener. Retrieve it.
- int isint;
- listener = LuaListener::getInstance(lua_tointegerx(mainthread, -1, &isint));
- // pop the int "event.listener" key
- lua_pop(mainthread, 1);
- // Nobody should have destroyed this LuaListener instance!
- llassert(isint && listener);
- }
- else
- {
- // pop the nil "event.listener" key
- lua_pop(mainthread, 1);
- // instantiate a new LuaListener, binding the mainthread state -- but
- // use a no-op deleter: we do NOT want to delete this new LuaListener
- // on return from listen_events()!
- listener.reset(new LuaListener(mainthread), [](LuaListener*){});
- // set its key in the field where we'll look for it later
- lua_pushinteger(mainthread, listener->getKey());
- lua_setfield(mainthread, LUA_REGISTRYINDEX, "event.listener");
- }
-
- // Now that we've found or created our LuaListener, store the passed Lua
- // function as the callback. Beware: our caller passed the function on L's
- // stack, but we want to store it on the mainthread registry.
- if (L != mainthread)
- {
- // push 1 value (the Lua function) from L's stack to mainthread's
- lua_xmove(L, mainthread, 1);
- }
- lua_setfield(mainthread, LUA_REGISTRYINDEX, "event.function");
-
+ auto listener{ LuaState::obtainListener(L) };
// return the reply pump name and the command pump name on caller's lua_State
lua_pushstdstring(L, listener->getReplyName());
lua_pushstdstring(L, listener->getCommandName());
return 2;
}
+lua_function(get_event_next,
+ "get_event_next():\n"
+ "Returns the next (pumpname, data) pair from the replypump whose name\n"
+ "is returned by get_event_pumps(). Blocks the calling chunk until an\n"
+ "event becomes available.")
+{
+ luaL_checkstack(L, 2, nullptr);
+ auto listener{ LuaState::obtainListener(L) };
+ const auto& [pump, data]{ listener->getNext() };
+ lua_pushstdstring(L, pump);
+ lua_pushllsd(L, data);
+ return 2;
+}
+
lua_function(await_event,
"await_event(pumpname [, timeout [, value to return if timeout (default nil)]]):\n"
"pause the running Lua chunk until the next event on the named LLEventPump")
@@ -370,7 +322,7 @@ void LLLUAmanager::runScriptLine(LuaState& L, const std::string& chunk, script_r
if (shortchunk.length() > shortlen)
shortchunk = stringize(shortchunk.substr(0, shortlen), "...");
- std::string desc{ stringize("runScriptLine('", shortchunk, "')") };
+ std::string desc{ stringize("lua: ", shortchunk) };
LLCoros::instance().launch(desc, [&L, desc, chunk, cb]()
{
auto [count, result] = L.expr(desc, chunk);
diff --git a/indra/newview/tests/llluamanager_test.cpp b/indra/newview/tests/llluamanager_test.cpp
index 1f25fd5f3b..81ec186cf4 100644
--- a/indra/newview/tests/llluamanager_test.cpp
+++ b/indra/newview/tests/llluamanager_test.cpp
@@ -108,7 +108,6 @@ namespace tut
replypump.listen("llluamanager_test",
listener([&fromlua](const LLSD& data){ fromlua = data; })));
const std::string lua(stringize(
- "-- test LLSD synthesized by Lua\n",
"data = ", construct, "\n"
"post_on('testpump', data)\n"
));
@@ -134,7 +133,7 @@ namespace tut
template<> template<>
void object::test<3>()
{
- set_test_name("test post_on(), listen_events(), await_event()");
+ set_test_name("test post_on(), get_event_pumps(), get_event_next()");
StringVec posts;
LLEventStream replypump("testpump");
LLTempBoundListener conn(
@@ -142,17 +141,14 @@ namespace tut
listener([&posts](const LLSD& data)
{ posts.push_back(data.asString()); })));
const std::string lua(
- "-- test post_on,listen_events,await_event\n"
+ "-- test post_on,get_event_pumps,get_event_next\n"
"post_on('testpump', 'entry')\n"
- "callback = function(pump, data)\n"
- " -- just echo the data we received\n"
- " post_on('testpump', data)\n"
- "end\n"
- "post_on('testpump', 'listen_events()')\n"
- "replypump, cmdpump = listen_events(callback)\n"
+ "post_on('testpump', 'get_event_pumps()')\n"
+ "replypump, cmdpump = get_event_pumps()\n"
"post_on('testpump', replypump)\n"
- "post_on('testpump', 'await_event()')\n"
- "await_event(replypump)\n"
+ "post_on('testpump', 'get_event_next()')\n"
+ "pump, data = get_event_next()\n"
+ "post_on('testpump', data)\n"
"post_on('testpump', 'exit')\n"
);
LuaState L;
@@ -162,9 +158,9 @@ namespace tut
auto future = LLLUAmanager::startScriptLine(L, lua);
StringVec expected{
"entry",
- "listen_events()",
+ "get_event_pumps()",
"",
- "await_event()",
+ "get_event_next()",
"message",
"exit"
};
@@ -188,18 +184,15 @@ namespace tut
listener([&reply](const LLSD& post){ reply = post; })));
const std::string lua(
"-- test LLSD round trip\n"
- "callback = function(pump, data)\n"
- " -- just echo the data we received\n"
- " post_on('testpump', data)\n"
- "end\n"
- "replypump, cmdpump = listen_events(callback)\n"
+ "replypump, cmdpump = get_event_pumps()\n"
"post_on('testpump', replypump)\n"
- "await_event(replypump)\n"
+ "pump, data = get_event_next()\n"
+ "return data\n"
);
LuaState L;
auto future = LLLUAmanager::startScriptLine(L, lua);
// We woke up again ourselves because the coroutine running Lua has
- // reached the await_event() call, which suspends the calling C++
+ // reached the get_event_next() call, which suspends the calling C++
// coroutine (including the Lua code running on it) until we post
// something to that reply pump.
auto luapump{ reply.asString() };
@@ -208,7 +201,7 @@ namespace tut
// The C++ coroutine running the Lua script is now ready to run. Run
// it so it will echo the LLSD back to us.
auto [count, result] = future.get();
- ensure_equals(desc, reply, expect);
+ ensure_equals(desc, result, expect);
}
// Define an RTItem to be used for round-trip LLSD testing: what it is,