Added a new type ResourceVector which manages object lifetimes, and used it to remove a bit of memory management.

Sun, 05 Mar 2017 13:33:37 +0200

author
Teemu Piippo <teemu@hecknology.net>
date
Sun, 05 Mar 2017 13:33:37 +0200
changeset 1185
c2e0db52ea07
parent 1184
393babf1319d
child 1186
eae8b3bce545

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();
+}

mercurial