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/graphics/ui/elements/SplitBox.cpp b/src/graphics/ui/elements/SplitBox.cpp index 247ef7410..c35374529 100644 --- a/src/graphics/ui/elements/SplitBox.cpp +++ b/src/graphics/ui/elements/SplitBox.cpp @@ -82,6 +82,19 @@ void SplitBox::doubleClick(int x, int y) { refresh(); } +std::shared_ptr SplitBox::getAt(const glm::vec2& pos) { + auto hover = Container::getAt(pos); + if (hover.get() != this) { + return hover; + } + for (const auto& node : nodes) { + if (node->isVisible() && node->isInside(pos)) { + return nullptr; + } + } + return hover; +} + void SplitBox::fullRefresh() { refresh(); reposition(); diff --git a/src/graphics/ui/elements/SplitBox.hpp b/src/graphics/ui/elements/SplitBox.hpp index 8482e73ec..1a452c2ff 100644 --- a/src/graphics/ui/elements/SplitBox.hpp +++ b/src/graphics/ui/elements/SplitBox.hpp @@ -11,6 +11,7 @@ namespace gui { virtual void refresh() override; virtual void fullRefresh() override; virtual void doubleClick(int x, int y) override; + virtual std::shared_ptr getAt(const glm::vec2& pos) override; private: float splitPos; }; 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); };