diff options
author | Thorbjørn Lindeijer <bjorn@lindeijer.nl> | 2025-02-25 17:46:32 +0100 |
---|---|---|
committer | Thorbjørn Lindeijer <bjorn@lindeijer.nl> | 2025-02-26 21:18:09 +0000 |
commit | 81a2f0829a9a0a0d524028fbff42273387078613 (patch) | |
tree | af78fed4c42f13d05250281414bba0d815c9d271 /src | |
parent | 471bd7e5ba449d0a5c7267e960801426248cfaa9 (diff) | |
download | mana-81a2f0829a9a0a0d524028fbff42273387078613.tar.gz mana-81a2f0829a9a0a0d524028fbff42273387078613.tar.bz2 mana-81a2f0829a9a0a0d524028fbff42273387078613.tar.xz mana-81a2f0829a9a0a0d524028fbff42273387078613.zip |
Plugged a few more memory leaks
* DebugWindow and SkillDialog were not deleting their tabs nor their tab
widgets.
* TabbedArea was not deleting its arrow buttons.
* Button was deleting its TextPopup on deletion of the last Button
instance, which was wrong because it was also being deleted by the
WindowContainer. Also removed some misplaced event forwarding to the
TextPopup.
TabbedArea is tricky because it does not automatically delete added tabs
or their widgets. Tab instances are only deleted when they were added by
name.
Issues found by Valgrind memory analyzer.
Diffstat (limited to 'src')
-rw-r--r-- | src/gui/debugwindow.cpp | 18 | ||||
-rw-r--r-- | src/gui/debugwindow.h | 11 | ||||
-rw-r--r-- | src/gui/skilldialog.cpp | 38 | ||||
-rw-r--r-- | src/gui/skilldialog.h | 4 | ||||
-rw-r--r-- | src/gui/widgets/button.cpp | 17 | ||||
-rw-r--r-- | src/gui/widgets/button.h | 1 | ||||
-rw-r--r-- | src/gui/widgets/tabbedarea.cpp | 8 | ||||
-rw-r--r-- | src/gui/widgets/tabbedarea.h | 3 |
8 files changed, 50 insertions, 50 deletions
diff --git a/src/gui/debugwindow.cpp b/src/gui/debugwindow.cpp index 3c514191..17020062 100644 --- a/src/gui/debugwindow.cpp +++ b/src/gui/debugwindow.cpp @@ -244,11 +244,15 @@ DebugWindow::DebugWindow() place(0, 0, tabs, 2, 2); loadWindowState(); - Tab *tabInfo = new Tab; - tabInfo->setCaption(_("Info")); - tabs->addTab(tabInfo, new DebugInfo); - - Tab *tabSwitches = new Tab; - tabSwitches->setCaption(_("Switches")); - tabs->addTab(tabSwitches, new DebugSwitches); + mInfoTab = std::make_unique<Tab>(); + mInfoTab->setCaption(_("Info")); + mInfoWidget = std::make_unique<DebugInfo>(); + tabs->addTab(mInfoTab.get(), mInfoWidget.get()); + + mSwitchesTab = std::make_unique<Tab>(); + mSwitchesTab->setCaption(_("Switches")); + mSwitchesWidget = std::make_unique<DebugSwitches>(); + tabs->addTab(mSwitchesTab.get(), mSwitchesWidget.get()); } + +DebugWindow::~DebugWindow() = default; diff --git a/src/gui/debugwindow.h b/src/gui/debugwindow.h index 63c0517e..807f0d0f 100644 --- a/src/gui/debugwindow.h +++ b/src/gui/debugwindow.h @@ -23,6 +23,10 @@ #include "gui/widgets/window.h" +#include <memory> + +class Tab; + /** * The debug window. * @@ -32,6 +36,13 @@ class DebugWindow : public Window { public: DebugWindow(); + ~DebugWindow() override; + + private: + std::unique_ptr<Tab> mInfoTab; + std::unique_ptr<Tab> mSwitchesTab; + std::unique_ptr<gcn::Widget> mInfoWidget; + std::unique_ptr<gcn::Widget> mSwitchesWidget; }; extern DebugWindow *debugWindow; diff --git a/src/gui/skilldialog.cpp b/src/gui/skilldialog.cpp index 0c223d80..217c3800 100644 --- a/src/gui/skilldialog.cpp +++ b/src/gui/skilldialog.cpp @@ -204,11 +204,11 @@ SkillDialog::SkillDialog(): setMinWidth(240); setupWindow->registerWindowForReset(this); - mTabs = new TabbedArea(); + mTabbedArea = new TabbedArea; mPointsLabel = new Label("0"); mIncreaseButton = new Button(_("Up"), "inc", this); - place(0, 0, mTabs, 5, 5); + place(0, 0, mTabbedArea, 5, 5); place(0, 5, mPointsLabel, 4); place(4, 5, mIncreaseButton); @@ -225,7 +225,7 @@ void SkillDialog::action(const gcn::ActionEvent &event) { if (event.getId() == "inc") { - auto *tab = static_cast<SkillTab*>(mTabs->getSelectedTab()); + auto *tab = static_cast<SkillTab*>(mTabbedArea->getSelectedTab()); if (SkillInfo *info = tab->getSelectedInfo()) Net::getPlayerHandler()->increaseSkill(info->id); } @@ -277,19 +277,10 @@ void SkillDialog::event(Event::Channel channel, const Event &event) void SkillDialog::clearSkills() { - // Fixes issues with removing tabs - if (mTabs->getSelectedTabIndex() != -1) - { - mTabs->setSelectedTab((unsigned int) 0); - - while (mTabs->getSelectedTabIndex() != -1) - { - gcn::Tab *tab = mTabs->getSelectedTab(); - mTabs->removeTabWithIndex(mTabs->getSelectedTabIndex()); - delete tab; - } - } + for (auto &tab : mTabs) + mTabbedArea->removeTab(tab.get()); + mTabs.clear(); mSkillModels.clear(); mSkills.clear(); } @@ -326,15 +317,16 @@ void SkillDialog::loadSkills() model->updateVisibilities(); auto listbox = new SkillListBox(model.get()); - auto scroll = new ScrollArea(listbox); + auto scroll = std::make_unique<ScrollArea>(listbox); scroll->setOpaque(false); scroll->setHorizontalScrollPolicy(ScrollArea::SHOW_NEVER); scroll->setVerticalScrollPolicy(ScrollArea::SHOW_ALWAYS); - auto *tab = new SkillTab("Skills", listbox); - - mTabs->addTab(tab, scroll); + auto tab = std::make_unique<SkillTab>("Skills", listbox); + mTabbedArea->addTab(tab.get(), scroll.get()); + mTabs.push_back(std::move(tab)); + mTabWidgets.push_back(std::move(scroll)); mSkillModels.push_back(std::move(model)); update(); @@ -378,15 +370,17 @@ void SkillDialog::loadSkills() model->updateVisibilities(); auto listbox = new SkillListBox(model.get()); - auto scroll = new ScrollArea(listbox); + auto scroll = std::make_unique<ScrollArea>(listbox); scroll->setOpaque(false); scroll->setHorizontalScrollPolicy(ScrollArea::SHOW_NEVER); scroll->setVerticalScrollPolicy(ScrollArea::SHOW_ALWAYS); - auto tab = new SkillTab(setName, listbox); + auto tab = std::make_unique<SkillTab>(setName, listbox); - mTabs->addTab(tab, scroll); + mTabbedArea->addTab(tab.get(), scroll.get()); + mTabs.push_back(std::move(tab)); + mTabWidgets.push_back(std::move(scroll)); mSkillModels.push_back(std::move(model)); } } diff --git a/src/gui/skilldialog.h b/src/gui/skilldialog.h index c69e3d9b..83dc8dd2 100644 --- a/src/gui/skilldialog.h +++ b/src/gui/skilldialog.h @@ -77,8 +77,10 @@ class SkillDialog : public Window, public gcn::ActionListener, public EventListe private: std::vector<std::unique_ptr<SkillModel>> mSkillModels; + std::vector<std::unique_ptr<Tab>> mTabs; + std::vector<std::unique_ptr<gcn::Widget>> mTabWidgets; std::map<int, SkillInfo*> mSkills; - TabbedArea *mTabs; + TabbedArea *mTabbedArea; Label *mPointsLabel; Button *mIncreaseButton; }; diff --git a/src/gui/widgets/button.cpp b/src/gui/widgets/button.cpp index ce7a856f..58630ee8 100644 --- a/src/gui/widgets/button.cpp +++ b/src/gui/widgets/button.cpp @@ -150,9 +150,10 @@ void Button::init() } updateAlpha(); - // Load the popup + // Create the tooltip popup. It is shared by all buttons and will get + // deleted by the WindowContainer. if (!mTextPopup) - mTextPopup = new TextPopup(); + mTextPopup = new TextPopup; } mInstances++; } @@ -169,10 +170,6 @@ Button::~Button() dtor<Image*>()); } delete[] mButton; - - // Remove the popup - delete mTextPopup; - mTextPopup = nullptr; } } @@ -293,16 +290,9 @@ void Button::setCaption(const std::string& caption) adjustSize(); } -void Button::logic() -{ - gcn::Button::logic(); - mTextPopup->logic(); -} - void Button::mouseMoved(gcn::MouseEvent &event) { gcn::Button::mouseMoved(event); - mTextPopup->mouseMoved(event); int x = event.getX(); int y = event.getY(); @@ -326,7 +316,6 @@ void Button::mouseMoved(gcn::MouseEvent &event) void Button::mouseExited(gcn::MouseEvent &event) { gcn::Button::mouseExited(event); - mTextPopup->mouseExited(event); mTextPopup->setVisible(false); } diff --git a/src/gui/widgets/button.h b/src/gui/widgets/button.h index 1502dc43..bac3f914 100644 --- a/src/gui/widgets/button.h +++ b/src/gui/widgets/button.h @@ -84,7 +84,6 @@ class Button : public gcn::Button void setButtonPopupText(const std::string &text) { mPopupText = text; } - void logic() override; void mouseMoved(gcn::MouseEvent &event) override; void mouseExited(gcn::MouseEvent &event) override; diff --git a/src/gui/widgets/tabbedarea.cpp b/src/gui/widgets/tabbedarea.cpp index af0c11cb..d9ff9566 100644 --- a/src/gui/widgets/tabbedarea.cpp +++ b/src/gui/widgets/tabbedarea.cpp @@ -30,13 +30,13 @@ TabbedArea::TabbedArea() mWidgetContainer->setOpaque(false); addWidgetListener(this); - mArrowButton[0] = new Button(std::string(), "shift_left", this); - mArrowButton[1] = new Button(std::string(), "shift_right", this); + mArrowButton[0] = std::make_unique<Button>(std::string(), "shift_left", this); + mArrowButton[1] = std::make_unique<Button>(std::string(), "shift_right", this); mArrowButton[0]->setButtonIcon("tab_arrows_left.png"); mArrowButton[1]->setButtonIcon("tab_arrows_right.png"); - add(mArrowButton[0]); - add(mArrowButton[1]); + add(mArrowButton[0].get()); + add(mArrowButton[1].get()); widgetResized(nullptr); } diff --git a/src/gui/widgets/tabbedarea.h b/src/gui/widgets/tabbedarea.h index 4b927ee2..c0566faa 100644 --- a/src/gui/widgets/tabbedarea.h +++ b/src/gui/widgets/tabbedarea.h @@ -28,6 +28,7 @@ #include "gui/widgets/button.h" +#include <memory> #include <string> class Tab; @@ -114,7 +115,7 @@ class TabbedArea : public gcn::TabbedArea, public gcn::WidgetListener private: /** The tab arrows */ - Button *mArrowButton[2]; + std::unique_ptr<Button> mArrowButton[2]; /** Check whether the arrow should be clickable */ void updateArrowEnableState(); |