1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-02-28 12:40:06 +00:00

Dispose Lua UI elements correctly

This commit is contained in:
uramer 2022-01-18 08:12:56 +00:00 committed by Petr Mikheev
parent c07fb75bf7
commit cc528d2e08
12 changed files with 59 additions and 49 deletions

View File

@ -53,7 +53,7 @@
#include <components/misc/resourcehelpers.hpp> #include <components/misc/resourcehelpers.hpp>
#include <components/misc/frameratelimiter.hpp> #include <components/misc/frameratelimiter.hpp>
#include <components/lua_ui/widgetlist.hpp> #include <components/lua_ui/util.hpp>
#include "../mwbase/inputmanager.hpp" #include "../mwbase/inputmanager.hpp"
#include "../mwbase/statemanager.hpp" #include "../mwbase/statemanager.hpp"
@ -510,6 +510,8 @@ namespace MWGui
{ {
try try
{ {
LuaUi::clearUserInterface();
mStatsWatcher.reset(); mStatsWatcher.reset();
MyGUI::LanguageManager::getInstance().eventRequestTag.clear(); MyGUI::LanguageManager::getInstance().eventRequestTag.clear();

View File

@ -12,6 +12,8 @@
#include <components/lua/utilpackage.hpp> #include <components/lua/utilpackage.hpp>
#include <components/lua_ui/util.hpp>
#include "../mwbase/windowmanager.hpp" #include "../mwbase/windowmanager.hpp"
#include "../mwworld/class.hpp" #include "../mwworld/class.hpp"
@ -237,6 +239,7 @@ namespace MWLua
void LuaManager::clear() void LuaManager::clear()
{ {
LuaUi::clearUserInterface();
mActiveLocalScripts.clear(); mActiveLocalScripts.clear();
mLocalEvents.clear(); mLocalEvents.clear();
mGlobalEvents.clear(); mGlobalEvents.clear();
@ -254,7 +257,6 @@ namespace MWLua
mPlayer.getRefData().setLuaScripts(nullptr); mPlayer.getRefData().setLuaScripts(nullptr);
mPlayer = MWWorld::Ptr(); mPlayer = MWWorld::Ptr();
} }
clearUserInterface();
mGlobalStorage.clearTemporary(); mGlobalStorage.clearTemporary();
mPlayerStorage.clearTemporary(); mPlayerStorage.clearTemporary();
} }
@ -454,6 +456,8 @@ namespace MWLua
void LuaManager::reloadAllScripts() void LuaManager::reloadAllScripts()
{ {
Log(Debug::Info) << "Reload Lua"; Log(Debug::Info) << "Reload Lua";
LuaUi::clearUserInterface();
mLua.dropScriptCache(); mLua.dropScriptCache();
initConfiguration(); initConfiguration();
@ -470,7 +474,6 @@ namespace MWLua
continue; continue;
ESM::LuaScripts data; ESM::LuaScripts data;
scripts->save(data); scripts->save(data);
clearUserInterface();
scripts->load(data); scripts->load(data);
} }
for (LocalScripts* scripts : mActiveLocalScripts) for (LocalScripts* scripts : mActiveLocalScripts)

View File

@ -1,4 +1,4 @@
#include <components/lua_ui/widgetlist.hpp> #include <components/lua_ui/util.hpp>
#include <components/lua_ui/element.hpp> #include <components/lua_ui/element.hpp>
#include <components/lua_ui/layers.hpp> #include <components/lua_ui/layers.hpp>
#include <components/lua_ui/content.hpp> #include <components/lua_ui/content.hpp>
@ -11,8 +11,6 @@ namespace MWLua
{ {
namespace namespace
{ {
std::set<LuaUi::Element*> allElements;
class UiAction final : public Action class UiAction final : public Action
{ {
public: public:
@ -189,7 +187,6 @@ namespace MWLua
{ {
if (element->mDestroy) if (element->mDestroy)
return; return;
allElements.erase(element.get());
element->mDestroy = true; element->mDestroy = true;
context.mLuaManager->addAction(std::make_unique<UiAction>(UiAction::DESTROY, element, context.mLua)); context.mLuaManager->addAction(std::make_unique<UiAction>(UiAction::DESTROY, element, context.mLua));
}; };
@ -205,8 +202,7 @@ namespace MWLua
}; };
api["create"] = [context](const sol::table& layout) api["create"] = [context](const sol::table& layout)
{ {
auto element = std::make_shared<LuaUi::Element>(layout); auto element = LuaUi::Element::make(layout);
allElements.emplace(element.get());
context.mLuaManager->addAction(std::make_unique<UiAction>(UiAction::CREATE, element, context.mLua)); context.mLuaManager->addAction(std::make_unique<UiAction>(UiAction::CREATE, element, context.mLua));
return element; return element;
}; };
@ -244,11 +240,4 @@ namespace MWLua
return LuaUtil::makeReadOnly(api); return LuaUtil::makeReadOnly(api);
} }
void clearUserInterface()
{
for (auto element : allElements)
element->destroy();
allElements.clear();
}
} }

View File

@ -162,7 +162,7 @@ add_component_dir (queries
) )
add_component_dir (lua_ui add_component_dir (lua_ui
widget widgetlist element layers content widget element util layers content
text textedit window text textedit window
) )

View File

@ -3,11 +3,10 @@
#include <MyGUI_Gui.h> #include <MyGUI_Gui.h>
#include "content.hpp" #include "content.hpp"
#include "widgetlist.hpp" #include "util.hpp"
namespace LuaUi namespace LuaUi
{ {
std::string widgetType(const sol::table& layout) std::string widgetType(const sol::table& layout)
{ {
return layout.get_or("type", std::string("LuaWidget")); return layout.get_or("type", std::string("LuaWidget"));
@ -70,7 +69,7 @@ namespace LuaUi
if (!ext) if (!ext)
throw std::runtime_error("Invalid widget!"); throw std::runtime_error("Invalid widget!");
ext->create(layout.lua_state(), widget); ext->initialize(layout.lua_state(), widget);
if (parent != nullptr) if (parent != nullptr)
widget->attachToWidget(parent->widget()); widget->attachToWidget(parent->widget());
@ -87,7 +86,7 @@ namespace LuaUi
void destroyWidget(LuaUi::WidgetExtension* ext) void destroyWidget(LuaUi::WidgetExtension* ext)
{ {
ext->destroy(); ext->deinitialize();
MyGUI::Gui::getInstancePtr()->destroyWidget(ext->widget()); MyGUI::Gui::getInstancePtr()->destroyWidget(ext->widget());
} }
@ -136,6 +135,23 @@ namespace LuaUi
} }
} }
std::map<Element*, std::shared_ptr<Element>> Element::sAllElements;
Element::Element(sol::table layout)
: mRoot{ nullptr }
, mLayout{ std::move(layout) }
, mUpdate{ false }
, mDestroy{ false }
{}
std::shared_ptr<Element> Element::make(sol::table layout)
{
std::shared_ptr<Element> ptr(new Element(std::move(layout)));
sAllElements[ptr.get()] = ptr;
return ptr;
}
void Element::create() void Element::create()
{ {
assert(!mRoot); assert(!mRoot);
@ -161,5 +177,6 @@ namespace LuaUi
if (mRoot) if (mRoot)
destroyWidget(mRoot); destroyWidget(mRoot);
mRoot = nullptr; mRoot = nullptr;
sAllElements.erase(this);
} }
} }

View File

@ -7,13 +7,7 @@ namespace LuaUi
{ {
struct Element struct Element
{ {
Element(sol::table layout) static std::shared_ptr<Element> make(sol::table layout);
: mRoot{ nullptr }
, mLayout{ layout }
, mUpdate{ false }
, mDestroy{ false }
{
}
LuaUi::WidgetExtension* mRoot; LuaUi::WidgetExtension* mRoot;
sol::table mLayout; sol::table mLayout;
@ -25,6 +19,12 @@ namespace LuaUi
void update(); void update();
void destroy(); void destroy();
friend void clearUserInterface();
private:
Element(sol::table layout);
static std::map<Element*, std::shared_ptr<Element>> sAllElements;
}; };
} }

View File

@ -7,11 +7,6 @@ namespace LuaUi
: mAutoSized(true) : mAutoSized(true)
{} {}
void LuaText::initialize()
{
WidgetExtension::initialize();
}
void LuaText::setProperties(sol::object props) void LuaText::setProperties(sol::object props)
{ {
setCaption(parseProperty(props, "caption", std::string())); setCaption(parseProperty(props, "caption", std::string()));

View File

@ -13,7 +13,6 @@ namespace LuaUi
public: public:
LuaText(); LuaText();
virtual void initialize() override;
virtual void setProperties(sol::object) override; virtual void setProperties(sol::object) override;
private: private:

View File

@ -1,4 +1,4 @@
#include "widgetlist.hpp" #include "util.hpp"
#include <MyGUI_FactoryManager.h> #include <MyGUI_FactoryManager.h>
@ -7,6 +7,8 @@
#include "textedit.hpp" #include "textedit.hpp"
#include "window.hpp" #include "window.hpp"
#include "element.hpp"
namespace LuaUi namespace LuaUi
{ {
@ -28,4 +30,10 @@ namespace LuaUi
}; };
return types; return types;
} }
void clearUserInterface()
{
while (!Element::sAllElements.empty())
Element::sAllElements.begin()->second->destroy();
}
} }

View File

@ -9,6 +9,8 @@ namespace LuaUi
void registerAllWidgets(); void registerAllWidgets();
const std::unordered_map<std::string, std::string>& widgetTypeToName(); const std::unordered_map<std::string, std::string>& widgetTypeToName();
void clearUserInterface();
} }
#endif // OPENMW_LUAUI_WIDGETLIST #endif // OPENMW_LUAUI_WIDGETLIST

View File

@ -26,7 +26,7 @@ namespace LuaUi
it->second(argument, mLayout); it->second(argument, mLayout);
} }
void WidgetExtension::create(lua_State* lua, MyGUI::Widget* self) void WidgetExtension::initialize(lua_State* lua, MyGUI::Widget* self)
{ {
mLua = lua; mLua = lua;
mWidget = self; mWidget = self;
@ -54,17 +54,9 @@ namespace LuaUi
mWidget->eventKeyLostFocus += MyGUI::newDelegate(this, &WidgetExtension::focusLoss); mWidget->eventKeyLostFocus += MyGUI::newDelegate(this, &WidgetExtension::focusLoss);
} }
void WidgetExtension::destroy()
{
clearCallbacks();
deinitialize();
for (WidgetExtension* child : mContent)
child->destroy();
}
void WidgetExtension::deinitialize() void WidgetExtension::deinitialize()
{ {
clearCallbacks();
mWidget->eventKeyButtonPressed.clear(); mWidget->eventKeyButtonPressed.clear();
mWidget->eventKeyButtonReleased.clear(); mWidget->eventKeyButtonReleased.clear();
mWidget->eventMouseButtonClick.clear(); mWidget->eventMouseButtonClick.clear();
@ -78,6 +70,9 @@ namespace LuaUi
mWidget->eventMouseLostFocus.clear(); mWidget->eventMouseLostFocus.clear();
mWidget->eventKeySetFocus.clear(); mWidget->eventKeySetFocus.clear();
mWidget->eventKeyLostFocus.clear(); mWidget->eventKeyLostFocus.clear();
for (WidgetExtension* child : mContent)
child->deinitialize();
} }
sol::table WidgetExtension::makeTable() const sol::table WidgetExtension::makeTable() const

View File

@ -22,9 +22,9 @@ namespace LuaUi
public: public:
WidgetExtension(); WidgetExtension();
// must be called after creating the underlying MyGUI::Widget // must be called after creating the underlying MyGUI::Widget
void create(lua_State* lua, MyGUI::Widget* self); void initialize(lua_State* lua, MyGUI::Widget* self);
// must be called after before destroying the underlying MyGUI::Widget // must be called after before destroying the underlying MyGUI::Widget
void destroy(); virtual void deinitialize();
void addChild(WidgetExtension* ext); void addChild(WidgetExtension* ext);
WidgetExtension* childAt(size_t index) const; WidgetExtension* childAt(size_t index) const;
@ -46,11 +46,11 @@ namespace LuaUi
void setLayout(const sol::table& layout) { mLayout = layout; } void setLayout(const sol::table& layout) { mLayout = layout; }
protected: protected:
virtual void initialize();
sol::table makeTable() const; sol::table makeTable() const;
sol::object keyEvent(MyGUI::KeyCode) const; sol::object keyEvent(MyGUI::KeyCode) const;
sol::object mouseEvent(int left, int top, MyGUI::MouseButton button) const; sol::object mouseEvent(int left, int top, MyGUI::MouseButton button) const;
virtual void initialize();
virtual void deinitialize();
virtual MyGUI::IntSize calculateSize(); virtual MyGUI::IntSize calculateSize();
virtual MyGUI::IntPoint calculatePosition(const MyGUI::IntSize& size); virtual MyGUI::IntPoint calculatePosition(const MyGUI::IntSize& size);
MyGUI::IntCoord calculateCoord(); MyGUI::IntCoord calculateCoord();