2019-06-29 11:16:31 +08:00
|
|
|
|
#include "qtcommon.h"
|
|
|
|
|
#include "extension.h"
|
2019-02-13 08:54:15 +08:00
|
|
|
|
#include "util.h"
|
2019-02-18 07:52:09 +08:00
|
|
|
|
#include <fstream>
|
2019-02-13 08:54:15 +08:00
|
|
|
|
#include <QPlainTextEdit>
|
|
|
|
|
|
2019-02-28 00:33:17 +08:00
|
|
|
|
extern const char* LUA_INTRO;
|
|
|
|
|
extern const char* LOAD_LUA_SCRIPT;
|
|
|
|
|
extern const wchar_t* LUA_ERROR;
|
|
|
|
|
|
2019-02-19 12:12:12 +08:00
|
|
|
|
constexpr auto LUA_SAVE_FILE = u8"Textractor.lua";
|
|
|
|
|
|
2019-02-17 11:53:19 +08:00
|
|
|
|
extern "C" // Lua library
|
2019-02-13 08:54:15 +08:00
|
|
|
|
{
|
2019-02-17 11:53:19 +08:00
|
|
|
|
enum LuaType { LUA_TNIL, LUA_TBOOLEAN, LUA_TLIGHTUSERDATA, LUA_TNUMBER, LUA_TSTRING, LUA_TTABLE, LUA_TFUNCTION, LUA_TUSERDATA, LUA_TTHREAD };
|
2019-02-13 08:54:15 +08:00
|
|
|
|
|
2019-02-17 11:53:19 +08:00
|
|
|
|
enum LuaStatus { LUA_OK, LUA_YIELD, LUA_ERRRUN, LUA_ERRSYNTAX, LUA_ERRMEM, LUA_ERRGCMM, LUA_ERRERR };
|
2019-02-13 08:54:15 +08:00
|
|
|
|
|
|
|
|
|
struct lua_State;
|
2019-02-17 11:53:19 +08:00
|
|
|
|
lua_State* luaL_newstate();
|
|
|
|
|
void luaL_openlibs(lua_State*);
|
|
|
|
|
void lua_close(lua_State*);
|
|
|
|
|
LuaStatus luaL_loadstring(lua_State*, const char* str);
|
|
|
|
|
|
|
|
|
|
const char* lua_tolstring(lua_State*, int index, size_t* size);
|
|
|
|
|
const char* lua_pushstring(lua_State*, const char* str);
|
|
|
|
|
void lua_pushinteger(lua_State*, int64_t n);
|
|
|
|
|
void lua_createtable(lua_State*, int narr, int nrec);
|
|
|
|
|
void lua_settable(lua_State*, int index);
|
|
|
|
|
|
|
|
|
|
void lua_settop(lua_State*, int index);
|
|
|
|
|
LuaType lua_getglobal(lua_State*, const char* name);
|
|
|
|
|
LuaStatus lua_pcallk(lua_State*, int nargs, int nresults, int msgh, void*, void*);
|
2019-02-13 08:54:15 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool luaL_dostring(lua_State* L, const char* str)
|
|
|
|
|
{
|
|
|
|
|
return luaL_loadstring(L, str) || lua_pcallk(L, 0, -1, 0, NULL, NULL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool logErrors = true;
|
2019-06-05 11:12:45 +08:00
|
|
|
|
Synchronized<std::string> script;
|
2019-02-18 07:52:09 +08:00
|
|
|
|
std::atomic<int> revCount = 0;
|
2019-02-13 08:54:15 +08:00
|
|
|
|
|
2019-06-21 13:29:48 +08:00
|
|
|
|
class Window : public QMainWindow
|
2019-02-13 08:54:15 +08:00
|
|
|
|
{
|
2019-06-21 13:29:48 +08:00
|
|
|
|
public:
|
|
|
|
|
Window()
|
2019-02-13 08:54:15 +08:00
|
|
|
|
{
|
2019-06-21 13:29:48 +08:00
|
|
|
|
connect(&loadButton, &QPushButton::clicked, this, &Window::LoadScript);
|
|
|
|
|
|
|
|
|
|
if (scriptEditor.toPlainText().isEmpty()) scriptEditor.setPlainText(LUA_INTRO);
|
|
|
|
|
layout.addWidget(&scriptEditor);
|
|
|
|
|
layout.addWidget(&loadButton);
|
|
|
|
|
|
2019-02-13 08:54:15 +08:00
|
|
|
|
resize(800, 600);
|
2019-06-21 13:29:48 +08:00
|
|
|
|
setCentralWidget(¢ralWidget);
|
2019-02-13 08:54:15 +08:00
|
|
|
|
setWindowTitle("Lua");
|
2019-06-21 13:29:48 +08:00
|
|
|
|
QMetaObject::invokeMethod(this, &QWidget::show, Qt::QueuedConnection);
|
2019-02-13 08:54:15 +08:00
|
|
|
|
}
|
2019-02-18 07:52:09 +08:00
|
|
|
|
|
2019-06-21 13:29:48 +08:00
|
|
|
|
~Window()
|
2019-02-13 08:54:15 +08:00
|
|
|
|
{
|
2019-06-21 13:29:48 +08:00
|
|
|
|
Save();
|
2019-02-13 08:54:15 +08:00
|
|
|
|
}
|
2019-06-21 13:29:48 +08:00
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
void LoadScript()
|
2019-02-13 08:54:15 +08:00
|
|
|
|
{
|
2019-06-21 13:29:48 +08:00
|
|
|
|
revCount += 1;
|
|
|
|
|
script->assign(scriptEditor.toPlainText().toUtf8());
|
|
|
|
|
Save();
|
2019-02-13 08:54:15 +08:00
|
|
|
|
}
|
2019-06-21 13:29:48 +08:00
|
|
|
|
|
|
|
|
|
void Save()
|
|
|
|
|
{
|
|
|
|
|
auto script = scriptEditor.toPlainText().toUtf8();
|
|
|
|
|
std::ofstream(LUA_SAVE_FILE, std::ios::out | std::ios::trunc).write(script, script.size());
|
2019-02-13 08:54:15 +08:00
|
|
|
|
}
|
2019-06-21 13:29:48 +08:00
|
|
|
|
|
|
|
|
|
QWidget centralWidget{ this };
|
|
|
|
|
QHBoxLayout layout{ ¢ralWidget };
|
2019-07-02 13:56:04 +08:00
|
|
|
|
QPlainTextEdit scriptEditor{ S(std::string(std::istreambuf_iterator<char>(std::ifstream(LUA_SAVE_FILE, std::ios::in)), {})), ¢ralWidget };
|
2019-06-21 13:29:48 +08:00
|
|
|
|
QPushButton loadButton{ LOAD_LUA_SCRIPT, ¢ralWidget };
|
|
|
|
|
} window;
|
2019-02-13 08:54:15 +08:00
|
|
|
|
|
|
|
|
|
bool ProcessSentence(std::wstring& sentence, SentenceInfo sentenceInfo)
|
|
|
|
|
{
|
2019-06-02 01:59:37 +08:00
|
|
|
|
thread_local static struct { std::unique_ptr<lua_State, Functor<lua_close>> L{ luaL_newstate() }; operator lua_State*() { return L.get(); } } L;
|
2019-02-13 08:54:15 +08:00
|
|
|
|
thread_local static auto _ = (luaL_openlibs(L), luaL_dostring(L, "function ProcessSentence() end"));
|
|
|
|
|
thread_local static int revCount = 0;
|
|
|
|
|
|
|
|
|
|
if (::revCount > revCount)
|
|
|
|
|
{
|
|
|
|
|
revCount = ::revCount;
|
|
|
|
|
luaL_dostring(L, "ProcessSentence = nil");
|
2019-02-18 07:52:09 +08:00
|
|
|
|
if (luaL_dostring(L, script->c_str()) != LUA_OK)
|
2019-02-13 08:54:15 +08:00
|
|
|
|
{
|
2019-06-13 16:01:29 +08:00
|
|
|
|
sentence += L"\n" + FormatString(LUA_ERROR, StringToWideString(lua_tolstring(L, 1, nullptr)));
|
2019-02-13 08:54:15 +08:00
|
|
|
|
lua_settop(L, 0);
|
|
|
|
|
return logErrors;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (lua_getglobal(L, "ProcessSentence") != LUA_TFUNCTION)
|
|
|
|
|
{
|
2019-06-13 16:01:29 +08:00
|
|
|
|
sentence += L"\n" + FormatString(LUA_ERROR, L"ProcessSentence is not a function");
|
2019-02-13 08:54:15 +08:00
|
|
|
|
lua_settop(L, 0);
|
|
|
|
|
return logErrors;
|
|
|
|
|
}
|
|
|
|
|
lua_pushstring(L, WideStringToString(sentence).c_str());
|
|
|
|
|
lua_createtable(L, 0, 0);
|
2019-06-17 05:15:47 +08:00
|
|
|
|
for (auto info = sentenceInfo.infoArray; info->name; ++info)
|
2019-02-13 08:54:15 +08:00
|
|
|
|
{
|
|
|
|
|
lua_pushstring(L, info->name);
|
|
|
|
|
lua_pushinteger(L, info->value);
|
|
|
|
|
lua_settable(L, 3);
|
|
|
|
|
}
|
|
|
|
|
if (lua_pcallk(L, 2, 1, 0, NULL, NULL) != LUA_OK)
|
|
|
|
|
{
|
2019-06-13 16:01:29 +08:00
|
|
|
|
sentence += L"\n" + FormatString(LUA_ERROR, StringToWideString(lua_tolstring(L, 1, nullptr)));
|
2019-02-13 08:54:15 +08:00
|
|
|
|
lua_settop(L, 0);
|
|
|
|
|
return logErrors;
|
|
|
|
|
}
|
2019-02-18 07:52:09 +08:00
|
|
|
|
if (const char* newSentence = lua_tolstring(L, 1, nullptr))
|
2019-02-13 08:54:15 +08:00
|
|
|
|
{
|
|
|
|
|
sentence = StringToWideString(newSentence);
|
|
|
|
|
lua_settop(L, 0);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
lua_settop(L, 0);
|
|
|
|
|
return false;
|
|
|
|
|
}
|