Fix LuaSmartRefs acting on dead Lua states
This fixes problems with degenerate cases such as: local button assert(coroutine.resume(coroutine.create(function() button = Button(10, 10, 20, 20) end))) button:action(function() print("hi") end)
This commit is contained in:
parent
f9c6633c62
commit
fd032eff36
@ -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;
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -14,7 +14,7 @@ class LuaComponentCallback : public LuaSmartRef
|
||||
{
|
||||
public:
|
||||
using LuaSmartRef::LuaSmartRef;
|
||||
int CheckAndAssignArg1();
|
||||
int CheckAndAssignArg1(lua_State *l);
|
||||
};
|
||||
|
||||
class LuaComponent
|
||||
|
@ -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))
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
@ -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()
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user