fix(lua): share environment between command bar calls
This commit is contained in:
parent
133ca0bb5e
commit
e40b594ae5
2 changed files with 39 additions and 0 deletions
|
@ -1,5 +1,6 @@
|
||||||
#include "commandedit.h"
|
#include "commandedit.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
#include "logger.h"
|
||||||
#include "lua.h"
|
#include "lua.h"
|
||||||
#include "objects/service/script/scriptcontext.h"
|
#include "objects/service/script/scriptcontext.h"
|
||||||
#include "luaapis.h" // IWYU pragma: keep
|
#include "luaapis.h" // IWYU pragma: keep
|
||||||
|
@ -18,6 +19,9 @@ CommandEdit::~CommandEdit() = default;
|
||||||
void CommandEdit::executeCommand() {
|
void CommandEdit::executeCommand() {
|
||||||
std::string command = this->text().toStdString();
|
std::string command = this->text().toStdString();
|
||||||
|
|
||||||
|
// Output
|
||||||
|
Logger::infof("> %s", command.c_str());
|
||||||
|
|
||||||
// Execute via Lua
|
// Execute via Lua
|
||||||
auto context = gDataModel->GetService<ScriptContext>();
|
auto context = gDataModel->GetService<ScriptContext>();
|
||||||
lua_State* L = context->state;
|
lua_State* L = context->state;
|
||||||
|
@ -25,6 +29,11 @@ void CommandEdit::executeCommand() {
|
||||||
int top = lua_gettop(L);
|
int top = lua_gettop(L);
|
||||||
lua_State* Lt = lua_newthread(L);
|
lua_State* Lt = lua_newthread(L);
|
||||||
|
|
||||||
|
lua_pushthread(Lt); // Push thread
|
||||||
|
getOrCreateEnvironment(Lt);
|
||||||
|
lua_setfenv(Lt, -2); // Set env of current thread
|
||||||
|
lua_pop(Lt, 1); // Pop thread
|
||||||
|
|
||||||
// Push wrapper as thread function
|
// Push wrapper as thread function
|
||||||
lua_getfield(Lt, LUA_REGISTRYINDEX, "LuaPCallWrapper");
|
lua_getfield(Lt, LUA_REGISTRYINDEX, "LuaPCallWrapper");
|
||||||
|
|
||||||
|
@ -55,6 +64,33 @@ void CommandEdit::executeCommand() {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Gets the command bar environment from the registry, or creates a new one and registers it
|
||||||
|
void CommandEdit::getOrCreateEnvironment(lua_State* L) {
|
||||||
|
auto context = gDataModel->GetService<ScriptContext>();
|
||||||
|
|
||||||
|
// Try to find existing environment
|
||||||
|
lua_getfield(L, LUA_REGISTRYINDEX, "commandBarEnv");
|
||||||
|
if (!lua_isnil(L, -1))
|
||||||
|
return; // Return the found environment
|
||||||
|
lua_pop(L, 1); // Pop nil
|
||||||
|
|
||||||
|
// Initialize script globals
|
||||||
|
context->NewEnvironment(L); // Pushes envtable, metatable
|
||||||
|
|
||||||
|
// Set source in metatable
|
||||||
|
lua_pushstring(L, "commandbar");
|
||||||
|
lua_setfield(L, -2, "source");
|
||||||
|
|
||||||
|
lua_pop(L, 1); // Pop metatable
|
||||||
|
|
||||||
|
// Register it
|
||||||
|
lua_pushvalue(L, -1); // Copy
|
||||||
|
lua_setfield(L, LUA_REGISTRYINDEX, "commandBarEnv");
|
||||||
|
|
||||||
|
// Remainder on stack:
|
||||||
|
// 1. Env table
|
||||||
|
}
|
||||||
|
|
||||||
void CommandEdit::keyPressEvent(QKeyEvent* evt) {
|
void CommandEdit::keyPressEvent(QKeyEvent* evt) {
|
||||||
switch (evt->key()) {
|
switch (evt->key()) {
|
||||||
case Qt::Key_Up:
|
case Qt::Key_Up:
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
#include <qlineedit.h>
|
#include <qlineedit.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
struct lua_State;
|
||||||
|
|
||||||
class CommandEdit : public QLineEdit {
|
class CommandEdit : public QLineEdit {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
@ -10,6 +12,7 @@ class CommandEdit : public QLineEdit {
|
||||||
int historyIndex = 0;
|
int historyIndex = 0;
|
||||||
|
|
||||||
void executeCommand();
|
void executeCommand();
|
||||||
|
void getOrCreateEnvironment(lua_State* L);
|
||||||
public:
|
public:
|
||||||
CommandEdit(QWidget* parent = nullptr);
|
CommandEdit(QWidget* parent = nullptr);
|
||||||
~CommandEdit();
|
~CommandEdit();
|
||||||
|
|
Loading…
Add table
Reference in a new issue