Sun, 05 Mar 2017 13:33:37 +0200
Added a new type ResourceVector which manages object lifetimes, and used it to remove a bit of memory management.
CMakeLists.txt | file | annotate | diff | comparison | revisions | |
src/mainwindow.cpp | file | annotate | diff | comparison | revisions | |
src/mainwindow.h | file | annotate | diff | comparison | revisions | |
src/types/resourcevector.h | file | annotate | diff | comparison | revisions |
--- a/CMakeLists.txt Sun Mar 05 01:57:56 2017 +0200 +++ b/CMakeLists.txt Sun Mar 05 13:33:37 2017 +0200 @@ -151,6 +151,7 @@ src/toolsets/toolset.h src/toolsets/viewtoolset.h src/types/matrix.h + src/types/resourcevector.h ) set (LDFORGE_FORMS
--- a/src/mainwindow.cpp Sun Mar 05 01:57:56 2017 +0200 +++ b/src/mainwindow.cpp Sun Mar 05 13:33:37 2017 +0200 @@ -215,22 +215,17 @@ // void MainWindow::updateRecentFilesMenu() { - // First, clear any items in the recent files menu - for (QAction* recent : m_recentFiles) - delete recent; - m_recentFiles.clear(); - QAction* first = nullptr; + QAction* previous = nullptr; for (const QVariant& it : m_config.recentFiles()) { QString file = it.toString(); - QAction* recent = new QAction (getIcon ("open-recent"), file, this); - connect (recent, SIGNAL (triggered()), this, SLOT (recentFileClicked())); - ui.menuOpenRecent->insertAction (first, recent); - m_recentFiles << recent; - first = recent; + QAction* recentFileAction = m_recentFiles.append(getIcon("open-recent"), file, this); + connect(recentFileAction, SIGNAL(triggered()), this, SLOT(recentFileClicked())); + ui.menuOpenRecent->insertAction(previous, recentFileAction); + previous = recentFileAction; } }
--- a/src/mainwindow.h Sun Mar 05 01:57:56 2017 +0200 +++ b/src/mainwindow.h Sun Mar 05 13:33:37 2017 +0200 @@ -27,6 +27,7 @@ #include "linetypes/modelobject.h" #include "colors.h" #include "doublemap.h" +#include "types/resourcevector.h" class MessageManager; class QToolButton; @@ -156,7 +157,7 @@ QVector<LDObject*> m_sel; QVector<ColorToolbarItem> m_quickColors; QList<QToolButton*> m_colorButtons; - QList<QAction*> m_recentFiles; + ResourceVector<QAction> m_recentFiles; class Ui_MainWindow& ui; QTabBar* m_tabs; bool m_updatingTabs;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/types/resourcevector.h Sun Mar 05 13:33:37 2017 +0200 @@ -0,0 +1,153 @@ +/* + * LDForge: LDraw parts authoring CAD + * Copyright (C) 2013 - 2017 Teemu Piippo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <QVector> + +/* + * A vector that allocates elements on the heap and manages their lifetime. + */ +template<typename T> +class ResourceVector +{ +public: + ~ResourceVector(); + void append(T) = delete; + template<typename TT = T, typename... Args> + T* append(Args&&... args); + T** const begin() const; + T** const end() const; + template<typename TT = T, typename... Args> + T* insert(int position, Args&&... args); + void clear(); + void removeAt(int position); + T* operator[](int position) const; + int size() const; + +private: + QVector<T*> _data; +}; + +template<typename T> +int countof(const ResourceVector<T>& vector); + +/* + * Frees the resources when the vector is deleted. + */ +template<typename T> +ResourceVector<T>::~ResourceVector() +{ + clear(); +} + +/* + * Creates a new resource and adds it to the end of this vector. + */ +template<typename T> +template<typename TT, typename... Args> +T* ResourceVector<T>::append(Args&&... args) +{ + _data.append(new TT {args...}); + return _data[size() - 1]; +} + +/* + * Returns an iterator to the beginning of this vector. + */ +template<typename T> +T** const ResourceVector<T>::begin() const +{ + return _data.cbegin(); +} + +/* + * Returns an iterator to the end of this vector. + */ +template<typename T> +T** const ResourceVector<T>::end() const +{ + return _data.cend(); +} + +/* + * Creates a new resource and inserts it to the specified position in this vector. + */ +template<typename T> +template<typename TT, typename... Args> +T* ResourceVector<T>::insert(int position, Args&&... args) +{ + _data.insert(position, new TT {args...}); +} + +/* + * Deletes all resources in this vector. + */ +template<typename T> +void ResourceVector<T>::clear() +{ + for (T* element : _data) + delete element; + + _data.clear(); +} + +/* + * Removes the resource at the provided position. Throws an exception if the index is out of range. + */ +template<typename T> +void ResourceVector<T>::removeAt(int position) +{ + if (position < _data.size()) + { + delete _data[position]; + _data.removeAt(position); + } + else + { + throw std::domain_error {"index out of range"}; + } +} + +/* + * Returns the resource at the provided position. Throws an exception if the index is out of range. + */ +template<typename T> +T* ResourceVector<T>::operator[](int position) const +{ + if (position < _data.size()) + return _data[position]; + else + throw std::domain_error {"index out of range"}; +} + +/* + * Returns the amount of resources in this vector. + */ +template<typename T> +int ResourceVector<T>::size() const +{ + return _data.size(); +} + +/* + * countof() overload for resource vectors. Returns the amount of resources in the given vector. + */ +template<typename T> +int countof(const ResourceVector<T>& vector) +{ + return vector.size(); +}