diff --git a/src/graphics/ui/elements/InlineFrame.cpp b/src/graphics/ui/elements/InlineFrame.cpp index 8699fd70b..acf00916e 100644 --- a/src/graphics/ui/elements/InlineFrame.cpp +++ b/src/graphics/ui/elements/InlineFrame.cpp @@ -35,8 +35,15 @@ void InlineFrame::setDocument(const std::shared_ptr& document) { root->setSize(size); - gui.postRunnable([this]() { - scripting::on_ui_open(*this->document, {}); + gui.postRunnable([weak = weak_from_this(), document]() { + auto node = weak.lock(); + if (node == nullptr) { + return; + } + if (static_cast(*node).document != document) { + return; + } + scripting::on_ui_open(*document, {}); }); } diff --git a/src/logic/scripting/scripting_functional.cpp b/src/logic/scripting/scripting_functional.cpp index a6ef42a48..c71133ca8 100644 --- a/src/logic/scripting/scripting_functional.cpp +++ b/src/logic/scripting/scripting_functional.cpp @@ -99,14 +99,21 @@ template std::function create_supplier( const scriptenv& env, const std::string& src, const std::string& file ) { - return [=]() { + return [=, errorLogged = false]() mutable { + lua::stackguard guard(lua::get_main_state()); if (auto L = process_callback(env, src, file)) { - if (lua::isfunction(L, -1)) { - lua::call_nothrow(L, 0); + if (lua::isfunction(L, -1) && !lua::call_nothrow(L, 0)) { + return T {}; + } + try { + return tovalueFunc(L, -1); + } catch (const std::exception& err) { + if (!errorLogged) { + logger.error() << "supplier " << util::quote(src) << ": " + << err.what(); + errorLogged = true; + } } - auto str = tovalueFunc(L, -1); - lua::pop(L); - return str; } return T {}; }; @@ -158,16 +165,33 @@ int_array_consumer scripting::create_int_array_consumer( vec2supplier scripting::create_vec2_supplier( const scriptenv& env, const std::string& src, const std::string& file ) { - return [=]() { - if (auto L = process_callback(env, src, file)) { - if (lua::isfunction(L, -1)) { - lua::call_nothrow(L, 0); + return [=, errorLogged = false]() mutable { + auto L = lua::get_main_state(); + lua::stackguard guard(L); + int top = lua::gettop(L); + if (process_callback(env, src, file)) { + if (lua::isfunction(L, -1) && !lua::call_nothrow(L, 0)) { + return glm::vec2(0, 0); + } + if (lua::gettop(L) - top < 2) { + if (!errorLogged) { + logger.error() << "supplier " << util::quote(src) + << ": two numbers expected"; + errorLogged = true; + } + return glm::vec2(0, 0); + } + try { + auto y = lua::tonumber(L, -1); + auto x = lua::tonumber(L, -2); + return glm::vec2(x, y); + } catch (const std::exception& err) { + if (!errorLogged) { + logger.error() << "supplier " << util::quote(src) << ": " + << err.what(); + errorLogged = true; + } } - auto y = lua::tonumber(L, -1); - lua::pop(L); - auto x = lua::tonumber(L, -1); - lua::pop(L); - return glm::vec2(x, y); } return glm::vec2(0, 0); };