From b9afd7245cd0ceea18658c97df4bd19c86994d17 Mon Sep 17 00:00:00 2001 From: uramer Date: Sat, 13 Jan 2024 00:47:08 +0100 Subject: [PATCH] Create separate UI api tables for menu and player contexts --- apps/openmw/mwlua/inputprocessor.hpp | 16 ++-- apps/openmw/mwlua/uibindings.cpp | 119 ++++++++++++++------------- components/lua_ui/element.cpp | 17 ++-- components/lua_ui/element.hpp | 18 ++-- components/lua_ui/scriptsettings.hpp | 1 - components/lua_ui/util.cpp | 4 +- 6 files changed, 85 insertions(+), 90 deletions(-) diff --git a/apps/openmw/mwlua/inputprocessor.hpp b/apps/openmw/mwlua/inputprocessor.hpp index fe6de5450e..e005183098 100644 --- a/apps/openmw/mwlua/inputprocessor.hpp +++ b/apps/openmw/mwlua/inputprocessor.hpp @@ -58,14 +58,14 @@ namespace MWLua private: Container* mScriptsContainer; - Container::EngineHandlerList mKeyPressHandlers{ "onKeyPress" }; - Container::EngineHandlerList mKeyReleaseHandlers{ "onKeyRelease" }; - Container::EngineHandlerList mControllerButtonPressHandlers{ "onControllerButtonPress" }; - Container::EngineHandlerList mControllerButtonReleaseHandlers{ "onControllerButtonRelease" }; - Container::EngineHandlerList mActionHandlers{ "onInputAction" }; - Container::EngineHandlerList mTouchpadPressed{ "onTouchPress" }; - Container::EngineHandlerList mTouchpadReleased{ "onTouchRelease" }; - Container::EngineHandlerList mTouchpadMoved{ "onTouchMove" }; + typename Container::EngineHandlerList mKeyPressHandlers{ "onKeyPress" }; + typename Container::EngineHandlerList mKeyReleaseHandlers{ "onKeyRelease" }; + typename Container::EngineHandlerList mControllerButtonPressHandlers{ "onControllerButtonPress" }; + typename Container::EngineHandlerList mControllerButtonReleaseHandlers{ "onControllerButtonRelease" }; + typename Container::EngineHandlerList mActionHandlers{ "onInputAction" }; + typename Container::EngineHandlerList mTouchpadPressed{ "onTouchPress" }; + typename Container::EngineHandlerList mTouchpadReleased{ "onTouchRelease" }; + typename Container::EngineHandlerList mTouchpadMoved{ "onTouchMove" }; }; } diff --git a/apps/openmw/mwlua/uibindings.cpp b/apps/openmw/mwlua/uibindings.cpp index 061dc4821a..354fd83ec2 100644 --- a/apps/openmw/mwlua/uibindings.cpp +++ b/apps/openmw/mwlua/uibindings.cpp @@ -89,39 +89,10 @@ namespace MWLua }(); } - sol::table initUserInterfacePackage(const Context& context) + sol::table registerUiApi(const Context& context, bool menu) { - { - sol::state_view& lua = context.mLua->sol(); - if (lua["openmw_ui"] != sol::nil) - return lua["openmw_ui"]; - } - MWBase::WindowManager* windowManager = MWBase::Environment::get().getWindowManager(); - auto element = context.mLua->sol().new_usertype("Element"); - element[sol::meta_function::to_string] = [](const LuaUi::Element& element) { - std::stringstream res; - res << "UiElement"; - if (element.mLayer != "") - res << "[" << element.mLayer << "]"; - return res.str(); - }; - element["layout"] = sol::property([](LuaUi::Element& element) { return element.mLayout; }, - [](LuaUi::Element& element, const sol::table& layout) { element.mLayout = layout; }); - element["update"] = [luaManager = context.mLuaManager](const std::shared_ptr& element) { - if (element->mDestroy || element->mUpdate) - return; - element->mUpdate = true; - luaManager->addAction([element] { wrapAction(element, [&] { element->update(); }); }, "Update UI"); - }; - element["destroy"] = [luaManager = context.mLuaManager](const std::shared_ptr& element) { - if (element->mDestroy) - return; - element->mDestroy = true; - luaManager->addAction([element] { wrapAction(element, [&] { element->destroy(); }); }, "Destroy UI"); - }; - sol::table api = context.mLua->newTable(); api["_setHudVisibility"] = [luaManager = context.mLuaManager](bool state) { luaManager->addAction([state] { MWBase::Environment::get().getWindowManager()->setHudVisibility(state); }); @@ -155,36 +126,20 @@ namespace MWLua } }; api["content"] = LuaUi::loadContentConstructor(context.mLua); - api["create"] = [context](const sol::table& layout) { - auto element - = context.mIsMenu ? LuaUi::Element::makeMenuElement(layout) : LuaUi::Element::makeGameElement(layout); - context.mLuaManager->addAction([element] { wrapAction(element, [&] { element->create(); }); }, "Create UI"); + + api["create"] = [luaManager = context.mLuaManager, menu](const sol::table& layout) { + auto element = LuaUi::Element::make(layout, menu); + luaManager->addAction([element] { wrapAction(element, [&] { element->create(); }); }, "Create UI"); return element; }; - api["updateAll"] = [context]() { - if (context.mIsMenu) - { - LuaUi::Element::forEachMenuElement([](LuaUi::Element* e) { e->mUpdate = true; }); - context.mLuaManager->addAction( - []() { LuaUi::Element::forEachMenuElement([](LuaUi::Element* e) { e->update(); }); }, - "Update all menu UI elements"); - } - else - { - LuaUi::Element::forEachGameElement([](LuaUi::Element* e) { e->mUpdate = true; }); - context.mLuaManager->addAction( - []() { LuaUi::Element::forEachGameElement([](LuaUi::Element* e) { e->update(); }); }, - "Update all game UI elements"); - } + + api["updateAll"] = [luaManager = context.mLuaManager, menu]() { + LuaUi::Element::forEach(menu, [](LuaUi::Element* e) { e->mUpdate = true; }); + luaManager->addAction([menu]() { LuaUi::Element::forEach(menu, [](LuaUi::Element* e) { e->update(); }); }, + "Update all menu UI elements"); }; api["_getMenuTransparency"] = []() -> float { return Settings::gui().mMenuTransparency; }; - auto uiLayer = context.mLua->sol().new_usertype("UiLayer"); - uiLayer["name"] = sol::property([](LuaUi::Layer& self) { return self.name(); }); - uiLayer["size"] = sol::property([](LuaUi::Layer& self) { return self.size(); }); - uiLayer[sol::meta_function::to_string] - = [](LuaUi::Layer& self) { return Misc::StringUtils::format("UiLayer(%s)", self.name()); }; - sol::table layersTable = context.mLua->newTable(); layersTable["indexOf"] = [](std::string_view name) -> sol::optional { size_t index = LuaUi::Layer::indexOf(name); @@ -247,7 +202,7 @@ namespace MWLua { "Center", LuaUi::Alignment::Center }, { "End", LuaUi::Alignment::End } })); api["registerSettingsPage"] = &LuaUi::registerSettingsPage; - api["removeSettingsPage"] = &LuaUi::registerSettingsPage; + api["removeSettingsPage"] = &LuaUi::removeSettingsPage; api["texture"] = [luaManager = context.mLuaManager](const sol::table& options) { LuaUi::TextureData data; @@ -325,8 +280,56 @@ namespace MWLua // TODO // api["_showMouseCursor"] = [](bool) {}; + return api; + } + + sol::table initUserInterfacePackage(const Context& context) + { + std::string_view menuCache = "openmw_ui_menu"; + std::string_view gameCache = "openmw_ui_game"; + std::string_view cacheKey = context.mIsMenu ? menuCache : gameCache; + { + sol::state_view& lua = context.mLua->sol(); + if (lua[cacheKey] != sol::nil) + return lua[cacheKey]; + } + + auto element = context.mLua->sol().new_usertype("UiElement"); + element[sol::meta_function::to_string] = [](const LuaUi::Element& element) { + std::stringstream res; + res << "UiElement"; + if (element.mLayer != "") + res << "[" << element.mLayer << "]"; + return res.str(); + }; + element["layout"] = sol::property([](const LuaUi::Element& element) { return element.mLayout; }, + [](LuaUi::Element& element, const sol::table& layout) { element.mLayout = layout; }); + element["update"] = [luaManager = context.mLuaManager](const std::shared_ptr& element) { + if (element->mDestroy || element->mUpdate) + return; + element->mUpdate = true; + luaManager->addAction([element] { wrapAction(element, [&] { element->update(); }); }, "Update UI"); + }; + element["destroy"] = [luaManager = context.mLuaManager](const std::shared_ptr& element) { + if (element->mDestroy) + return; + element->mDestroy = true; + luaManager->addAction( + [element] { wrapAction(element, [&] { LuaUi::Element::erase(element.get()); }); }, "Destroy UI"); + }; + + auto uiLayer = context.mLua->sol().new_usertype("UiLayer"); + uiLayer["name"] = sol::readonly_property([](LuaUi::Layer& self) { return self.name(); }); + uiLayer["size"] = sol::readonly_property([](LuaUi::Layer& self) { return self.size(); }); + uiLayer[sol::meta_function::to_string] + = [](LuaUi::Layer& self) { return Misc::StringUtils::format("UiLayer(%s)", self.name()); }; + + sol::table menuApi = registerUiApi(context, true); + sol::table gameApi = registerUiApi(context, false); + sol::state_view& lua = context.mLua->sol(); - lua["openmw_ui"] = LuaUtil::makeReadOnly(api); - return lua["openmw_ui"]; + lua[menuCache] = LuaUtil::makeReadOnly(menuApi); + lua[gameCache] = LuaUtil::makeReadOnly(gameApi); + return lua[cacheKey]; } } diff --git a/components/lua_ui/element.cpp b/components/lua_ui/element.cpp index 9d124d2a0e..da39cca1b8 100644 --- a/components/lua_ui/element.cpp +++ b/components/lua_ui/element.cpp @@ -240,8 +240,8 @@ namespace LuaUi } } - std::map> Element::sGameElements; std::map> Element::sMenuElements; + std::map> Element::sGameElements; Element::Element(sol::table layout) : mRoot(nullptr) @@ -252,18 +252,19 @@ namespace LuaUi { } - std::shared_ptr Element::makeGameElement(sol::table layout) + std::shared_ptr Element::make(sol::table layout, bool menu) { std::shared_ptr ptr(new Element(std::move(layout))); - sGameElements[ptr.get()] = ptr; + auto& container = menu ? sMenuElements : sGameElements; + container[ptr.get()] = ptr; return ptr; } - std::shared_ptr Element::makeMenuElement(sol::table layout) + void Element::erase(Element* element) { - std::shared_ptr ptr(new Element(std::move(layout))); - sMenuElements[ptr.get()] = ptr; - return ptr; + element->destroy(); + sMenuElements.erase(element); + sGameElements.erase(element); } void Element::create() @@ -311,7 +312,5 @@ namespace LuaUi mRoot = nullptr; mLayout = sol::make_object(mLayout.lua_state(), sol::nil); } - sGameElements.erase(this); - sMenuElements.erase(this); } } diff --git a/components/lua_ui/element.hpp b/components/lua_ui/element.hpp index 0446f448b6..4398a769df 100644 --- a/components/lua_ui/element.hpp +++ b/components/lua_ui/element.hpp @@ -7,21 +7,15 @@ namespace LuaUi { struct Element { - static std::shared_ptr makeGameElement(sol::table layout); - static std::shared_ptr makeMenuElement(sol::table layout); + static std::shared_ptr make(sol::table layout, bool menu); + static void erase(Element* element); template - static void forEachGameElement(Callback callback) + static void forEach(bool menu, Callback callback) { - for (auto& [e, _] : sGameElements) - callback(e); - } - - template - static void forEachMenuElement(Callback callback) - { - for (auto& [e, _] : sMenuElements) - callback(e); + auto& container = menu ? sMenuElements : sGameElements; + for (auto& [_, element] : container) + callback(element.get()); } WidgetExtension* mRoot; diff --git a/components/lua_ui/scriptsettings.hpp b/components/lua_ui/scriptsettings.hpp index ab68bde839..94ed065bbc 100644 --- a/components/lua_ui/scriptsettings.hpp +++ b/components/lua_ui/scriptsettings.hpp @@ -3,7 +3,6 @@ #include #include -#include namespace LuaUi { diff --git a/components/lua_ui/util.cpp b/components/lua_ui/util.cpp index fe47de3b1d..8dfda3d4cb 100644 --- a/components/lua_ui/util.cpp +++ b/components/lua_ui/util.cpp @@ -47,12 +47,12 @@ namespace LuaUi void clearGameInterface() { while (!Element::sGameElements.empty()) - Element::sGameElements.begin()->second->destroy(); + Element::erase(Element::sGameElements.begin()->second.get()); } void clearMenuInterface() { while (!Element::sMenuElements.empty()) - Element::sMenuElements.begin()->second->destroy(); + Element::erase(Element::sMenuElements.begin()->second.get()); } }