diff --git a/core/src/objects/script.cpp b/core/src/objects/script.cpp index af5f854..213e21c 100644 --- a/core/src/objects/script.cpp +++ b/core/src/objects/script.cpp @@ -12,8 +12,6 @@ #include #include -int script_wait(lua_State*); -int script_delay(lua_State*); int script_errhandler(lua_State*); Script::Script(): Instance(&TYPE) { @@ -38,20 +36,6 @@ void Script::Run() { InstanceRef(shared_from_this()).PushLuaValue(Lt); lua_setfield(Lt, -2, "script"); - - InstanceRef(dataModel().value()).PushLuaValue(Lt); - lua_setfield(Lt, -2, "game"); - - InstanceRef(dataModel().value()->GetService()).PushLuaValue(Lt); - lua_setfield(Lt, -2, "workspace"); - - lua_pushlightuserdata(Lt, scriptContext.get()); - lua_pushcclosure(Lt, script_wait, 1); - lua_setfield(Lt, -2, "wait"); - - lua_pushlightuserdata(Lt, scriptContext.get()); - lua_pushcclosure(Lt, script_delay, 1); - lua_setfield(Lt, -2, "delay"); lua_pop(Lt, 1); // _G @@ -83,35 +67,6 @@ void Script::Stop() { // TODO: } -int script_wait(lua_State* L) { - ScriptContext* scriptContext = (ScriptContext*)lua_touserdata(L, lua_upvalueindex(1)); - float secs = lua_gettop(L) == 0 ? 0.03 : std::max(luaL_checknumber(L, 1), 0.03); - if (lua_gettop(L) > 0) lua_pop(L, 1); // pop secs - - scriptContext->PushThreadSleep(L, secs); - - // Yield - return lua_yield(L, 0); -} - -int script_delay(lua_State* L) { - ScriptContext* scriptContext = (ScriptContext*)lua_touserdata(L, lua_upvalueindex(1)); - float secs = std::max(luaL_checknumber(L, 1), 0.03); - luaL_checktype(L, 2, LUA_TFUNCTION); - - lua_State* Lt = lua_newthread(L); // Create a new thread - // I think this is memory abuse?? - // Wouldn't popping the thread in this case make it eligible for garbage collection? - lua_pop(L, 1); // pop the newly created thread so that xmove moves func instead of it into itself - lua_xmove(L, Lt, 1); // move func - lua_pop(L, 1); // pop secs - - // Schedule next run - scriptContext->PushThreadSleep(Lt, secs); - - return 0; -} - int script_errhandler(lua_State* L) { std::string errorMessage = lua_tostring(L, -1); Logger::error(errorMessage); diff --git a/core/src/objects/service/script/scriptcontext.cpp b/core/src/objects/service/script/scriptcontext.cpp index b071350..88bdbaf 100644 --- a/core/src/objects/service/script/scriptcontext.cpp +++ b/core/src/objects/service/script/scriptcontext.cpp @@ -1,8 +1,11 @@ #include "scriptcontext.h" #include "datatypes/cframe.h" #include "datatypes/color3.h" +#include "datatypes/ref.h" #include "datatypes/vector.h" #include "logger.h" +#include "objects/datamodel.h" +#include "objects/service/workspace.h" #include "timeutil.h" #include #include @@ -10,6 +13,8 @@ const char* WRAPPER_SRC = "local func, errhandler = ... return function(...) local args = {...} xpcall(function() func(unpack(args)) end, errhandler) end"; +int g_wait(lua_State*); +int g_delay(lua_State*); static int g_print(lua_State*); static int g_require(lua_State*); static const struct luaL_Reg luaglobals [] = { @@ -50,6 +55,25 @@ void ScriptContext::InitService() { Color3::PushLuaLibrary(state); Instance::PushLuaLibrary(state); + // Add other globals + lua_getglobal(state, "_G"); + + InstanceRef(dataModel().value()).PushLuaValue(state); + lua_setfield(state, -2, "game"); + + InstanceRef(dataModel().value()->GetService()).PushLuaValue(state); + lua_setfield(state, -2, "workspace"); + + lua_pushlightuserdata(state, this); + lua_pushcclosure(state, g_wait, 1); + lua_setfield(state, -2, "wait"); + + lua_pushlightuserdata(state, this); + lua_pushcclosure(state, g_delay, 1); + lua_setfield(state, -2, "delay"); + + lua_pop(state, 1); // _G + // Add wrapper function luaL_loadbuffer(state, WRAPPER_SRC, strlen(WRAPPER_SRC), "=PCALL_WRAPPER"); lua_setfield(state, LUA_REGISTRYINDEX, "LuaPCallWrapper"); @@ -167,4 +191,33 @@ static int g_require(lua_State* L) { if (nargs < 1) return luaL_error(L, "expected argument module"); return luaL_error(L, "require is not yet implemented"); +} + +int g_wait(lua_State* L) { + ScriptContext* scriptContext = (ScriptContext*)lua_touserdata(L, lua_upvalueindex(1)); + float secs = lua_gettop(L) == 0 ? 0.03 : std::max(luaL_checknumber(L, 1), 0.03); + if (lua_gettop(L) > 0) lua_pop(L, 1); // pop secs + + scriptContext->PushThreadSleep(L, secs); + + // Yield + return lua_yield(L, 0); +} + +int g_delay(lua_State* L) { + ScriptContext* scriptContext = (ScriptContext*)lua_touserdata(L, lua_upvalueindex(1)); + float secs = std::max(luaL_checknumber(L, 1), 0.03); + luaL_checktype(L, 2, LUA_TFUNCTION); + + lua_State* Lt = lua_newthread(L); // Create a new thread + // I think this is memory abuse?? + // Wouldn't popping the thread in this case make it eligible for garbage collection? + lua_pop(L, 1); // pop the newly created thread so that xmove moves func instead of it into itself + lua_xmove(L, Lt, 1); // move func + lua_pop(L, 1); // pop secs + + // Schedule next run + scriptContext->PushThreadSleep(Lt, secs); + + return 0; } \ No newline at end of file diff --git a/editor/CMakeLists.txt b/editor/CMakeLists.txt index 3c61fb0..3ebcf05 100644 --- a/editor/CMakeLists.txt +++ b/editor/CMakeLists.txt @@ -38,6 +38,8 @@ set(PROJECT_SOURCES panes/outputtextview.cpp script/scriptdocument.h script/scriptdocument.cpp + script/commandedit.h + script/commandedit.cpp aboutdialog.ui aboutdialog.h aboutdialog.cpp diff --git a/editor/mainwindow.cpp b/editor/mainwindow.cpp index 5260d2a..50306fa 100644 --- a/editor/mainwindow.cpp +++ b/editor/mainwindow.cpp @@ -1,5 +1,6 @@ #include "mainwindow.h" #include "./ui_mainwindow.h" +#include "script/commandedit.h" #include "common.h" #include "aboutdialog.h" #include "logger.h" @@ -14,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -117,6 +119,8 @@ MainWindow::MainWindow(QWidget *parent) undoManager.SetUndoStateListener([&]() { updateToolbars(); }); + + setUpCommandBar(); } void MainWindow::closeEvent(QCloseEvent* evt) { @@ -142,6 +146,14 @@ void MainWindow::closeEvent(QCloseEvent* evt) { #endif } +void MainWindow::setUpCommandBar() { + CommandEdit* commandEdit; + QToolBar* commandBar = ui->commandBar; + commandBar->layout()->setSpacing(5); + commandBar->addWidget(new QLabel(tr("Command "))); + commandBar->addWidget(commandEdit = new CommandEdit()); +} + void MainWindow::connectActionHandlers() { connect(ui->actionToolSelect, &QAction::triggered, this, [&]() { selectedTool = TOOL_SELECT; updateToolbars(); }); connect(ui->actionToolMove, &QAction::triggered, this, [&](bool state) { selectedTool = state ? TOOL_MOVE : TOOL_SELECT; updateToolbars(); }); diff --git a/editor/mainwindow.h b/editor/mainwindow.h index 195d053..fcf4fb4 100644 --- a/editor/mainwindow.h +++ b/editor/mainwindow.h @@ -69,11 +69,11 @@ public: private: PlaceDocument* placeDocument; + void setUpCommandBar(); + void connectActionHandlers(); void updateToolbars(); void closeEvent(QCloseEvent* evt) override; ScriptDocument* findScriptWindow(std::shared_ptr