summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorNat Goodspeed <nat@lindenlab.com>2024-03-24 02:16:55 +0900
committerNat Goodspeed <nat@lindenlab.com>2024-03-24 02:16:55 +0900
commit93b30f960ea327fe3c36deed72a8075ce0d13f19 (patch)
tree10894a7372bfed0ae94f7217e03c8d03050a042e /indra
parent2dc003779443db99f46b3db6d17a1954f7b141dd (diff)
Introduce LLStreamListener: bundle LLEventStream+LLTempBoundListener.
This is a very common pattern, especially in test code, but elsewhere in the viewer too. Use it in llluamanager_test.cpp.
Diffstat (limited to 'indra')
-rw-r--r--indra/llcommon/llevents.h43
-rw-r--r--indra/newview/tests/llluamanager_test.cpp53
2 files changed, 64 insertions, 32 deletions
diff --git a/indra/llcommon/llevents.h b/indra/llcommon/llevents.h
index 1f35a6de18..ebc893d1e6 100644
--- a/indra/llcommon/llevents.h
+++ b/indra/llcommon/llevents.h
@@ -151,6 +151,8 @@ typedef boost::signals2::signal<bool(const LLSD&), LLStopWhenHandled, float> LL
/// Methods that forward listeners (e.g. constructed with
/// <tt>boost::bind()</tt>) should accept (const LLEventListener&)
typedef LLStandardSignal::slot_type LLEventListener;
+/// Accept a void listener too
+typedef std::function<void(const LLSD&)> LLVoidListener;
/// Result of registering a listener, supports <tt>connected()</tt>,
/// <tt>disconnect()</tt> and <tt>blocked()</tt>
typedef boost::signals2::connection LLBoundListener;
@@ -158,6 +160,23 @@ typedef boost::signals2::connection LLBoundListener;
/// referenced listener when the LLTempBoundListener instance is destroyed.
typedef boost::signals2::scoped_connection LLTempBoundListener;
+/// Accepting (const LLListener&) allows either LLEventListener or LLVoidListener
+/// TODO: but compiler considers the constructor call ambiguous??
+class LLListener
+{
+public:
+ LLListener(const LLEventListener& listener):
+ mListener(listener)
+ {}
+ LLListener(const LLVoidListener& listener):
+ mListener([listener](const LLSD& data){ listener(data); return false; })
+ {}
+ operator LLEventListener() const { return mListener; }
+
+private:
+ LLEventListener mListener;
+};
+
/**
* A common idiom for event-based code is to accept either a callable --
* directly called on completion -- or the string name of an LLEventPump on
@@ -688,6 +707,30 @@ private:
};
/*****************************************************************************
+* LLNamedListener
+*****************************************************************************/
+/**
+ * LLNamedListener bundles a concrete LLEventPump subclass with a specific
+ * listener function, with an LLTempBoundListener to ensure that it's
+ * disconnected before destruction.
+ */
+template <class PUMP=LLEventStream>
+class LL_COMMON_API LLNamedListener: PUMP
+{
+ using pump_t = PUMP;
+public:
+ template <typename LISTENER>
+ LLNamedListener(const std::string& name, LISTENER&& listener):
+ pump_t(name, false), // don't tweak the name
+ mConn(pump_t::listen("func", std::forward<LISTENER>(listener)))
+ {}
+
+private:
+ LLTempBoundListener mConn;
+};
+using LLStreamListener = LLNamedListener<>;
+
+/*****************************************************************************
* LLReqID
*****************************************************************************/
/**
diff --git a/indra/newview/tests/llluamanager_test.cpp b/indra/newview/tests/llluamanager_test.cpp
index 0fd91c1354..872d7827fe 100644
--- a/indra/newview/tests/llluamanager_test.cpp
+++ b/indra/newview/tests/llluamanager_test.cpp
@@ -105,10 +105,8 @@ namespace tut
void from_lua(const std::string& desc, const std::string_view& construct, const LLSD& expect)
{
LLSD fromlua;
- LLEventStream replypump("testpump");
- LLTempBoundListener conn(
- replypump.listen("llluamanager_test",
- listener([&fromlua](const LLSD& data){ fromlua = data; })));
+ LLStreamListener pump("testpump",
+ listener([&fromlua](const LLSD& data){ fromlua = data; }));
const std::string lua(stringize(
"data = ", construct, "\n"
"post_on('testpump', data)\n"
@@ -137,11 +135,9 @@ namespace tut
{
set_test_name("test post_on(), get_event_pumps(), get_event_next()");
StringVec posts;
- LLEventStream replypump("testpump");
- LLTempBoundListener conn(
- replypump.listen("test<3>",
- listener([&posts](const LLSD& data)
- { posts.push_back(data.asString()); })));
+ LLStreamListener pump("testpump",
+ listener([&posts](const LLSD& data)
+ { posts.push_back(data.asString()); }));
const std::string lua(
"-- test post_on,get_event_pumps,get_event_next\n"
"post_on('testpump', 'entry')\n"
@@ -180,7 +176,7 @@ namespace tut
void round_trip(const std::string& desc, const LLSD& send, const LLSD& expect)
{
- LLEventMailDrop replypump("testpump");
+ LLEventMailDrop testpump("testpump");
const std::string lua(
"-- test LLSD round trip\n"
"replypump, cmdpump = get_event_pumps()\n"
@@ -194,7 +190,7 @@ namespace tut
// 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{ llcoro::suspendUntilEventOn(replypump).asString() };
+ auto luapump{ llcoro::suspendUntilEventOn(testpump).asString() };
LLEventPumps::instance().post(luapump, send);
// The C++ coroutine running the Lua script is now ready to run. Run
// it so it will echo the LLSD back to us.
@@ -319,18 +315,13 @@ namespace tut
"}\n"
);
- LLEventStream pump("echo", false);
- LLTempBoundListener conn{
- pump.listen(
- "test<5>()",
- listener([](const LLSD& data)
- {
- LL_DEBUGS("Lua") << "echo pump got: " << data << LL_ENDL;
- LLEventPumps::instance().post(
- data["reply"],
- llsd::map("reqid", data["reqid"], "data", data["data"]));
- }))
- };
+ LLStreamListener pump(
+ "echo",
+ listener([](const LLSD& data)
+ {
+ LL_DEBUGS("Lua") << "echo pump got: " << data << LL_ENDL;
+ sendReply(data, data);
+ }));
LuaState L;
auto [count, result] = LLLUAmanager::waitScriptLine(L, lua);
@@ -397,15 +388,13 @@ namespace tut
);
LLSD requests;
- LLEventStream pump("testpump", false);
- LLTempBoundListener conn{
- pump.listen("test<6>()",
- listener([&requests](const LLSD& data)
- {
- LL_DEBUGS("Lua") << "testpump got: " << data << LL_ENDL;
- requests.append(data);
- }))
- };
+ LLStreamListener pump(
+ "testpump",
+ listener([&requests](const LLSD& data)
+ {
+ LL_DEBUGS("Lua") << "testpump got: " << data << LL_ENDL;
+ requests.append(data);
+ }));
LuaState L;
auto future = LLLUAmanager::startScriptLine(L, lua);