mirror of
https://github.com/The-Powder-Toy/The-Powder-Toy.git
synced 2025-08-12 11:24:04 +02:00
Fix crash from Lua prompts when exiting the game completely
The problem is that Engine outlives GameController and thus also LuaScriptInterface. The solution is to not try to access LSI's lua_State if it doesn't exist; this is the case in Engine's dtor. This is ugly as hell and the root of the problem is the cursed ownership model of LuaComponents and Windows by Engine, which I don't think I'll be fixing any time soon.
This commit is contained in:
@@ -1,11 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
//Legacy blocking prompts
|
|
||||||
//This are not implemented here, but rather in the engine bootstrapper
|
|
||||||
bool ConfirmUI(String title, String message, String confirmText) {}
|
|
||||||
|
|
||||||
void ErrorUI(String title, String message) {}
|
|
||||||
|
|
||||||
void InformationUI(String title, String message) {}
|
|
||||||
|
|
||||||
String MessagePromptUI(String title, String message, String text, String placeholder) {}
|
|
@@ -16,8 +16,7 @@ Luna<LuaButton>::RegType LuaButton::methods[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
LuaButton::LuaButton(lua_State * l) :
|
LuaButton::LuaButton(lua_State * l) :
|
||||||
LuaComponent(l),
|
LuaComponent(l)
|
||||||
actionFunction(l)
|
|
||||||
{
|
{
|
||||||
int posX = luaL_optinteger(l, 1, 0);
|
int posX = luaL_optinteger(l, 1, 0);
|
||||||
int posY = luaL_optinteger(l, 2, 0);
|
int posY = luaL_optinteger(l, 2, 0);
|
||||||
|
@@ -16,8 +16,7 @@ Luna<LuaCheckbox>::RegType LuaCheckbox::methods[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
LuaCheckbox::LuaCheckbox(lua_State * l) :
|
LuaCheckbox::LuaCheckbox(lua_State * l) :
|
||||||
LuaComponent(l),
|
LuaComponent(l)
|
||||||
actionFunction(l)
|
|
||||||
{
|
{
|
||||||
int posX = luaL_optinteger(l, 1, 0);
|
int posX = luaL_optinteger(l, 1, 0);
|
||||||
int posY = luaL_optinteger(l, 2, 0);
|
int posY = luaL_optinteger(l, 2, 0);
|
||||||
|
@@ -465,7 +465,7 @@ tpt.partsdata = nil");
|
|||||||
lua_setmetatable(l, top);
|
lua_setmetatable(l, top);
|
||||||
}
|
}
|
||||||
|
|
||||||
tptPart = new LuaSmartRef(l);
|
tptPart = new LuaSmartRef();
|
||||||
tptPart->Assign(l, -1);
|
tptPart->Assign(l, -1);
|
||||||
lua_pop(l, 1);
|
lua_pop(l, 1);
|
||||||
#endif
|
#endif
|
||||||
@@ -510,14 +510,14 @@ tpt.partsdata = nil");
|
|||||||
}
|
}
|
||||||
lua_setfield(l, tptProperties, "eltransition");
|
lua_setfield(l, tptProperties, "eltransition");
|
||||||
|
|
||||||
lua_gr_func_v = std::vector<LuaSmartRef>(PT_NUM, l);
|
lua_gr_func_v = std::vector<LuaSmartRef>(PT_NUM);
|
||||||
lua_gr_func = &lua_gr_func_v[0];
|
lua_gr_func = &lua_gr_func_v[0];
|
||||||
lua_el_func_v = std::vector<LuaSmartRef>(PT_NUM, l);
|
lua_el_func_v = std::vector<LuaSmartRef>(PT_NUM);
|
||||||
lua_el_func = &lua_el_func_v[0];
|
lua_el_func = &lua_el_func_v[0];
|
||||||
lua_el_mode_v = std::vector<int>(PT_NUM, 0);
|
lua_el_mode_v = std::vector<int>(PT_NUM, 0);
|
||||||
lua_el_mode = &lua_el_mode_v[0];
|
lua_el_mode = &lua_el_mode_v[0];
|
||||||
|
|
||||||
gameControllerEventHandlers = std::vector<LuaSmartRef>(std::variant_size<GameControllerEvent>::value, l);
|
gameControllerEventHandlers = std::vector<LuaSmartRef>(std::variant_size<GameControllerEvent>::value);
|
||||||
for (auto &ref : gameControllerEventHandlers)
|
for (auto &ref : gameControllerEventHandlers)
|
||||||
{
|
{
|
||||||
lua_newtable(l);
|
lua_newtable(l);
|
||||||
@@ -525,10 +525,10 @@ tpt.partsdata = nil");
|
|||||||
lua_pop(l, 1);
|
lua_pop(l, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
luaCtypeDrawHandlers = std::vector<LuaSmartRef>(PT_NUM, l);
|
luaCtypeDrawHandlers = std::vector<LuaSmartRef>(PT_NUM);
|
||||||
luaCreateHandlers = std::vector<LuaSmartRef>(PT_NUM, l);
|
luaCreateHandlers = std::vector<LuaSmartRef>(PT_NUM);
|
||||||
luaCreateAllowedHandlers = std::vector<LuaSmartRef>(PT_NUM, l);
|
luaCreateAllowedHandlers = std::vector<LuaSmartRef>(PT_NUM);
|
||||||
luaChangeTypeHandlers = std::vector<LuaSmartRef>(PT_NUM, l);
|
luaChangeTypeHandlers = std::vector<LuaSmartRef>(PT_NUM);
|
||||||
|
|
||||||
//make tpt.* a metatable
|
//make tpt.* a metatable
|
||||||
lua_newtable(l);
|
lua_newtable(l);
|
||||||
@@ -697,8 +697,7 @@ static int beginMessageBox(lua_State* l)
|
|||||||
auto title = PickIfType(l, 1, String("Title"));
|
auto title = PickIfType(l, 1, String("Title"));
|
||||||
auto message = PickIfType(l, 2, String("Message"));
|
auto message = PickIfType(l, 2, String("Message"));
|
||||||
auto large = PickIfType(l, 3, false);
|
auto large = PickIfType(l, 3, false);
|
||||||
auto *luacon_ci = static_cast<LuaScriptInterface *>(commandInterface);
|
auto cb = std::make_shared<LuaSmartRef>(); // * Bind to main lua state (might be different from l).
|
||||||
auto cb = std::make_shared<LuaSmartRef>(luacon_ci->l); // * Bind to main lua state (might be different from l).
|
|
||||||
cb->Assign(l, lua_gettop(l));
|
cb->Assign(l, lua_gettop(l));
|
||||||
new InformationMessage(title, message, large, { [cb]() {
|
new InformationMessage(title, message, large, { [cb]() {
|
||||||
auto *luacon_ci = static_cast<LuaScriptInterface *>(commandInterface);
|
auto *luacon_ci = static_cast<LuaScriptInterface *>(commandInterface);
|
||||||
@@ -722,8 +721,7 @@ static int beginMessageBox(lua_State* l)
|
|||||||
static int beginThrowError(lua_State* l)
|
static int beginThrowError(lua_State* l)
|
||||||
{
|
{
|
||||||
auto errorMessage = PickIfType(l, 1, String("Error text"));
|
auto errorMessage = PickIfType(l, 1, String("Error text"));
|
||||||
auto *luacon_ci = static_cast<LuaScriptInterface *>(commandInterface);
|
auto cb = std::make_shared<LuaSmartRef>(); // * Bind to main lua state (might be different from l).
|
||||||
auto cb = std::make_shared<LuaSmartRef>(luacon_ci->l); // * Bind to main lua state (might be different from l).
|
|
||||||
cb->Assign(l, lua_gettop(l));
|
cb->Assign(l, lua_gettop(l));
|
||||||
new ErrorMessage("Error", errorMessage, { [cb]() {
|
new ErrorMessage("Error", errorMessage, { [cb]() {
|
||||||
auto *luacon_ci = static_cast<LuaScriptInterface *>(commandInterface);
|
auto *luacon_ci = static_cast<LuaScriptInterface *>(commandInterface);
|
||||||
@@ -750,8 +748,7 @@ static int beginInput(lua_State* l)
|
|||||||
auto prompt = PickIfType(l, 2, String("Enter some text:"));
|
auto prompt = PickIfType(l, 2, String("Enter some text:"));
|
||||||
auto text = PickIfType(l, 3, String(""));
|
auto text = PickIfType(l, 3, String(""));
|
||||||
auto shadow = PickIfType(l, 4, String(""));
|
auto shadow = PickIfType(l, 4, String(""));
|
||||||
auto *luacon_ci = static_cast<LuaScriptInterface *>(commandInterface);
|
auto cb = std::make_shared<LuaSmartRef>(); // * Bind to main lua state (might be different from l).
|
||||||
auto cb = std::make_shared<LuaSmartRef>(luacon_ci->l); // * Bind to main lua state (might be different from l).
|
|
||||||
cb->Assign(l, lua_gettop(l));
|
cb->Assign(l, lua_gettop(l));
|
||||||
auto handle = [cb](std::optional<String> input) {
|
auto handle = [cb](std::optional<String> input) {
|
||||||
auto *luacon_ci = static_cast<LuaScriptInterface *>(commandInterface);
|
auto *luacon_ci = static_cast<LuaScriptInterface *>(commandInterface);
|
||||||
@@ -790,8 +787,7 @@ static int beginConfirm(lua_State *l)
|
|||||||
auto title = PickIfType(l, 1, String("Title"));
|
auto title = PickIfType(l, 1, String("Title"));
|
||||||
auto message = PickIfType(l, 2, String("Message"));
|
auto message = PickIfType(l, 2, String("Message"));
|
||||||
auto buttonText = PickIfType(l, 3, String("Confirm"));
|
auto buttonText = PickIfType(l, 3, String("Confirm"));
|
||||||
auto *luacon_ci = static_cast<LuaScriptInterface *>(commandInterface);
|
auto cb = std::make_shared<LuaSmartRef>(); // * Bind to main lua state (might be different from l).
|
||||||
auto cb = std::make_shared<LuaSmartRef>(luacon_ci->l); // * Bind to main lua state (might be different from l).
|
|
||||||
cb->Assign(l, lua_gettop(l));
|
cb->Assign(l, lua_gettop(l));
|
||||||
auto handle = [cb](int result) {
|
auto handle = [cb](int result) {
|
||||||
auto *luacon_ci = static_cast<LuaScriptInterface *>(commandInterface);
|
auto *luacon_ci = static_cast<LuaScriptInterface *>(commandInterface);
|
||||||
@@ -875,7 +871,7 @@ int LuaScriptInterface::interface_addComponent(lua_State * l)
|
|||||||
luaL_typerror(l, 1, "Component");
|
luaL_typerror(l, 1, "Component");
|
||||||
if (luacon_ci->Window && luaComponent)
|
if (luacon_ci->Window && luaComponent)
|
||||||
{
|
{
|
||||||
auto ok = luacon_ci->grabbed_components.insert(std::make_pair(luaComponent, LuaSmartRef(l)));
|
auto ok = luacon_ci->grabbed_components.insert(std::make_pair(luaComponent, LuaSmartRef()));
|
||||||
if (ok.second)
|
if (ok.second)
|
||||||
{
|
{
|
||||||
auto it = ok.first;
|
auto it = ok.first;
|
||||||
@@ -5108,7 +5104,7 @@ int LuaScriptInterface::luatpt_getscript(lua_State* l)
|
|||||||
auto filename = tpt_lua_checkByteString(l, 2);
|
auto filename = tpt_lua_checkByteString(l, 2);
|
||||||
auto runScript = PickIfType(l, 3, false);
|
auto runScript = PickIfType(l, 3, false);
|
||||||
|
|
||||||
auto cb = std::make_shared<LuaSmartRef>(luacon_ci->l); // * Bind to main lua state (might be different from l).
|
auto cb = std::make_shared<LuaSmartRef>(); // * Bind to main lua state (might be different from l).
|
||||||
cb->Assign(l, lua_gettop(l));
|
cb->Assign(l, lua_gettop(l));
|
||||||
luacon_ci->scriptDownloadComplete = [cb](const GetScriptStatus &status) {
|
luacon_ci->scriptDownloadComplete = [cb](const GetScriptStatus &status) {
|
||||||
auto *luacon_ci = static_cast<LuaScriptInterface *>(commandInterface);
|
auto *luacon_ci = static_cast<LuaScriptInterface *>(commandInterface);
|
||||||
|
@@ -16,8 +16,7 @@ Luna<LuaSlider>::RegType LuaSlider::methods[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
LuaSlider::LuaSlider(lua_State * l) :
|
LuaSlider::LuaSlider(lua_State * l) :
|
||||||
LuaComponent(l),
|
LuaComponent(l)
|
||||||
onValueChangedFunction(l)
|
|
||||||
{
|
{
|
||||||
int posX = luaL_optinteger(l, 1, 0);
|
int posX = luaL_optinteger(l, 1, 0);
|
||||||
int posY = luaL_optinteger(l, 2, 0);
|
int posY = luaL_optinteger(l, 2, 0);
|
||||||
|
@@ -1,17 +1,14 @@
|
|||||||
#include "LuaSmartRef.h"
|
#include "LuaSmartRef.h"
|
||||||
|
#include "LuaScriptInterface.h"
|
||||||
|
|
||||||
void LuaSmartRef::Clear()
|
void LuaSmartRef::Clear()
|
||||||
{
|
{
|
||||||
luaL_unref(rootl, LUA_REGISTRYINDEX, ref);
|
auto *luacon_ci = static_cast<LuaScriptInterface *>(commandInterface);
|
||||||
ref = LUA_REFNIL;
|
if (luacon_ci)
|
||||||
}
|
{
|
||||||
|
luaL_unref(luacon_ci->l, LUA_REGISTRYINDEX, ref);
|
||||||
LuaSmartRef::LuaSmartRef(lua_State *l) :
|
ref = LUA_REFNIL;
|
||||||
ref(LUA_REFNIL)
|
}
|
||||||
{
|
|
||||||
tpt_lua_getmainthread(l);
|
|
||||||
rootl = lua_tothread(l, -1);
|
|
||||||
lua_pop(l, 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LuaSmartRef::~LuaSmartRef()
|
LuaSmartRef::~LuaSmartRef()
|
||||||
|
@@ -3,11 +3,9 @@
|
|||||||
|
|
||||||
class LuaSmartRef
|
class LuaSmartRef
|
||||||
{
|
{
|
||||||
int ref;
|
int ref = LUA_REFNIL;
|
||||||
lua_State *rootl;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
LuaSmartRef(lua_State *l);
|
|
||||||
~LuaSmartRef();
|
~LuaSmartRef();
|
||||||
void Assign(lua_State *l, 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();
|
void Clear();
|
||||||
|
@@ -16,8 +16,7 @@ Luna<LuaTextbox>::RegType LuaTextbox::methods[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
LuaTextbox::LuaTextbox(lua_State * l) :
|
LuaTextbox::LuaTextbox(lua_State * l) :
|
||||||
LuaComponent(l),
|
LuaComponent(l)
|
||||||
onTextChangedFunction(l)
|
|
||||||
{
|
{
|
||||||
this->l = l;
|
this->l = l;
|
||||||
int posX = luaL_optinteger(l, 1, 0);
|
int posX = luaL_optinteger(l, 1, 0);
|
||||||
|
@@ -35,21 +35,7 @@ Luna<LuaWindow>::RegType LuaWindow::methods[] = {
|
|||||||
{0, 0}
|
{0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
LuaWindow::LuaWindow(lua_State * l) :
|
LuaWindow::LuaWindow(lua_State * l)
|
||||||
onInitializedFunction(l),
|
|
||||||
onExitFunction(l),
|
|
||||||
onTickFunction(l),
|
|
||||||
onDrawFunction(l),
|
|
||||||
onFocusFunction(l),
|
|
||||||
onBlurFunction(l),
|
|
||||||
onTryExitFunction(l),
|
|
||||||
onTryOkayFunction(l),
|
|
||||||
onMouseMoveFunction(l),
|
|
||||||
onMouseDownFunction(l),
|
|
||||||
onMouseUpFunction(l),
|
|
||||||
onMouseWheelFunction(l),
|
|
||||||
onKeyPressFunction(l),
|
|
||||||
onKeyReleaseFunction(l)
|
|
||||||
{
|
{
|
||||||
this->l = l;
|
this->l = l;
|
||||||
int posX = luaL_optinteger(l, 1, 1);
|
int posX = luaL_optinteger(l, 1, 1);
|
||||||
@@ -122,7 +108,7 @@ int LuaWindow::addComponent(lua_State * l)
|
|||||||
luaL_typerror(l, 1, "Component");
|
luaL_typerror(l, 1, "Component");
|
||||||
if (luaComponent)
|
if (luaComponent)
|
||||||
{
|
{
|
||||||
auto ok = grabbed_components.insert(std::make_pair(luaComponent, LuaSmartRef(l)));
|
auto ok = grabbed_components.insert(std::make_pair(luaComponent, LuaSmartRef()));
|
||||||
if (ok.second)
|
if (ok.second)
|
||||||
{
|
{
|
||||||
auto it = ok.first;
|
auto it = ok.first;
|
||||||
|
Reference in New Issue
Block a user