Merge branch 'context_matters' into 'master'
Some checks are pending
Build and test / Windows (2019) (push) Blocked by required conditions
Build and test / Windows (2022) (push) Blocked by required conditions
Build and test / Ubuntu (push) Waiting to run
Build and test / MacOS (push) Waiting to run
Build and test / Read .env file and expose it as output (push) Waiting to run

Fix in-game actions not clearing because of input bindings only initializing in menu context

See merge request OpenMW/openmw!4570
This commit is contained in:
psi29a 2025-03-05 21:18:02 +00:00
commit 95312139d5
2 changed files with 103 additions and 81 deletions

View file

@ -148,7 +148,7 @@ namespace MWLua
}; };
} }
sol::table readOnly = LuaUtil::makeReadOnly(api); sol::table readOnlyApi = LuaUtil::makeReadOnly(api);
return context.setTypePackage(readOnly, "openmw_core"); return context.setTypePackage(readOnlyApi, "openmw_core");
} }
} }

View file

@ -38,94 +38,116 @@ namespace MWLua
sol::table initInputPackage(const Context& context) 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(); sol::state_view lua = context.sol();
{
if (lua["openmw_input"] != sol::nil)
return lua["openmw_input"];
}
sol::usertype<SDL_Keysym> keyEvent = lua.new_usertype<SDL_Keysym>("KeyEvent"); context.cachePackage("openmw_input_keyevent", [&lua]() {
keyEvent["symbol"] = sol::readonly_property([](const SDL_Keysym& e) { sol::usertype<SDL_Keysym> keyEvent = lua.new_usertype<SDL_Keysym>("KeyEvent");
if (e.sym > 0 && e.sym <= 255) keyEvent["symbol"] = sol::readonly_property([](const SDL_Keysym& e) {
return std::string(1, static_cast<char>(e.sym)); if (e.sym > 0 && e.sym <= 255)
else return std::string(1, static_cast<char>(e.sym));
return std::string(); 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<SDLUtil::TouchEvent>("TouchpadEvent"); context.cachePackage("openmw_input_touchpadevent", [&lua]() {
touchpadEvent["device"] = sol::readonly_property([](const SDLUtil::TouchEvent& e) -> int { return e.mDevice; }); auto touchpadEvent = lua.new_usertype<SDLUtil::TouchEvent>("TouchpadEvent");
touchpadEvent["finger"] = sol::readonly_property([](const SDLUtil::TouchEvent& e) -> int { return e.mFinger; }); touchpadEvent["device"]
touchpadEvent["position"] = sol::readonly_property([](const SDLUtil::TouchEvent& e) -> osg::Vec2f { = sol::readonly_property([](const SDLUtil::TouchEvent& e) -> int { return e.mDevice; });
return { e.mX, e.mY }; 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<LuaUtil::InputAction::Registry>("InputActions"); context.cachePackage("openmw_input_inputactions", [&lua]() {
inputActions[sol::meta_function::index] auto inputActions = lua.new_usertype<LuaUtil::InputAction::Registry>("InputActions");
= [](LuaUtil::InputAction::Registry& registry, std::string_view key) { return registry[key]; }; inputActions[sol::meta_function::index]
{ = [](LuaUtil::InputAction::Registry& registry, std::string_view key) { return registry[key]; };
auto pairs = [](LuaUtil::InputAction::Registry& registry) { {
auto next auto pairs = [](LuaUtil::InputAction::Registry& registry) {
= [](LuaUtil::InputAction::Registry& registry, auto next = [](LuaUtil::InputAction::Registry& registry, std::string_view key)
std::string_view key) -> sol::optional<std::tuple<std::string, LuaUtil::InputAction::Info>> { -> sol::optional<std::tuple<std::string, LuaUtil::InputAction::Info>> {
std::optional<std::string> nextKey(registry.nextKey(key)); std::optional<std::string> nextKey(registry.nextKey(key));
if (!nextKey.has_value()) if (!nextKey.has_value())
return sol::nullopt; return sol::nullopt;
else else
return std::make_tuple(*nextKey, registry[*nextKey].value()); 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<LuaUtil::InputAction::Info>("ActionInfo"); context.cachePackage("openmw_input_actioninfo", [&lua]() {
actionInfo["key"] = sol::readonly_property( auto actionInfo = lua.new_usertype<LuaUtil::InputAction::Info>("ActionInfo");
[](const LuaUtil::InputAction::Info& info) -> std::string_view { return info.mKey; }); actionInfo["key"] = sol::readonly_property(
actionInfo["name"] = sol::readonly_property( [](const LuaUtil::InputAction::Info& info) -> std::string_view { return info.mKey; });
[](const LuaUtil::InputAction::Info& info) -> std::string_view { return info.mName; }); actionInfo["name"] = sol::readonly_property(
actionInfo["description"] = sol::readonly_property( [](const LuaUtil::InputAction::Info& info) -> std::string_view { return info.mName; });
[](const LuaUtil::InputAction::Info& info) -> std::string_view { return info.mDescription; }); actionInfo["description"] = sol::readonly_property(
actionInfo["l10n"] = sol::readonly_property( [](const LuaUtil::InputAction::Info& info) -> std::string_view { return info.mDescription; });
[](const LuaUtil::InputAction::Info& info) -> std::string_view { return info.mL10n; }); actionInfo["l10n"] = sol::readonly_property(
actionInfo["type"] = sol::readonly_property([](const LuaUtil::InputAction::Info& info) { return info.mType; }); [](const LuaUtil::InputAction::Info& info) -> std::string_view { return info.mL10n; });
actionInfo["defaultValue"] actionInfo["type"]
= sol::readonly_property([](const LuaUtil::InputAction::Info& info) { return info.mDefaultValue; }); = 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<LuaUtil::InputTrigger::Registry>("InputTriggers"); context.cachePackage("openmw_input_inputtriggers", [&lua]() {
inputTriggers[sol::meta_function::index] auto inputTriggers = lua.new_usertype<LuaUtil::InputTrigger::Registry>("InputTriggers");
= [](LuaUtil::InputTrigger::Registry& registry, std::string_view key) { return registry[key]; }; inputTriggers[sol::meta_function::index]
{ = [](LuaUtil::InputTrigger::Registry& registry, std::string_view key) { return registry[key]; };
auto pairs = [](LuaUtil::InputTrigger::Registry& registry) { {
auto next auto pairs = [](LuaUtil::InputTrigger::Registry& registry) {
= [](LuaUtil::InputTrigger::Registry& registry, auto next = [](LuaUtil::InputTrigger::Registry& registry, std::string_view key)
std::string_view key) -> sol::optional<std::tuple<std::string, LuaUtil::InputTrigger::Info>> { -> sol::optional<std::tuple<std::string, LuaUtil::InputTrigger::Info>> {
std::optional<std::string> nextKey(registry.nextKey(key)); std::optional<std::string> nextKey(registry.nextKey(key));
if (!nextKey.has_value()) if (!nextKey.has_value())
return sol::nullopt; return sol::nullopt;
else else
return std::make_tuple(*nextKey, registry[*nextKey].value()); 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<LuaUtil::InputTrigger::Info>("TriggerInfo"); context.cachePackage("openmw_input_triggerinfo", [&lua]() {
triggerInfo["key"] = sol::readonly_property( auto triggerInfo = lua.new_usertype<LuaUtil::InputTrigger::Info>("TriggerInfo");
[](const LuaUtil::InputTrigger::Info& info) -> std::string_view { return info.mKey; }); triggerInfo["key"] = sol::readonly_property(
triggerInfo["name"] = sol::readonly_property( [](const LuaUtil::InputTrigger::Info& info) -> std::string_view { return info.mKey; });
[](const LuaUtil::InputTrigger::Info& info) -> std::string_view { return info.mName; }); triggerInfo["name"] = sol::readonly_property(
triggerInfo["description"] = sol::readonly_property( [](const LuaUtil::InputTrigger::Info& info) -> std::string_view { return info.mName; });
[](const LuaUtil::InputTrigger::Info& info) -> std::string_view { return info.mDescription; }); triggerInfo["description"] = sol::readonly_property(
triggerInfo["l10n"] = sol::readonly_property( [](const LuaUtil::InputTrigger::Info& info) -> std::string_view { return info.mDescription; });
[](const LuaUtil::InputTrigger::Info& info) -> std::string_view { return info.mL10n; }); 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(); MWBase::InputManager* input = MWBase::Environment::get().getInputManager();
sol::table api(lua, sol::create); sol::table api(lua, sol::create);
@ -449,8 +471,8 @@ namespace MWLua
{ "Tab", SDL_SCANCODE_TAB }, { "Tab", SDL_SCANCODE_TAB },
})); }));
lua["openmw_input"] = LuaUtil::makeReadOnly(api); sol::table readOnlyApi = LuaUtil::makeReadOnly(api);
return lua["openmw_input"]; return context.setTypePackage(readOnlyApi, "openmw_input");
} }
} }