Attach elements to each other, safely destroy

macos_ci_fix
uramer 1 year ago
parent f037dc814d
commit 4a4cef5709

@ -18,7 +18,7 @@ namespace LuaUi
{
mContainer = MyGUI::Gui::getInstancePtr()->createWidget<LuaContainer>(
"", MyGUI::IntCoord(), MyGUI::Align::Default, "", "");
mContainer->initialize(luaState, mContainer);
mContainer->initialize(luaState, mContainer, false);
mContainer->onCoordChange([this](WidgetExtension* ext, MyGUI::IntCoord coord) { setSize(coord.size()); });
mContainer->widget()->attachToWidget(this);
}

@ -43,17 +43,17 @@ namespace LuaUi
}
void insert(size_t index, const sol::table& table) { callMethod("insert", toLua(index), table); }
sol::table at(size_t index) const
sol::object at(size_t index) const
{
if (index < size())
return mTable.get<sol::table>(toLua(index));
return mTable.get<sol::object>(toLua(index));
else
throw std::range_error("Invalid Content index");
}
sol::table at(std::string_view name) const
sol::object at(std::string_view name) const
{
if (indexOf(name).has_value())
return mTable.get<sol::table>(name);
return mTable.get<sol::object>(name);
else
throw std::range_error("Invalid Content key");
}

@ -49,6 +49,36 @@ namespace LuaUi
MyGUI::Gui::getInstancePtr()->destroyWidget(ext->widget());
}
void destroyChild(LuaUi::WidgetExtension* ext)
{
if (!ext->isRoot())
destroyWidget(ext);
}
void detachElements(LuaUi::WidgetExtension* ext)
{
for (auto* child : ext->children())
{
if (child->isRoot())
child->widget()->detachFromWidget();
else
detachElements(child);
}
for (auto* child : ext->templateChildren())
{
if (child->isRoot())
child->widget()->detachFromWidget();
else
detachElements(child);
}
}
void destroyRoot(LuaUi::WidgetExtension* ext)
{
detachElements(ext);
destroyWidget(ext);
}
WidgetExtension* createWidget(const sol::table& layout, uint64_t depth);
void updateWidget(WidgetExtension* ext, const sol::table& layout, uint64_t depth);
@ -60,7 +90,7 @@ namespace LuaUi
if (contentObj == sol::nil)
{
for (WidgetExtension* w : children)
destroyWidget(w);
destroyChild(w);
return result;
}
ContentView content(LuaUtil::cast<sol::table>(contentObj));
@ -69,22 +99,46 @@ namespace LuaUi
for (size_t i = 0; i < minSize; i++)
{
WidgetExtension* ext = children[i];
sol::table newLayout = content.at(i);
if (ext->widget()->getTypeName() == widgetType(newLayout))
sol::object child = content.at(i);
if (child.is<Element>())
{
updateWidget(ext, newLayout, depth);
std::shared_ptr<Element> element = child.as<std::shared_ptr<Element>>();
if (ext != element->mRoot)
destroyChild(ext);
result[i] = element->mRoot;
element->mRoot->updateCoord();
}
else
{
destroyWidget(ext);
ext = createWidget(newLayout, depth);
sol::table newLayout = child.as<sol::table>();
if (ext->widget()->getTypeName() == widgetType(newLayout))
{
updateWidget(ext, newLayout, depth);
}
else
{
destroyChild(ext);
ext = createWidget(newLayout, depth);
}
result[i] = ext;
}
result[i] = ext;
}
for (size_t i = minSize; i < children.size(); i++)
destroyWidget(children[i]);
destroyChild(children[i]);
for (size_t i = minSize; i < content.size(); i++)
result[i] = createWidget(content.at(i), depth);
{
sol::object child = content.at(i);
if (child.is<Element>())
{
std::shared_ptr<Element> element = child.as<std::shared_ptr<Element>>();
result[i] = element->mRoot;
element->mRoot->updateCoord();
}
else
{
result[i] = createWidget(child.as<sol::table>(), depth);
}
}
return result;
}
@ -130,7 +184,7 @@ namespace LuaUi
WidgetExtension* ext = dynamic_cast<WidgetExtension*>(widget);
if (!ext)
throw std::runtime_error("Invalid widget!");
ext->initialize(layout.lua_state(), widget);
ext->initialize(layout.lua_state(), widget, depth == 0);
updateWidget(ext, layout, depth);
return ext;
@ -201,7 +255,7 @@ namespace LuaUi
{
if (mRoot->widget()->getTypeName() != widgetType(layout()))
{
destroyWidget(mRoot);
destroyRoot(mRoot);
mRoot = createWidget(layout(), 0);
}
else
@ -218,7 +272,7 @@ namespace LuaUi
{
if (mRoot)
{
destroyWidget(mRoot);
destroyRoot(mRoot);
mRoot = nullptr;
mLayout = sol::make_object(mLayout.lua_state(), sol::nil);
}

@ -18,13 +18,15 @@ namespace LuaUi
, mExternal(sol::nil)
, mParent(nullptr)
, mTemplateChild(false)
, mElementRoot(false)
{
}
void WidgetExtension::initialize(lua_State* lua, MyGUI::Widget* self)
void WidgetExtension::initialize(lua_State* lua, MyGUI::Widget* self, bool isRoot)
{
mLua = lua;
mWidget = self;
mElementRoot = isRoot;
initialize();
updateTemplate();
}

@ -26,13 +26,15 @@ namespace LuaUi
virtual ~WidgetExtension() = default;
// must be called after creating the underlying MyGUI::Widget
void initialize(lua_State* lua, MyGUI::Widget* self);
void initialize(lua_State* lua, MyGUI::Widget* self, bool isRoot);
// must be called after before destroying the underlying MyGUI::Widget
virtual void deinitialize();
MyGUI::Widget* widget() const { return mWidget; }
WidgetExtension* slot() const { return mSlot; }
bool isRoot() const { return mElementRoot; }
void reset();
const std::vector<WidgetExtension*>& children() { return mChildren; }
@ -152,6 +154,7 @@ namespace LuaUi
sol::object mExternal;
WidgetExtension* mParent;
bool mTemplateChild;
bool mElementRoot;
void attach(WidgetExtension* ext);
void attachTemplate(WidgetExtension* ext);

Loading…
Cancel
Save