summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/llcommon/lua_function.cpp113
-rw-r--r--indra/llcommon/lua_function.h6
-rw-r--r--indra/llui/lltexteditor.cpp3
-rw-r--r--indra/llui/lltexteditor.h15
4 files changed, 86 insertions, 51 deletions
diff --git a/indra/llcommon/lua_function.cpp b/indra/llcommon/lua_function.cpp
index 455e853e8f..467ca04449 100644
--- a/indra/llcommon/lua_function.cpp
+++ b/indra/llcommon/lua_function.cpp
@@ -525,12 +525,15 @@ LuaPopper::~LuaPopper()
LuaFunction::LuaFunction(const std::string_view& name, lua_CFunction function,
const std::string_view& helptext)
{
- getRegistry().emplace(name, Registry::mapped_type{ function, helptext });
+ const auto& [registry, lookup] = getState();
+ registry.emplace(name, Registry::mapped_type{ function, helptext });
+ lookup.emplace(function, name);
}
void LuaFunction::init(lua_State* L)
{
- for (const auto& [name, pair]: getRegistry())
+ const auto& [registry, lookup] = getRState();
+ for (const auto& [name, pair]: registry)
{
const auto& [funcptr, helptext] = pair;
lua_register(L, name.c_str(), funcptr);
@@ -541,16 +544,75 @@ lua_CFunction LuaFunction::get(const std::string& key)
{
// use find() instead of subscripting to avoid creating an entry for
// unknown key
- const auto& registry{ getRegistry() };
+ const auto& [registry, lookup] = getState();
auto found{ registry.find(key) };
return (found == registry.end())? nullptr : found->second.first;
}
-LuaFunction::Registry& LuaFunction::getRegistry()
+std::pair<LuaFunction::Registry&, LuaFunction::Lookup&> LuaFunction::getState()
{
- // use a function-local static to ensure it's initialized
+ // use function-local statics to ensure they're initialized
static Registry registry;
- return registry;
+ static Lookup lookup;
+ return { registry, lookup };
+}
+
+/*****************************************************************************
+* help()
+*****************************************************************************/
+lua_function(help,
+ "help(): list viewer's Lua functions\n"
+ "help(function): show help string for specific function")
+{
+ auto& luapump{ LLEventPumps::instance().obtain("lua output") };
+ const auto& [registry, lookup]{ LuaFunction::getRState() };
+ if (! lua_gettop(L))
+ {
+ // no arguments passed: list all lua_functions
+ for (const auto& [name, pair] : registry)
+ {
+ const auto& [fptr, helptext] = pair;
+ luapump.post(helptext);
+ }
+ }
+ else
+ {
+ // arguments passed: list each of the specified lua_functions
+ for (int idx = 1, top = lua_gettop(L); idx <= top; ++idx)
+ {
+ std::string arg{ stringize("<unknown ", lua_typename(L, lua_type(L, idx)), ">") };
+ if (lua_type(L, idx) == LUA_TSTRING)
+ {
+ arg = lua_tostdstring(L, idx);
+ }
+ else if (lua_type(L, idx) == LUA_TFUNCTION)
+ {
+ // Caller passed the actual function instead of its string
+ // name. A Lua function is an anonymous callable object; it
+ // has a name only by assigment. You can't ask Lua for a
+ // function's name, which is why our constructor maintains a
+ // reverse Lookup map.
+ auto function{ lua_tocfunction(L, idx) };
+ if (auto found = lookup.find(function); found != lookup.end())
+ {
+ // okay, pass found name to lookup below
+ arg = found->second;
+ }
+ }
+
+ if (auto found = registry.find(arg); found != registry.end())
+ {
+ luapump.post(found->second.second);
+ }
+ else
+ {
+ luapump.post(arg + ": NOT FOUND");
+ }
+ }
+ // pop all arguments
+ lua_settop(L, 0);
+ }
+ return 0; // void return
}
/*****************************************************************************
@@ -633,42 +695,3 @@ DebugExit::~DebugExit()
{
LL_DEBUGS("Lua") << "exit " << mName << LL_ENDL;
}
-
-/*****************************************************************************
-* help()
-*****************************************************************************/
-lua_function(help,
- "help(): list viewer's Lua functions\n"
- "help(function): show help string for specific function")
-{
- auto& luapump{ LLEventPumps::instance().obtain("lua output") };
- const auto& registered{ LuaFunction::getRegistered() };
- if (! lua_gettop(L))
- {
- // no arguments passed: list all lua_functions
- for (const auto& [name, pair] : registered)
- {
- const auto& [fptr, helptext] = pair;
- luapump.post(helptext);
- }
- }
- else
- {
- // arguments passed: list each of the specified lua_functions
- for (int idx = 1, top = lua_gettop(L); idx <= top; ++idx)
- {
- auto arg{ lua_tostdstring(L, idx) };
- if (auto found = registered.find(arg); found != registered.end())
- {
- luapump.post(found->second.second);
- }
- else
- {
- luapump.post(arg + ": NOT FOUND");
- }
- }
- // pop all arguments
- lua_settop(L, 0);
- }
- return 0; // void return
-}
diff --git a/indra/llcommon/lua_function.h b/indra/llcommon/lua_function.h
index 3129b5eaca..b3a0bb0d7e 100644
--- a/indra/llcommon/lua_function.h
+++ b/indra/llcommon/lua_function.h
@@ -131,11 +131,13 @@ public:
static lua_CFunction get(const std::string& key);
+protected:
using Registry = std::map<std::string, std::pair<lua_CFunction, std::string>>;
- static const Registry& getRegistered() { return getRegistry(); }
+ using Lookup = std::map<lua_CFunction, std::string>;
+ static std::pair<const Registry&, const Lookup&> getRState() { return getState(); }
private:
- static Registry& getRegistry();
+ static std::pair<Registry&, Lookup&> getState();
};
/**
diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index 99154bab83..ccd04f83e7 100644
--- a/indra/llui/lltexteditor.cpp
+++ b/indra/llui/lltexteditor.cpp
@@ -1504,7 +1504,8 @@ void LLTextEditor::cleanStringForPaste(LLWString & clean_string)
}
-void LLTextEditor::pasteTextWithLinebreaks(const LLWString & clean_string)
+template <>
+void LLTextEditor::pasteTextWithLinebreaks<LLWString>(const LLWString & clean_string)
{
std::basic_string<llwchar>::size_type start = 0;
std::basic_string<llwchar>::size_type pos = clean_string.find('\n',start);
diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h
index 6cc2c32d4e..01b5ce5fbd 100644
--- a/indra/llui/lltexteditor.h
+++ b/indra/llui/lltexteditor.h
@@ -34,6 +34,7 @@
#include "llstyle.h"
#include "lleditmenuhandler.h"
#include "llviewborder.h" // for params
+#include "llstring.h"
#include "lltextbase.h"
#include "lltextvalidate.h"
@@ -289,16 +290,24 @@ protected:
void updateLinkSegments();
void keepSelectionOnReturn(bool keep) { mKeepSelectionOnReturn = keep; }
class LLViewBorder* mBorder;
- void pasteTextWithLinebreaks(const LLWString & clean_string);
-// void pasteTextWithLinebreaks(const std::string & clean_string);
private:
//
// Methods
//
- void pasteHelper(bool is_primary);
+ void pasteHelper(bool is_primary);
void cleanStringForPaste(LLWString & clean_string);
+public:
+ template <typename STRINGTYPE>
+ void pasteTextWithLinebreaks(const STRINGTYPE& clean_string)
+ {
+ pasteTextWithLinebreaks<LLWString>(ll_convert(clean_string));
+ }
+ template <>
+ void pasteTextWithLinebreaks<LLWString>(const LLWString & clean_string);
+
+private:
void onKeyStroke();
// Concrete TextCmd sub-classes used by the LLTextEditor base class