Emscripten: Remove direct blocking prompt calls from Lua
Notable changes: - tpt.{input,throw_error,message_box,confirm} have been superseded by ui.begin{Input,ThrowError,MessageBox,Confirm}, each with an extra callback argument and no blocking behaviour, but otherwise the same semantics as their predecessors. - The "script not responding" error doesn't wait for user confirmation anymore, it fires without asking. Future exercise: maybe let the user configure the timeout. - Remove the confirmPrompt argument of tpt.getscript; this also means it unconditionally fails if the destination file exists.
This commit is contained in:
parent
67e41b6705
commit
4f31f85b6b
@ -8,8 +8,9 @@
|
||||
|
||||
#include "graphics/Graphics.h"
|
||||
|
||||
InformationMessage::InformationMessage(String title, String message, bool large):
|
||||
ui::Window(ui::Point(-1, -1), ui::Point(200, 35))
|
||||
InformationMessage::InformationMessage(String title, String message, bool large, DismissCallback callback_):
|
||||
ui::Window(ui::Point(-1, -1), ui::Point(200, 35)),
|
||||
callback(callback_)
|
||||
{
|
||||
if (large) //Maybe also use this large mode for changelogs eventually, or have it as a customizable size?
|
||||
{
|
||||
@ -61,6 +62,8 @@ InformationMessage::InformationMessage(String title, String message, bool large)
|
||||
okayButton->Appearance.BorderInactive = ui::Colour(200, 200, 200);
|
||||
okayButton->SetActionCallback({ [this] {
|
||||
CloseActiveWindow();
|
||||
if (callback.dismiss)
|
||||
callback.dismiss();
|
||||
SelfDestruct(); //TODO: Fix component disposal
|
||||
} });
|
||||
AddComponent(okayButton);
|
||||
|
@ -3,8 +3,15 @@
|
||||
|
||||
class InformationMessage : public ui::Window
|
||||
{
|
||||
struct DismissCallback
|
||||
{
|
||||
std::function<void ()> dismiss;
|
||||
};
|
||||
|
||||
DismissCallback callback;
|
||||
|
||||
public:
|
||||
InformationMessage(String title, String message, bool large);
|
||||
InformationMessage(String title, String message, bool large, DismissCallback callback_ = {});
|
||||
virtual ~InformationMessage() = default;
|
||||
|
||||
void OnDraw() override;
|
||||
|
@ -11,10 +11,6 @@
|
||||
#include "simulation/gravity/Gravity.h"
|
||||
#include "simulation/Simulation.h"
|
||||
#include "simulation/SimulationData.h"
|
||||
#include "gui/dialogues/ConfirmPrompt.h"
|
||||
#include "gui/dialogues/ErrorMessage.h"
|
||||
#include "gui/dialogues/InformationMessage.h"
|
||||
#include "gui/dialogues/TextPrompt.h"
|
||||
#include "gui/game/GameController.h"
|
||||
#include "gui/game/GameModel.h"
|
||||
#include "gui/interface/Engine.h"
|
||||
@ -264,7 +260,6 @@ void luacon_hook(lua_State * l, lua_Debug * ar)
|
||||
auto *luacon_ci = static_cast<LuaScriptInterface *>(commandInterface);
|
||||
if (ar->event == LUA_HOOKCOUNT && Platform::GetTime() - luacon_ci->luaExecutionStart > 3000)
|
||||
{
|
||||
if(ConfirmPrompt::Blocking("Script not responding", "The Lua script may have stopped responding. There might be an infinite loop. Press \"Stop\" to stop it", "Stop"))
|
||||
luaL_error(l, "Error: Script not responding");
|
||||
luacon_ci->luaExecutionStart = Platform::GetTime();
|
||||
}
|
||||
@ -303,13 +298,6 @@ int luatpt_getelement(lua_State *l)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int luatpt_error(lua_State* l)
|
||||
{
|
||||
String errorMessage = tpt_lua_optString(l, 1, "Error text");
|
||||
ErrorMessage::Blocking("Error", errorMessage);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int luatpt_drawtext(lua_State* l)
|
||||
{
|
||||
int textx, texty, textred, textgreen, textblue, textalpha;
|
||||
@ -1038,38 +1026,6 @@ int luatpt_delete(lua_State* l)
|
||||
return luaL_error(l,"Invalid coordinates or particle ID");
|
||||
}
|
||||
|
||||
int luatpt_input(lua_State* l)
|
||||
{
|
||||
String title = tpt_lua_optString(l, 1, "Title");
|
||||
String prompt = tpt_lua_optString(l, 2, "Enter some text:");
|
||||
String text = tpt_lua_optString(l, 3, "");
|
||||
String shadow = tpt_lua_optString(l, 4, "");
|
||||
|
||||
String result = TextPrompt::Blocking(title, prompt, text, shadow, false);
|
||||
|
||||
tpt_lua_pushString(l, result);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int luatpt_message_box(lua_State* l)
|
||||
{
|
||||
String title = tpt_lua_optString(l, 1, "Title");
|
||||
String message = tpt_lua_optString(l, 2, "Message");
|
||||
int large = lua_toboolean(l, 3);
|
||||
new InformationMessage(title, message, large);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int luatpt_confirm(lua_State *l)
|
||||
{
|
||||
String title = tpt_lua_optString(l, 1, "Title");
|
||||
String message = tpt_lua_optString(l, 2, "Message");
|
||||
String buttonText = tpt_lua_optString(l, 3, "Confirm");
|
||||
bool ret = ConfirmPrompt::Blocking(title, message, buttonText);
|
||||
lua_pushboolean(l, ret ? 1 : 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int luatpt_get_numOfParts(lua_State* l)
|
||||
{
|
||||
lua_pushinteger(l, luacon_sim->NUM_PARTS);
|
||||
|
@ -49,7 +49,6 @@ int luacon_transitionwrite(lua_State* l);
|
||||
//tpt. api
|
||||
int luatpt_getelement(lua_State *l);
|
||||
|
||||
int luatpt_error(lua_State* l);
|
||||
int luatpt_drawtext(lua_State* l);
|
||||
|
||||
int luatpt_create(lua_State* l);
|
||||
@ -96,9 +95,6 @@ int luatpt_textwidth(lua_State* l);
|
||||
int luatpt_get_name(lua_State* l);
|
||||
|
||||
int luatpt_delete(lua_State* l);
|
||||
int luatpt_input(lua_State* l);
|
||||
int luatpt_message_box(lua_State* l);
|
||||
int luatpt_confirm(lua_State* l);
|
||||
int luatpt_get_numOfParts(lua_State* l);
|
||||
int luatpt_start_getPartIndex(lua_State* l);
|
||||
int luatpt_next_getPartIndex(lua_State* l);
|
||||
|
@ -38,6 +38,10 @@
|
||||
#include "simulation/SaveRenderer.h"
|
||||
#include "simulation/Snapshot.h"
|
||||
|
||||
#include "gui/dialogues/ConfirmPrompt.h"
|
||||
#include "gui/dialogues/ErrorMessage.h"
|
||||
#include "gui/dialogues/InformationMessage.h"
|
||||
#include "gui/dialogues/TextPrompt.h"
|
||||
#include "gui/interface/Window.h"
|
||||
#include "gui/interface/Engine.h"
|
||||
#include "gui/game/GameView.h"
|
||||
@ -345,9 +349,6 @@ LuaScriptInterface::LuaScriptInterface(GameController * c, GameModel * m):
|
||||
{"textwidth", &luatpt_textwidth},
|
||||
{"get_name", &luatpt_get_name},
|
||||
{"delete", &luatpt_delete},
|
||||
{"input", &luatpt_input},
|
||||
{"message_box", &luatpt_message_box},
|
||||
{"confirm", &luatpt_confirm},
|
||||
{"get_numOfParts", &luatpt_get_numOfParts},
|
||||
{"start_getPartIndex", &luatpt_start_getPartIndex},
|
||||
{"next_getPartIndex", &luatpt_next_getPartIndex},
|
||||
@ -360,7 +361,6 @@ LuaScriptInterface::LuaScriptInterface(GameController * c, GameModel * m):
|
||||
{"num_menus", &luatpt_num_menus},
|
||||
{"decorations_enable", &luatpt_decorations_enable},
|
||||
{"display_mode", &luatpt_cmode_set},
|
||||
{"throw_error", &luatpt_error},
|
||||
{"heat", &luatpt_heat},
|
||||
{"setfire", &luatpt_setfire},
|
||||
{"setdebug", &luatpt_setdebug},
|
||||
@ -660,7 +660,124 @@ int LuaScriptInterface::tpt_newIndex(lua_State *l)
|
||||
return 0;
|
||||
}
|
||||
|
||||
//// Begin Interface API
|
||||
static int beginMessageBox(lua_State* l)
|
||||
{
|
||||
String title = tpt_lua_optString(l, 1, "Title");
|
||||
String message = tpt_lua_optString(l, 2, "Message");
|
||||
int large = lua_toboolean(l, 3);
|
||||
auto *luacon_ci = static_cast<LuaScriptInterface *>(commandInterface);
|
||||
auto cb = std::make_shared<LuaSmartRef>(luacon_ci->l); // * Bind to main lua state (might be different from l).
|
||||
cb->Assign(l, 4);
|
||||
new InformationMessage(title, message, large, { [cb]() {
|
||||
auto *luacon_ci = static_cast<LuaScriptInterface *>(commandInterface);
|
||||
auto l = luacon_ci->l;
|
||||
cb->Push(l);
|
||||
if (lua_isfunction(l, -1))
|
||||
{
|
||||
if (lua_pcall(l, 0, 0, 0))
|
||||
{
|
||||
luacon_ci->Log(CommandInterface::LogError, luacon_geterror());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pop(l, 1);
|
||||
}
|
||||
} });
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int beginThrowError(lua_State* l)
|
||||
{
|
||||
String errorMessage = tpt_lua_optString(l, 1, "Error text");
|
||||
auto *luacon_ci = static_cast<LuaScriptInterface *>(commandInterface);
|
||||
auto cb = std::make_shared<LuaSmartRef>(luacon_ci->l); // * Bind to main lua state (might be different from l).
|
||||
cb->Assign(l, 2);
|
||||
new ErrorMessage("Error", errorMessage, { [cb]() {
|
||||
auto *luacon_ci = static_cast<LuaScriptInterface *>(commandInterface);
|
||||
auto l = luacon_ci->l;
|
||||
cb->Push(l);
|
||||
if (lua_isfunction(l, -1))
|
||||
{
|
||||
if (lua_pcall(l, 0, 0, 0))
|
||||
{
|
||||
luacon_ci->Log(CommandInterface::LogError, luacon_geterror());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pop(l, 1);
|
||||
}
|
||||
} });
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int beginInput(lua_State* l)
|
||||
{
|
||||
String title = tpt_lua_optString(l, 1, "Title");
|
||||
String prompt = tpt_lua_optString(l, 2, "Enter some text:");
|
||||
String text = tpt_lua_optString(l, 3, "");
|
||||
String shadow = tpt_lua_optString(l, 4, "");
|
||||
auto *luacon_ci = static_cast<LuaScriptInterface *>(commandInterface);
|
||||
auto cb = std::make_shared<LuaSmartRef>(luacon_ci->l); // * Bind to main lua state (might be different from l).
|
||||
cb->Assign(l, 5);
|
||||
auto handle = [cb](const String &input) {
|
||||
auto *luacon_ci = static_cast<LuaScriptInterface *>(commandInterface);
|
||||
auto l = luacon_ci->l;
|
||||
cb->Push(l);
|
||||
if (lua_isfunction(l, -1))
|
||||
{
|
||||
tpt_lua_pushString(l, input);
|
||||
if (lua_pcall(l, 1, 0, 0))
|
||||
{
|
||||
luacon_ci->Log(CommandInterface::LogError, luacon_geterror());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pop(l, 1);
|
||||
}
|
||||
};
|
||||
new TextPrompt(title, prompt, text, shadow, false, { [handle](const String &input) {
|
||||
handle(input);
|
||||
}, [handle]() {
|
||||
handle({}); // * Has always returned empty string >_>
|
||||
} });
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int beginConfirm(lua_State *l)
|
||||
{
|
||||
String title = tpt_lua_optString(l, 1, "Title");
|
||||
String message = tpt_lua_optString(l, 2, "Message");
|
||||
String buttonText = tpt_lua_optString(l, 3, "Confirm");
|
||||
auto *luacon_ci = static_cast<LuaScriptInterface *>(commandInterface);
|
||||
auto cb = std::make_shared<LuaSmartRef>(luacon_ci->l); // * Bind to main lua state (might be different from l).
|
||||
cb->Assign(l, 4);
|
||||
auto handle = [cb](int result) {
|
||||
auto *luacon_ci = static_cast<LuaScriptInterface *>(commandInterface);
|
||||
auto l = luacon_ci->l;
|
||||
cb->Push(l);
|
||||
if (lua_isfunction(l, -1))
|
||||
{
|
||||
lua_pushboolean(l, result);
|
||||
if (lua_pcall(l, 1, 0, 0))
|
||||
{
|
||||
luacon_ci->Log(CommandInterface::LogError, luacon_geterror());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pop(l, 1);
|
||||
}
|
||||
};
|
||||
new ConfirmPrompt(title, message, { [handle]() {
|
||||
handle(1);
|
||||
}, [handle]() {
|
||||
handle(0);
|
||||
} }, buttonText);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void LuaScriptInterface::initInterfaceAPI()
|
||||
{
|
||||
@ -672,6 +789,10 @@ void LuaScriptInterface::initInterfaceAPI()
|
||||
{"grabTextInput", interface_grabTextInput},
|
||||
{"dropTextInput", interface_dropTextInput},
|
||||
{"textInputRect", interface_textInputRect},
|
||||
{"beginInput", beginInput},
|
||||
{"beginMessageBox", beginMessageBox},
|
||||
{"beginConfirm", beginConfirm},
|
||||
{"beginThrowError", beginThrowError},
|
||||
{NULL, NULL}
|
||||
};
|
||||
luaL_register(l, "interface", interfaceAPIMethods);
|
||||
@ -4431,8 +4552,9 @@ void LuaScriptInterface::OnTick()
|
||||
new ErrorMessage("Script download", ByteString(http::StatusText(ret)).FromUtf8());
|
||||
return;
|
||||
}
|
||||
if (Platform::FileExists(scriptDownloadFilename) && scriptDownloadConfirmPrompt && !ConfirmPrompt::Blocking("File already exists, overwrite?", scriptDownloadFilename.FromUtf8(), "Overwrite"))
|
||||
if (Platform::FileExists(scriptDownloadFilename))
|
||||
{
|
||||
new ErrorMessage("Script download", "File already exists");
|
||||
return;
|
||||
}
|
||||
if (!Platform::WriteFile(std::vector<char>(scriptData.begin(), scriptData.end()), scriptDownloadFilename))
|
||||
@ -4885,7 +5007,6 @@ int LuaScriptInterface::luatpt_getscript(lua_State* l)
|
||||
int scriptID = luaL_checkinteger(l, 1);
|
||||
auto filename = tpt_lua_checkByteString(l, 2);
|
||||
bool runScript = luaL_optint(l, 3, 0);
|
||||
int confirmPrompt = luaL_optint(l, 4, 1);
|
||||
|
||||
if (luacon_ci->scriptDownload)
|
||||
{
|
||||
@ -4894,16 +5015,11 @@ int LuaScriptInterface::luatpt_getscript(lua_State* l)
|
||||
}
|
||||
|
||||
ByteString url = ByteString::Build(SCHEME, "starcatcher.us/scripts/main.lua?get=", scriptID);
|
||||
if (confirmPrompt && !ConfirmPrompt::Blocking("Do you want to install script?", url.FromUtf8(), "Install"))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
luacon_ci->scriptDownload = std::make_unique<http::Request>(url);
|
||||
luacon_ci->scriptDownload->Start();
|
||||
luacon_ci->scriptDownloadFilename = filename;
|
||||
luacon_ci->scriptDownloadRunScript = runScript;
|
||||
luacon_ci->scriptDownloadConfirmPrompt = confirmPrompt;
|
||||
|
||||
luacon_controller->HideConsole();
|
||||
return 0;
|
||||
|
@ -31,7 +31,6 @@ class LuaScriptInterface: public TPTScriptInterface
|
||||
std::unique_ptr<http::Request> scriptDownload;
|
||||
ByteString scriptDownloadFilename;
|
||||
bool scriptDownloadRunScript;
|
||||
bool scriptDownloadConfirmPrompt;
|
||||
|
||||
int luacon_mousex, luacon_mousey, luacon_mousebutton;
|
||||
ByteString luacon_selectedl, luacon_selectedr, luacon_selectedalt, luacon_selectedreplace;
|
||||
|
Loading…
Reference in New Issue
Block a user