From 5425d344ba53dc2d616a5c8534612e85af03cb24 Mon Sep 17 00:00:00 2001 From: Eduardo Bart Date: Mon, 9 Apr 2012 17:52:39 -0300 Subject: [PATCH] optimize widget destruction --- modules/core_lib/ui/radiogroup.lua | 12 ++++++-- modules/game_npctrade/npctrade.lua | 7 +++-- src/framework/ui/uigridlayout.cpp | 3 ++ src/framework/ui/uilayout.cpp | 10 ++++--- src/framework/ui/uiwidget.cpp | 45 +++++++++++++++++++++--------- src/framework/ui/uiwidget.h | 1 + 6 files changed, 57 insertions(+), 21 deletions(-) diff --git a/modules/core_lib/ui/radiogroup.lua b/modules/core_lib/ui/radiogroup.lua index d4c0c833..ffc7d76f 100644 --- a/modules/core_lib/ui/radiogroup.lua +++ b/modules/core_lib/ui/radiogroup.lua @@ -7,9 +7,10 @@ function RadioGroup.create() end function RadioGroup:destroy() - while #self.widgets ~= 0 do - self:removeWidget(self.widgets[1]) + for k,widget in pairs(self.widgets) do + widget.onMousePress = nil end + self.widgets = {} end function RadioGroup:addWidget(widget) @@ -25,6 +26,13 @@ function RadioGroup:removeWidget(widget) table.removevalue(self.widgets, widget) end +function RadioGroup:destroy() + for k,widget in pairs(self.widgets) do + widget.onMousePress = nil + end + self.widgets = {} +end + function RadioGroup:selectWidget(selectedWidget) if selectedWidget == self.selectedWidget then return end diff --git a/modules/game_npctrade/npctrade.lua b/modules/game_npctrade/npctrade.lua index e4327695..2d1c2fd2 100644 --- a/modules/game_npctrade/npctrade.lua +++ b/modules/game_npctrade/npctrade.lua @@ -59,7 +59,7 @@ function NPCTrade.init() end function NPCTrade.terminate() - radioTabs:destroy() + --radioTabs:destroy() radioTabs = nil npcWindow:destroy() npcWindow = nil @@ -229,7 +229,10 @@ function NPCTrade.createItemsOnPanel() offerSelected = nil itemsPanel:destroyChildren() - + + if radioItems then + radioItems:destroy() + end radioItems = RadioGroup.create() for i, v in pairs(cacheItems) do diff --git a/src/framework/ui/uigridlayout.cpp b/src/framework/ui/uigridlayout.cpp index f16f75d4..af572aa0 100644 --- a/src/framework/ui/uigridlayout.cpp +++ b/src/framework/ui/uigridlayout.cpp @@ -74,6 +74,9 @@ bool UIGridLayout::internalUpdate() { bool changed = false; UIWidgetPtr parentWidget = getParentWidget(); + if(!parentWidget) + return false; + UIWidgetList widgets = parentWidget->getChildren(); Rect clippingRect = parentWidget->getClippingRect(); diff --git a/src/framework/ui/uilayout.cpp b/src/framework/ui/uilayout.cpp index 2ce98683..2c700740 100644 --- a/src/framework/ui/uilayout.cpp +++ b/src/framework/ui/uilayout.cpp @@ -27,6 +27,7 @@ void UILayout::update() { + //logTraceCounter(); if(m_updateDisabled) return; @@ -35,12 +36,13 @@ void UILayout::update() return; } + UIWidgetPtr parentWidget = getParentWidget(); + if(!parentWidget || parentWidget->isDestroyed()) + return; + m_updating = true; internalUpdate(); - if(UIWidgetPtr parentWidget = getParentWidget()) { - if(!parentWidget->isDestroyed()) - parentWidget->onLayoutUpdate(); - } + parentWidget->onLayoutUpdate(); m_updating = false; } diff --git a/src/framework/ui/uiwidget.cpp b/src/framework/ui/uiwidget.cpp index 91f50bbc..c49ad7fe 100644 --- a/src/framework/ui/uiwidget.cpp +++ b/src/framework/ui/uiwidget.cpp @@ -659,21 +659,19 @@ void UIWidget::bindRectToParent() setRect(boundRect); } -void UIWidget::destroy() +void UIWidget::internalDestroy() { - if(m_destroyed) - logWarning("attempt to destroy widget '", m_id, "' two times"); - m_destroyed = true; - setVisible(false); - setEnabled(false); - - // remove itself from parent - if(UIWidgetPtr parent = getParent()) - parent->removeChild(asUIWidget()); - - destroyChildren(); + m_visible = false; + m_enabled = false; + m_parent.reset(); m_focusedChild = nullptr; + m_layout = nullptr; + m_lockedChildren.clear(); + + for(const UIWidgetPtr& child : m_children) + child->internalDestroy(); + m_children.clear(); callLuaField("onDestroy"); @@ -682,10 +680,31 @@ void UIWidget::destroy() g_ui.onWidgetDestroy(asUIWidget()); } +void UIWidget::destroy() +{ + if(m_destroyed) + logWarning("attempt to destroy widget '", m_id, "' two times"); + + // hold itself reference + UIWidgetPtr self = asUIWidget(); + m_destroyed = true; + + // remove itself from parent + if(UIWidgetPtr parent = getParent()) + parent->removeChild(self); + internalDestroy(); +} + void UIWidget::destroyChildren() { + UILayoutPtr layout = getLayout(); + if(layout) + layout->disableUpdates(); + while(!m_children.empty()) - getFirstChild()->destroy(); + m_children[0]->destroy(); + + layout->enableUpdates(); } void UIWidget::setId(const std::string& id) diff --git a/src/framework/ui/uiwidget.h b/src/framework/ui/uiwidget.h index 3fcaaff1..30d54352 100644 --- a/src/framework/ui/uiwidget.h +++ b/src/framework/ui/uiwidget.h @@ -164,6 +164,7 @@ protected: bool hasState(Fw::WidgetState state); private: + void internalDestroy(); void updateState(Fw::WidgetState state); void updateStates(); void updateChildrenIndexStates();