diff --git a/src/lua/LegacyLuaAPI.cpp b/src/lua/LegacyLuaAPI.cpp index b73f3674f..25e547453 100644 --- a/src/lua/LegacyLuaAPI.cpp +++ b/src/lua/LegacyLuaAPI.cpp @@ -348,7 +348,7 @@ int luatpt_element_func(lua_State *l) int replace = luaL_optint(l, 3, 0); if (luacon_sim->IsValidElement(element)) { - lua_el_func[element].Assign(1); + lua_el_func[element].Assign(l, 1); if (replace == 2) lua_el_mode[element] = 3; //update before else if (replace) @@ -428,7 +428,7 @@ int luatpt_graphics_func(lua_State *l) int element = luaL_optint(l, 2, 0); if (luacon_sim->IsValidElement(element)) { - lua_gr_func[element].Assign(1); + lua_gr_func[element].Assign(l, 1); luacon_ren->graphicscache[element].isready = 0; return 0; } diff --git a/src/lua/LuaButton.cpp b/src/lua/LuaButton.cpp index d97895888..b9a117cbb 100644 --- a/src/lua/LuaButton.cpp +++ b/src/lua/LuaButton.cpp @@ -53,7 +53,7 @@ int LuaButton::enabled(lua_State * l) int LuaButton::action(lua_State * l) { - return actionFunction.CheckAndAssignArg1(); + return actionFunction.CheckAndAssignArg1(l); } int LuaButton::text(lua_State * l) diff --git a/src/lua/LuaCheckbox.cpp b/src/lua/LuaCheckbox.cpp index e20fa82ef..5f9b2bb7e 100644 --- a/src/lua/LuaCheckbox.cpp +++ b/src/lua/LuaCheckbox.cpp @@ -51,7 +51,7 @@ int LuaCheckbox::checked(lua_State * l) int LuaCheckbox::action(lua_State * l) { - return actionFunction.CheckAndAssignArg1(); + return actionFunction.CheckAndAssignArg1(l); } int LuaCheckbox::text(lua_State * l) diff --git a/src/lua/LuaCompat.c b/src/lua/LuaCompat.c index d3f38ebf0..96a56fef7 100644 --- a/src/lua/LuaCompat.c +++ b/src/lua/LuaCompat.c @@ -8,6 +8,15 @@ int luaL_typerror (lua_State *L, int narg, const char *tname) return luaL_argerror(L, narg, msg); } +void tpt_lua_setmainthread(lua_State *L) +{ +} + +void tpt_lua_getmainthread(lua_State *L) +{ + lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_MAINTHREAD); +} + #else // Implement function added in lua 5.2 that we now use @@ -16,6 +25,17 @@ void lua_pushglobaltable(lua_State *L) lua_pushvalue(L, LUA_GLOBALSINDEX); } +void tpt_lua_setmainthread(lua_State *L) +{ + lua_pushthread(L); + lua_setfield(L, LUA_REGISTRYINDEX, "tpt_lua_mainthread"); +} + +void tpt_lua_getmainthread(lua_State *L) +{ + lua_getfield(L, LUA_REGISTRYINDEX, "tpt_lua_mainthread"); +} + #endif // Useful helper function, mainly used for logging diff --git a/src/lua/LuaCompat.h b/src/lua/LuaCompat.h index 027929522..2335a36bd 100644 --- a/src/lua/LuaCompat.h +++ b/src/lua/LuaCompat.h @@ -24,6 +24,9 @@ extern "C" #include "lua5.1/lualib.h" #endif +LUALIB_API void tpt_lua_setmainthread(lua_State *L); +LUALIB_API void tpt_lua_getmainthread(lua_State *L); + #if LUA_VERSION_NUM >= 502 LUALIB_API int (luaL_typerror) (lua_State *L, int narg, const char *tname); #else diff --git a/src/lua/LuaComponent.cpp b/src/lua/LuaComponent.cpp index 85b7d5a6c..98ee7c730 100644 --- a/src/lua/LuaComponent.cpp +++ b/src/lua/LuaComponent.cpp @@ -7,20 +7,20 @@ #include "gui/interface/Component.h" #include "gui/interface/Window.h" -int LuaComponentCallback::CheckAndAssignArg1() +int LuaComponentCallback::CheckAndAssignArg1(lua_State *l) { if (lua_type(l, 1) != LUA_TNIL) { luaL_checktype(l, 1, LUA_TFUNCTION); } - LuaSmartRef::Assign(1); + LuaSmartRef::Assign(l, 1); return 0; } LuaComponent::LuaComponent(lua_State * l) : owner_ref(LUA_REFNIL) { - this->l = l; - + this->l = l; // I don't get how this doesn't cause crashes later on + lua_pushstring(l, "Luacon_ci"); lua_gettable(l, LUA_REGISTRYINDEX); ci = (LuaScriptInterface*)lua_touserdata(l, -1); diff --git a/src/lua/LuaComponent.h b/src/lua/LuaComponent.h index 1c62dfc05..b37b920a7 100644 --- a/src/lua/LuaComponent.h +++ b/src/lua/LuaComponent.h @@ -14,7 +14,7 @@ class LuaComponentCallback : public LuaSmartRef { public: using LuaSmartRef::LuaSmartRef; - int CheckAndAssignArg1(); + int CheckAndAssignArg1(lua_State *l); }; class LuaComponent diff --git a/src/lua/LuaScriptInterface.cpp b/src/lua/LuaScriptInterface.cpp index 229d20947..dfdca4533 100644 --- a/src/lua/LuaScriptInterface.cpp +++ b/src/lua/LuaScriptInterface.cpp @@ -125,6 +125,7 @@ LuaScriptInterface::LuaScriptInterface(GameController * c, GameModel * m): //New TPT API l = luaL_newstate(); + tpt_lua_setmainthread(l); lua_atpanic(l, atPanic); luaL_openlibs(l); luaopen_bit(l); @@ -291,7 +292,7 @@ tpt.partsdata = nil"); } tptPart = new LuaSmartRef(l); - tptPart->Assign(-1); + tptPart->Assign(l, -1); lua_pop(l, 1); #endif @@ -522,7 +523,7 @@ int LuaScriptInterface::interface_addComponent(lua_State * l) if (ok.second) { auto it = ok.first; - it->second.Assign(1); + it->second.Assign(l, 1); it->first->owner_ref = it->second; } luacon_ci->Window->AddComponent(luaComponent->GetComponent()); @@ -2818,7 +2819,7 @@ int LuaScriptInterface::elements_element(lua_State * l) lua_getfield(l, -1, "Update"); if (lua_type(l, -1) == LUA_TFUNCTION) { - lua_el_func[id].Assign(-1); + lua_el_func[id].Assign(l, -1); lua_el_mode[id] = 1; } else if (lua_type(l, -1) == LUA_TBOOLEAN && !lua_toboolean(l, -1)) @@ -2832,7 +2833,7 @@ int LuaScriptInterface::elements_element(lua_State * l) lua_getfield(l, -1, "Graphics"); if (lua_type(l, -1) == LUA_TFUNCTION) { - lua_gr_func[id].Assign(-1); + lua_gr_func[id].Assign(l, -1); } else if (lua_type(l, -1) == LUA_TBOOLEAN && !lua_toboolean(l, -1)) { @@ -2844,7 +2845,7 @@ int LuaScriptInterface::elements_element(lua_State * l) lua_getfield(l, -1, "Create"); if (lua_type(l, -1) == LUA_TFUNCTION) { - luaCreateHandlers[id].Assign(-1); + luaCreateHandlers[id].Assign(l, -1); luacon_sim->elements[id].Create = luaCreateWrapper; } else if (lua_type(l, -1) == LUA_TBOOLEAN && !lua_toboolean(l, -1)) @@ -2857,7 +2858,7 @@ int LuaScriptInterface::elements_element(lua_State * l) lua_getfield(l, -1, "CreateAllowed"); if (lua_type(l, -1) == LUA_TFUNCTION) { - luaCreateAllowedHandlers[id].Assign(-1); + luaCreateAllowedHandlers[id].Assign(l, -1); luacon_sim->elements[id].CreateAllowed = luaCreateAllowedWrapper; } else if (lua_type(l, -1) == LUA_TBOOLEAN && !lua_toboolean(l, -1)) @@ -2870,7 +2871,7 @@ int LuaScriptInterface::elements_element(lua_State * l) lua_getfield(l, -1, "ChangeType"); if (lua_type(l, -1) == LUA_TFUNCTION) { - luaChangeTypeHandlers[id].Assign(-1); + luaChangeTypeHandlers[id].Assign(l, -1); luacon_sim->elements[id].ChangeType = luaChangeTypeWrapper; } else if (lua_type(l, -1) == LUA_TBOOLEAN && !lua_toboolean(l, -1)) @@ -2883,7 +2884,7 @@ int LuaScriptInterface::elements_element(lua_State * l) lua_getfield(l, -1, "CtypeDraw"); if (lua_type(l, -1) == LUA_TFUNCTION) { - luaCtypeDrawHandlers[id].Assign(-1); + luaCtypeDrawHandlers[id].Assign(l, -1); luacon_sim->elements[id].CtypeDraw = luaCtypeDrawWrapper; } else if (lua_type(l, -1) == LUA_TBOOLEAN && !lua_toboolean(l, -1)) @@ -2998,7 +2999,7 @@ int LuaScriptInterface::elements_property(lua_State * l) lua_el_mode[id] = 1; //update after break; } - lua_el_func[id].Assign(3); + lua_el_func[id].Assign(l, 3); } else if (lua_type(l, 3) == LUA_TBOOLEAN && !lua_toboolean(l, 3)) { @@ -3011,7 +3012,7 @@ int LuaScriptInterface::elements_property(lua_State * l) { if (lua_type(l, 3) == LUA_TFUNCTION) { - lua_gr_func[id].Assign(3); + lua_gr_func[id].Assign(l, 3); } else if (lua_type(l, 3) == LUA_TBOOLEAN && !lua_toboolean(l, 3)) { @@ -3024,7 +3025,7 @@ int LuaScriptInterface::elements_property(lua_State * l) { if (lua_type(l, 3) == LUA_TFUNCTION) { - luaCreateHandlers[id].Assign(3); + luaCreateHandlers[id].Assign(l, 3); luacon_sim->elements[id].Create = luaCreateWrapper; } else if (lua_type(l, 3) == LUA_TBOOLEAN && !lua_toboolean(l, 3)) @@ -3037,7 +3038,7 @@ int LuaScriptInterface::elements_property(lua_State * l) { if (lua_type(l, 3) == LUA_TFUNCTION) { - luaCreateAllowedHandlers[id].Assign(3); + luaCreateAllowedHandlers[id].Assign(l, 3); luacon_sim->elements[id].CreateAllowed = luaCreateAllowedWrapper; } else if (lua_type(l, 3) == LUA_TBOOLEAN && !lua_toboolean(l, 3)) @@ -3050,7 +3051,7 @@ int LuaScriptInterface::elements_property(lua_State * l) { if (lua_type(l, 3) == LUA_TFUNCTION) { - luaChangeTypeHandlers[id].Assign(3); + luaChangeTypeHandlers[id].Assign(l, 3); luacon_sim->elements[id].ChangeType = luaChangeTypeWrapper; } else if (lua_type(l, 3) == LUA_TBOOLEAN && !lua_toboolean(l, 3)) @@ -3063,7 +3064,7 @@ int LuaScriptInterface::elements_property(lua_State * l) { if (lua_type(l, 3) == LUA_TFUNCTION) { - luaCtypeDrawHandlers[id].Assign(3); + luaCtypeDrawHandlers[id].Assign(l, 3); luacon_sim->elements[id].CtypeDraw = luaCtypeDrawWrapper; } else if (lua_type(l, 3) == LUA_TBOOLEAN && !lua_toboolean(l, 3)) diff --git a/src/lua/LuaSlider.cpp b/src/lua/LuaSlider.cpp index b6a7c5fe6..a392cc587 100644 --- a/src/lua/LuaSlider.cpp +++ b/src/lua/LuaSlider.cpp @@ -51,7 +51,7 @@ int LuaSlider::steps(lua_State * l) int LuaSlider::onValueChanged(lua_State * l) { - return onValueChangedFunction.CheckAndAssignArg1(); + return onValueChangedFunction.CheckAndAssignArg1(l); } int LuaSlider::value(lua_State * l) diff --git a/src/lua/LuaSmartRef.cpp b/src/lua/LuaSmartRef.cpp index 24783e080..080dc0dfb 100644 --- a/src/lua/LuaSmartRef.cpp +++ b/src/lua/LuaSmartRef.cpp @@ -3,14 +3,16 @@ void LuaSmartRef::Clear() { - luaL_unref(l, LUA_REGISTRYINDEX, ref); + luaL_unref(rootl, LUA_REGISTRYINDEX, ref); ref = LUA_REFNIL; } -LuaSmartRef::LuaSmartRef(lua_State *state) : - ref(LUA_REFNIL), - l(state) +LuaSmartRef::LuaSmartRef(lua_State *l) : + ref(LUA_REFNIL) { + tpt_lua_getmainthread(l); + rootl = lua_tothread(l, -1); + lua_pop(l, 1); } LuaSmartRef::~LuaSmartRef() @@ -18,20 +20,21 @@ LuaSmartRef::~LuaSmartRef() Clear(); } -void LuaSmartRef::Assign(int index) +void LuaSmartRef::Assign(lua_State *l, int index) { + if (index < 0) + { + index = lua_gettop(l) + index + 1; + } Clear(); lua_pushvalue(l, index); ref = luaL_ref(l, LUA_REGISTRYINDEX); } -LuaSmartRef::operator int() const +int LuaSmartRef::Push(lua_State *l) { - return ref; + lua_rawgeti(l, LUA_REGISTRYINDEX, ref); + return lua_type(l, -1); } -LuaSmartRef::operator bool() const -{ - return ref != LUA_REFNIL; -} #endif diff --git a/src/lua/LuaSmartRef.h b/src/lua/LuaSmartRef.h index 0f9cc97c4..60ee9270c 100644 --- a/src/lua/LuaSmartRef.h +++ b/src/lua/LuaSmartRef.h @@ -5,16 +5,22 @@ class LuaSmartRef { int ref; - -protected: - lua_State *l; + lua_State *rootl; public: LuaSmartRef(lua_State *l); ~LuaSmartRef(); - void Assign(int index); // Copies the value before getting reference, stack unchanged. + void Assign(lua_State *l, int index); // Copies the value before getting reference, stack unchanged. void Clear(); - operator int() const; - operator bool() const; -}; + int Push(lua_State *l); // Always pushes exactly one value, possibly nil. + inline operator int() const + { + return ref; + } + + inline operator bool() const + { + return ref != LUA_REFNIL; + } +}; diff --git a/src/lua/LuaTextbox.cpp b/src/lua/LuaTextbox.cpp index cdbaf8283..fc2d5810f 100644 --- a/src/lua/LuaTextbox.cpp +++ b/src/lua/LuaTextbox.cpp @@ -55,7 +55,7 @@ int LuaTextbox::readonly(lua_State * l) int LuaTextbox::onTextChanged(lua_State * l) { - return onTextChangedFunction.CheckAndAssignArg1(); + return onTextChangedFunction.CheckAndAssignArg1(l); } void LuaTextbox::triggerOnTextChanged() diff --git a/src/lua/LuaWindow.cpp b/src/lua/LuaWindow.cpp index f015caddf..1451bd677 100644 --- a/src/lua/LuaWindow.cpp +++ b/src/lua/LuaWindow.cpp @@ -131,7 +131,7 @@ int LuaWindow::addComponent(lua_State * l) if (ok.second) { auto it = ok.first; - it->second.Assign(1); + it->second.Assign(l, 1); it->first->owner_ref = it->second; } window->AddComponent(luaComponent->GetComponent()); @@ -416,72 +416,72 @@ void LuaWindow::triggerOnKeyRelease(int key, int scan, bool repeat, bool shift, int LuaWindow::onInitialized(lua_State * l) { - return onInitializedFunction.CheckAndAssignArg1(); + return onInitializedFunction.CheckAndAssignArg1(l); } int LuaWindow::onExit(lua_State * l) { - return onExitFunction.CheckAndAssignArg1(); + return onExitFunction.CheckAndAssignArg1(l); } int LuaWindow::onTick(lua_State * l) { - return onTickFunction.CheckAndAssignArg1(); + return onTickFunction.CheckAndAssignArg1(l); } int LuaWindow::onDraw(lua_State * l) { - return onDrawFunction.CheckAndAssignArg1(); + return onDrawFunction.CheckAndAssignArg1(l); } int LuaWindow::onFocus(lua_State * l) { - return onFocusFunction.CheckAndAssignArg1(); + return onFocusFunction.CheckAndAssignArg1(l); } int LuaWindow::onBlur(lua_State * l) { - return onBlurFunction.CheckAndAssignArg1(); + return onBlurFunction.CheckAndAssignArg1(l); } int LuaWindow::onTryExit(lua_State * l) { - return onTryExitFunction.CheckAndAssignArg1(); + return onTryExitFunction.CheckAndAssignArg1(l); } int LuaWindow::onTryOkay(lua_State * l) { - return onTryOkayFunction.CheckAndAssignArg1(); + return onTryOkayFunction.CheckAndAssignArg1(l); } int LuaWindow::onMouseMove(lua_State * l) { - return onMouseMoveFunction.CheckAndAssignArg1(); + return onMouseMoveFunction.CheckAndAssignArg1(l); } int LuaWindow::onMouseDown(lua_State * l) { - return onMouseDownFunction.CheckAndAssignArg1(); + return onMouseDownFunction.CheckAndAssignArg1(l); } int LuaWindow::onMouseUp(lua_State * l) { - return onMouseUpFunction.CheckAndAssignArg1(); + return onMouseUpFunction.CheckAndAssignArg1(l); } int LuaWindow::onMouseWheel(lua_State * l) { - return onMouseWheelFunction.CheckAndAssignArg1(); + return onMouseWheelFunction.CheckAndAssignArg1(l); } int LuaWindow::onKeyPress(lua_State * l) { - return onKeyPressFunction.CheckAndAssignArg1(); + return onKeyPressFunction.CheckAndAssignArg1(l); } int LuaWindow::onKeyRelease(lua_State * l) { - return onKeyReleaseFunction.CheckAndAssignArg1(); + return onKeyReleaseFunction.CheckAndAssignArg1(l); }