From 990096ff9b551382c6e8c88adf06424565dcdedb Mon Sep 17 00:00:00 2001 From: uramer Date: Tue, 4 Mar 2025 21:03:15 +0100 Subject: [PATCH] Fix in-game actions not clearing because of input bindings only initializing in menu context --- apps/openmw/mwlua/corebindings.cpp | 4 +- apps/openmw/mwlua/inputbindings.cpp | 180 ++++++++++++++++------------ 2 files changed, 103 insertions(+), 81 deletions(-) diff --git a/apps/openmw/mwlua/corebindings.cpp b/apps/openmw/mwlua/corebindings.cpp index 445bcdd617..9df435c00d 100644 --- a/apps/openmw/mwlua/corebindings.cpp +++ b/apps/openmw/mwlua/corebindings.cpp @@ -148,7 +148,7 @@ namespace MWLua }; } - sol::table readOnly = LuaUtil::makeReadOnly(api); - return context.setTypePackage(readOnly, "openmw_core"); + sol::table readOnlyApi = LuaUtil::makeReadOnly(api); + return context.setTypePackage(readOnlyApi, "openmw_core"); } } diff --git a/apps/openmw/mwlua/inputbindings.cpp b/apps/openmw/mwlua/inputbindings.cpp index 27c6714bb4..c3b47c5061 100644 --- a/apps/openmw/mwlua/inputbindings.cpp +++ b/apps/openmw/mwlua/inputbindings.cpp @@ -38,94 +38,116 @@ namespace MWLua sol::table initInputPackage(const Context& context) { + sol::object cached = context.getTypePackage("openmw_input"); + if (cached != sol::nil) + return cached; sol::state_view lua = context.sol(); - { - if (lua["openmw_input"] != sol::nil) - return lua["openmw_input"]; - } - sol::usertype keyEvent = lua.new_usertype("KeyEvent"); - keyEvent["symbol"] = sol::readonly_property([](const SDL_Keysym& e) { - if (e.sym > 0 && e.sym <= 255) - return std::string(1, static_cast(e.sym)); - else - return std::string(); + context.cachePackage("openmw_input_keyevent", [&lua]() { + sol::usertype keyEvent = lua.new_usertype("KeyEvent"); + keyEvent["symbol"] = sol::readonly_property([](const SDL_Keysym& e) { + if (e.sym > 0 && e.sym <= 255) + return std::string(1, static_cast(e.sym)); + else + return std::string(); + }); + keyEvent["code"] = sol::readonly_property([](const SDL_Keysym& e) -> int { return e.scancode; }); + keyEvent["withShift"] + = sol::readonly_property([](const SDL_Keysym& e) -> bool { return e.mod & KMOD_SHIFT; }); + keyEvent["withCtrl"] + = sol::readonly_property([](const SDL_Keysym& e) -> bool { return e.mod & KMOD_CTRL; }); + keyEvent["withAlt"] = sol::readonly_property([](const SDL_Keysym& e) -> bool { return e.mod & KMOD_ALT; }); + keyEvent["withSuper"] + = sol::readonly_property([](const SDL_Keysym& e) -> bool { return e.mod & KMOD_GUI; }); + + return sol::table(lua, sol::create); }); - keyEvent["code"] = sol::readonly_property([](const SDL_Keysym& e) -> int { return e.scancode; }); - keyEvent["withShift"] = sol::readonly_property([](const SDL_Keysym& e) -> bool { return e.mod & KMOD_SHIFT; }); - keyEvent["withCtrl"] = sol::readonly_property([](const SDL_Keysym& e) -> bool { return e.mod & KMOD_CTRL; }); - keyEvent["withAlt"] = sol::readonly_property([](const SDL_Keysym& e) -> bool { return e.mod & KMOD_ALT; }); - keyEvent["withSuper"] = sol::readonly_property([](const SDL_Keysym& e) -> bool { return e.mod & KMOD_GUI; }); - auto touchpadEvent = lua.new_usertype("TouchpadEvent"); - touchpadEvent["device"] = sol::readonly_property([](const SDLUtil::TouchEvent& e) -> int { return e.mDevice; }); - touchpadEvent["finger"] = sol::readonly_property([](const SDLUtil::TouchEvent& e) -> int { return e.mFinger; }); - touchpadEvent["position"] = sol::readonly_property([](const SDLUtil::TouchEvent& e) -> osg::Vec2f { - return { e.mX, e.mY }; + context.cachePackage("openmw_input_touchpadevent", [&lua]() { + auto touchpadEvent = lua.new_usertype("TouchpadEvent"); + touchpadEvent["device"] + = sol::readonly_property([](const SDLUtil::TouchEvent& e) -> int { return e.mDevice; }); + touchpadEvent["finger"] + = sol::readonly_property([](const SDLUtil::TouchEvent& e) -> int { return e.mFinger; }); + touchpadEvent["position"] = sol::readonly_property([](const SDLUtil::TouchEvent& e) -> osg::Vec2f { + return { e.mX, e.mY }; + }); + touchpadEvent["pressure"] + = sol::readonly_property([](const SDLUtil::TouchEvent& e) -> float { return e.mPressure; }); + return sol::table(lua, sol::create); }); - touchpadEvent["pressure"] - = sol::readonly_property([](const SDLUtil::TouchEvent& e) -> float { return e.mPressure; }); - auto inputActions = lua.new_usertype("InputActions"); - inputActions[sol::meta_function::index] - = [](LuaUtil::InputAction::Registry& registry, std::string_view key) { return registry[key]; }; - { - auto pairs = [](LuaUtil::InputAction::Registry& registry) { - auto next - = [](LuaUtil::InputAction::Registry& registry, - std::string_view key) -> sol::optional> { - std::optional nextKey(registry.nextKey(key)); - if (!nextKey.has_value()) - return sol::nullopt; - else - return std::make_tuple(*nextKey, registry[*nextKey].value()); + context.cachePackage("openmw_input_inputactions", [&lua]() { + auto inputActions = lua.new_usertype("InputActions"); + inputActions[sol::meta_function::index] + = [](LuaUtil::InputAction::Registry& registry, std::string_view key) { return registry[key]; }; + { + auto pairs = [](LuaUtil::InputAction::Registry& registry) { + auto next = [](LuaUtil::InputAction::Registry& registry, std::string_view key) + -> sol::optional> { + std::optional nextKey(registry.nextKey(key)); + if (!nextKey.has_value()) + return sol::nullopt; + else + return std::make_tuple(*nextKey, registry[*nextKey].value()); + }; + return std::make_tuple(next, registry, registry.firstKey()); }; - return std::make_tuple(next, registry, registry.firstKey()); - }; - inputActions[sol::meta_function::pairs] = pairs; - } + inputActions[sol::meta_function::pairs] = pairs; + } + return sol::table(lua, sol::create); + }); - auto actionInfo = lua.new_usertype("ActionInfo"); - actionInfo["key"] = sol::readonly_property( - [](const LuaUtil::InputAction::Info& info) -> std::string_view { return info.mKey; }); - actionInfo["name"] = sol::readonly_property( - [](const LuaUtil::InputAction::Info& info) -> std::string_view { return info.mName; }); - actionInfo["description"] = sol::readonly_property( - [](const LuaUtil::InputAction::Info& info) -> std::string_view { return info.mDescription; }); - actionInfo["l10n"] = sol::readonly_property( - [](const LuaUtil::InputAction::Info& info) -> std::string_view { return info.mL10n; }); - actionInfo["type"] = sol::readonly_property([](const LuaUtil::InputAction::Info& info) { return info.mType; }); - actionInfo["defaultValue"] - = sol::readonly_property([](const LuaUtil::InputAction::Info& info) { return info.mDefaultValue; }); + context.cachePackage("openmw_input_actioninfo", [&lua]() { + auto actionInfo = lua.new_usertype("ActionInfo"); + actionInfo["key"] = sol::readonly_property( + [](const LuaUtil::InputAction::Info& info) -> std::string_view { return info.mKey; }); + actionInfo["name"] = sol::readonly_property( + [](const LuaUtil::InputAction::Info& info) -> std::string_view { return info.mName; }); + actionInfo["description"] = sol::readonly_property( + [](const LuaUtil::InputAction::Info& info) -> std::string_view { return info.mDescription; }); + actionInfo["l10n"] = sol::readonly_property( + [](const LuaUtil::InputAction::Info& info) -> std::string_view { return info.mL10n; }); + actionInfo["type"] + = sol::readonly_property([](const LuaUtil::InputAction::Info& info) { return info.mType; }); + actionInfo["defaultValue"] + = sol::readonly_property([](const LuaUtil::InputAction::Info& info) { return info.mDefaultValue; }); + return sol::table(lua, sol::create); + }); - auto inputTriggers = lua.new_usertype("InputTriggers"); - inputTriggers[sol::meta_function::index] - = [](LuaUtil::InputTrigger::Registry& registry, std::string_view key) { return registry[key]; }; - { - auto pairs = [](LuaUtil::InputTrigger::Registry& registry) { - auto next - = [](LuaUtil::InputTrigger::Registry& registry, - std::string_view key) -> sol::optional> { - std::optional nextKey(registry.nextKey(key)); - if (!nextKey.has_value()) - return sol::nullopt; - else - return std::make_tuple(*nextKey, registry[*nextKey].value()); + context.cachePackage("openmw_input_inputtriggers", [&lua]() { + auto inputTriggers = lua.new_usertype("InputTriggers"); + inputTriggers[sol::meta_function::index] + = [](LuaUtil::InputTrigger::Registry& registry, std::string_view key) { return registry[key]; }; + { + auto pairs = [](LuaUtil::InputTrigger::Registry& registry) { + auto next = [](LuaUtil::InputTrigger::Registry& registry, std::string_view key) + -> sol::optional> { + std::optional nextKey(registry.nextKey(key)); + if (!nextKey.has_value()) + return sol::nullopt; + else + return std::make_tuple(*nextKey, registry[*nextKey].value()); + }; + return std::make_tuple(next, registry, registry.firstKey()); }; - return std::make_tuple(next, registry, registry.firstKey()); - }; - inputTriggers[sol::meta_function::pairs] = pairs; - } + inputTriggers[sol::meta_function::pairs] = pairs; + } + return sol::table(lua, sol::create); + }); - auto triggerInfo = lua.new_usertype("TriggerInfo"); - triggerInfo["key"] = sol::readonly_property( - [](const LuaUtil::InputTrigger::Info& info) -> std::string_view { return info.mKey; }); - triggerInfo["name"] = sol::readonly_property( - [](const LuaUtil::InputTrigger::Info& info) -> std::string_view { return info.mName; }); - triggerInfo["description"] = sol::readonly_property( - [](const LuaUtil::InputTrigger::Info& info) -> std::string_view { return info.mDescription; }); - triggerInfo["l10n"] = sol::readonly_property( - [](const LuaUtil::InputTrigger::Info& info) -> std::string_view { return info.mL10n; }); + context.cachePackage("openmw_input_triggerinfo", [&lua]() { + auto triggerInfo = lua.new_usertype("TriggerInfo"); + triggerInfo["key"] = sol::readonly_property( + [](const LuaUtil::InputTrigger::Info& info) -> std::string_view { return info.mKey; }); + triggerInfo["name"] = sol::readonly_property( + [](const LuaUtil::InputTrigger::Info& info) -> std::string_view { return info.mName; }); + triggerInfo["description"] = sol::readonly_property( + [](const LuaUtil::InputTrigger::Info& info) -> std::string_view { return info.mDescription; }); + triggerInfo["l10n"] = sol::readonly_property( + [](const LuaUtil::InputTrigger::Info& info) -> std::string_view { return info.mL10n; }); + return sol::table(lua, sol::create); + }); MWBase::InputManager* input = MWBase::Environment::get().getInputManager(); sol::table api(lua, sol::create); @@ -449,8 +471,8 @@ namespace MWLua { "Tab", SDL_SCANCODE_TAB }, })); - lua["openmw_input"] = LuaUtil::makeReadOnly(api); - return lua["openmw_input"]; + sol::table readOnlyApi = LuaUtil::makeReadOnly(api); + return context.setTypePackage(readOnlyApi, "openmw_input"); } }