#include "script.h" #include "common.h" #include "datatypes/variant.h" #include "lauxlib.h" #include "logger.h" #include "objects/base/instance.h" #include "objects/base/member.h" #include "objects/service/script/scriptcontext.h" #include "objects/service/workspace.h" #include "objects/datamodel.h" #include "datatypes/ref.h" #include "luaapis.h" // IWYU pragma: keep #include #include int script_errhandler(lua_State*); Script::Script(): Instance(&TYPE) { source = "print(\"Hello, world!\")"; } Script::~Script() { } void Script::Run() { std::shared_ptr scriptContext = dataModel()->GetService(); lua_State* L = scriptContext->state; int top = lua_gettop(L); // Create thread this->thread = lua_newthread(L); lua_State* Lt = thread; // Push wrapper as thread function lua_getfield(Lt, LUA_REGISTRYINDEX, "LuaPCallWrapper"); // Load source code and push onto thread as upvalue for wrapper int status = luaL_loadbuffer(Lt, source.c_str(), source.size(), this->GetFullName().c_str()); if (status != LUA_OK) { // Failed to parse/load chunk Logger::error(lua_tostring(Lt, -1)); lua_settop(L, top); return; } // Initialize script globals scriptContext->NewEnvironment(Lt); // Pushes envtable, metatable // Set script in metatable source InstanceRef(shared_from_this()).PushLuaValue(Lt); lua_setfield(Lt, -2, "source"); lua_pop(Lt, 1); // Pop metatable // Set script in environment InstanceRef(shared_from_this()).PushLuaValue(Lt); lua_setfield(Lt, -2, "script"); lua_setfenv(Lt, -2); // Set env of loaded function // Push our error handler and then generate the wrapped function lua_pushcfunction(Lt, script_errhandler); lua_call(Lt, 2, 1); // Resume the thread lua_resume(Lt, 0); lua_pop(L, 1); // Pop the thread lua_settop(L, top); } void Script::Stop() { // TODO: } static std::shared_ptr