more lua features

This commit is contained in:
Akash Mozumdar 2019-02-17 18:52:09 -05:00
parent 48ea8f531b
commit e826801c87
4 changed files with 45 additions and 17 deletions

View File

@ -2,6 +2,7 @@
#include "util.h" #include "util.h"
#include "text.h" #include "text.h"
#include "defs.h" #include "defs.h"
#include <fstream>
#include <QMainWindow> #include <QMainWindow>
#include <QLayout> #include <QLayout>
#include <QPlainTextEdit> #include <QPlainTextEdit>
@ -37,32 +38,38 @@ bool luaL_dostring(lua_State* L, const char* str)
} }
bool logErrors = true; bool logErrors = true;
ThreadSafe<std::string> script;
std::mutex m; std::atomic<int> revCount = 0;
std::string script;
int revCount = 0;
struct : QMainWindow struct : QMainWindow
{ {
void launch() void launch()
{ {
auto centralWidget = new QWidget(this); auto centralWidget = new QWidget(this);
auto layout = new QVBoxLayout(centralWidget); auto layout = new QHBoxLayout(centralWidget);
auto scriptEditor = new QPlainTextEdit(centralWidget); auto scriptEditor = new QPlainTextEdit(std::string(std::istreambuf_iterator<char>(std::ifstream(LUA_SAVE_FILE, std::ios::in)), {}).c_str(), centralWidget);
auto loadButton = new QPushButton("Load Script", centralWidget); auto loadButton = new QPushButton(LOAD_LUA_SCRIPT, centralWidget);
if (scriptEditor->toPlainText().isEmpty()) scriptEditor->setPlainText(LUA_INTRO);
layout->addWidget(scriptEditor); layout->addWidget(scriptEditor);
layout->addWidget(loadButton); layout->addWidget(loadButton);
save = [=]
{
auto script = scriptEditor->toPlainText().toUtf8();
std::ofstream(LUA_SAVE_FILE, std::ios::out | std::ios::trunc).write(script, strlen(script));
};
connect(loadButton, &QPushButton::clicked, [=](bool) connect(loadButton, &QPushButton::clicked, [=](bool)
{ {
std::lock_guard l(m);
++revCount; ++revCount;
script = scriptEditor->toPlainText().toUtf8(); script->assign(scriptEditor->toPlainText().toUtf8());
save();
}); });
resize(800, 600); resize(800, 600);
setCentralWidget(centralWidget); setCentralWidget(centralWidget);
setWindowTitle("Lua"); setWindowTitle("Lua");
show(); show();
} }
std::function<void()> save;
}*window = nullptr; }*window = nullptr;
BOOL WINAPI DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) BOOL WINAPI DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
@ -73,18 +80,16 @@ BOOL WINAPI DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved
{ {
QTimer::singleShot(0, [] QTimer::singleShot(0, []
{ {
std::lock_guard l(m);
(window = new std::remove_pointer_t<decltype(window)>)->launch(); (window = new std::remove_pointer_t<decltype(window)>)->launch();
}); });
} }
break; break;
case DLL_PROCESS_DETACH: case DLL_PROCESS_DETACH:
{ {
window->save();
if (lpReserved == NULL) // https://blogs.msdn.microsoft.com/oldnewthing/20120105-00/?p=8683 if (lpReserved == NULL) // https://blogs.msdn.microsoft.com/oldnewthing/20120105-00/?p=8683
{ {
std::lock_guard l(m);
delete window; delete window;
window = nullptr;
} }
} }
break; break;
@ -101,12 +106,11 @@ bool ProcessSentence(std::wstring& sentence, SentenceInfo sentenceInfo)
if (::revCount > revCount) if (::revCount > revCount)
{ {
std::lock_guard l(m);
revCount = ::revCount; revCount = ::revCount;
luaL_dostring(L, "ProcessSentence = nil"); luaL_dostring(L, "ProcessSentence = nil");
if (luaL_dostring(L, script.c_str()) != LUA_OK) if (luaL_dostring(L, script->c_str()) != LUA_OK)
{ {
sentence += NEWLINE + LUA_ERROR + StringToWideString(lua_tolstring(L, -1, nullptr)); sentence += NEWLINE + LUA_ERROR + StringToWideString(lua_tolstring(L, 1, nullptr));
lua_settop(L, 0); lua_settop(L, 0);
return logErrors; return logErrors;
} }
@ -128,11 +132,11 @@ bool ProcessSentence(std::wstring& sentence, SentenceInfo sentenceInfo)
} }
if (lua_pcallk(L, 2, 1, 0, NULL, NULL) != LUA_OK) if (lua_pcallk(L, 2, 1, 0, NULL, NULL) != LUA_OK)
{ {
sentence += NEWLINE + LUA_ERROR + StringToWideString(lua_tolstring(L, -1, nullptr)); sentence += NEWLINE + LUA_ERROR + StringToWideString(lua_tolstring(L, 1, nullptr));
lua_settop(L, 0); lua_settop(L, 0);
return logErrors; return logErrors;
} }
if (const char* newSentence = lua_tolstring(L, -1, nullptr)) if (const char* newSentence = lua_tolstring(L, 1, nullptr))
{ {
sentence = StringToWideString(newSentence); sentence = StringToWideString(newSentence);
lua_settop(L, 0); lua_settop(L, 0);

View File

@ -31,6 +31,7 @@ constexpr auto HOOK_SAVE_FILE = u8"SavedHooks.txt";
constexpr auto GAME_SAVE_FILE = u8"SavedGames.txt"; constexpr auto GAME_SAVE_FILE = u8"SavedGames.txt";
constexpr auto EXTEN_SAVE_FILE = u8"SavedExtensions.txt"; constexpr auto EXTEN_SAVE_FILE = u8"SavedExtensions.txt";
constexpr auto REPLACE_SAVE_FILE = u8"SavedReplacements.txt"; constexpr auto REPLACE_SAVE_FILE = u8"SavedReplacements.txt";
constexpr auto LUA_SAVE_FILE = u8"Textractor.lua";
// Misc // Misc

View File

@ -55,6 +55,8 @@ extern const char* BG_COLOR;
extern const char* TEXT_COLOR; extern const char* TEXT_COLOR;
extern const char* FONT_SIZE; extern const char* FONT_SIZE;
extern const char* TOPMOST; extern const char* TOPMOST;
extern const char* LUA_INTRO;
extern const char* LOAD_LUA_SCRIPT;
extern const wchar_t* LUA_ERROR; extern const wchar_t* LUA_ERROR;
extern const char* REGEX_FILTER; extern const char* REGEX_FILTER;
extern const char* INVALID_REGEX; extern const char* INVALID_REGEX;

View File

@ -84,6 +84,27 @@ const char* BG_COLOR = u8"Background Color";
const char* TEXT_COLOR = u8"Text Color"; const char* TEXT_COLOR = u8"Text Color";
const char* FONT_SIZE = u8"Font Size"; const char* FONT_SIZE = u8"Font Size";
const char* TOPMOST = u8"Always on Top"; const char* TOPMOST = u8"Always on Top";
const char* LUA_INTRO = u8R"(--[[
ProcessSentence is called each time Textractor receives a sentence of text.
Param sentence: sentence received by Textractor (UTF-8).
Param sentenceInfo: table of miscellaneous info about the sentence.
If you return a string, the sentence will be turned into that string.
If you return nil, the sentence will be unmodified.
This extension uses several copies of the Lua interpreter for thread safety.
Modifications to global variables from ProcessSentence are not guaranteed to persist.
Properties in sentenceInfo:
"current select": 0 unless sentence is in the text thread currently selected by the user.
"process id": process id that the sentence is coming from. 0 for console and clipboard.
"text number": number of the current text thread. Counts up one by one as text threads are created. 0 for console, 1 for clipboard.
--]]
function ProcessSentence(sentence, sentenceInfo)
--Your code here...
end)";
const char* LOAD_LUA_SCRIPT = u8"Load Script";
const wchar_t* LUA_ERROR = L"Lua error: "; const wchar_t* LUA_ERROR = L"Lua error: ";
const char* REGEX_FILTER = u8"Regex Filter"; const char* REGEX_FILTER = u8"Regex Filter";
const char* INVALID_REGEX = u8"Invalid regex"; const char* INVALID_REGEX = u8"Invalid regex";