Replace LDIterate function with LDObjectIterator class

Sun, 30 Aug 2015 03:04:39 +0300

author
Teemu Piippo <crimsondusk64@gmail.com>
date
Sun, 30 Aug 2015 03:04:39 +0300
changeset 956
2af18ba2665f
parent 955
39d789d675fc
child 957
429c7ed3cc54

Replace LDIterate function with LDObjectIterator class

CMakeLists.txt file | annotate | diff | comparison | revisions
src/actions.cpp file | annotate | diff | comparison | revisions
src/actionsEdit.cpp file | annotate | diff | comparison | revisions
src/ldObject.cpp file | annotate | diff | comparison | revisions
src/ldObject.h file | annotate | diff | comparison | revisions
src/ldobjectiterator.h file | annotate | diff | comparison | revisions
--- a/CMakeLists.txt	Sat Aug 29 19:21:49 2015 +0300
+++ b/CMakeLists.txt	Sun Aug 30 03:04:39 2015 +0300
@@ -145,7 +145,7 @@
 # set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lGLU")
 
 if (NOT MSVC)
-	set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x -W -Wall")
+	set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x -W -Wall -Wno-maybe-uninitialized")
 endif()
 
 if (TRANSPARENT_DIRECT_COLORS)
--- a/src/actions.cpp	Sat Aug 29 19:21:49 2015 +0300
+++ b/src/actions.cpp	Sun Aug 30 03:04:39 2015 +0300
@@ -36,7 +36,7 @@
 #include "radioGroup.h"
 #include "colors.h"
 #include "glCompiler.h"
-#include "ui_newpart.h"
+#include "ldobjectiterator.h"
 #include "dialogs/ldrawpathdialog.h"
 #include "dialogs/newpartdialog.h"
 #include "editmodes/abstractEditMode.h"
@@ -759,8 +759,6 @@
 
 		int subidx = 1;
 		QString digits;
-		QFile f;
-		QString testfname;
 
 		// Now find the appropriate filename. Increase the number of the subfile
 		// until we find a name which isn't already taken.
@@ -778,15 +776,14 @@
 
 	// Determine the BFC winding type used in the main document - it is to
 	// be carried over to the subfile.
-	LDIterate<LDBFC> (CurrentDocument()->objects(), [&] (LDBFC* const& bfc)
+	for (LDObjectIterator<LDBFC> it (CurrentDocument()); it.isValid(); ++it)
 	{
-		if (Eq (bfc->statement(), BFCStatement::CertifyCCW, BFCStatement::CertifyCW, 
-			BFCStatement::NoCertify))
+		if (Eq (it->statement(), BFCStatement::CertifyCCW, BFCStatement::CertifyCW, BFCStatement::NoCertify))
 		{
-			bfctype = bfc->statement();
-			Break();
+			bfctype = it->statement();
+			break;
 		}
-	});
+	}
 
 	// Get the body of the document in LDraw code
 	for (LDObject* obj : Selection())
--- a/src/actionsEdit.cpp	Sat Aug 29 19:21:49 2015 +0300
+++ b/src/actionsEdit.cpp	Sun Aug 30 03:04:39 2015 +0300
@@ -36,6 +36,7 @@
 #include "ui_editraw.h"
 #include "ui_flip.h"
 #include "ui_addhistoryline.h"
+#include "ldobjectiterator.h"
 
 EXTERN_CFGENTRY (String, DefaultUser)
 
@@ -122,14 +123,14 @@
 {
 	LDObjectList sel = Selection();
 
-	LDIterate<LDSubfile> (Selection(), [&](LDSubfile* const& ref)
+	for (LDObjectIterator<LDSubfile> it (Selection()); it.isValid(); ++it)
 	{
 		// Get the index of the subfile so we know where to insert the
 		// inlined contents.
-		long idx = ref->lineNumber();
+		long idx = it->lineNumber();
 
 		assert (idx != -1);
-		LDObjectList objs = ref->inlineContents (deep, false);
+		LDObjectList objs = it->inlineContents (deep, false);
 
 		// Merge in the inlined objects
 		for (LDObject* inlineobj : objs)
@@ -142,8 +143,8 @@
 		}
 
 		// Delete the subfile now as it's been inlined.
-		ref->destroy();
-	});
+		it->destroy();
+	}
 }
 
 void MainWindow::slot_actionInline()
@@ -164,22 +165,22 @@
 {
 	int num = 0;
 
-	LDIterate<LDQuad> (Selection(), [&](LDQuad* const& quad)
+	for (LDObjectIterator<LDQuad> it (Selection()); it.isValid(); ++it)
 	{
 		// Find the index of this quad
-		long index = quad->lineNumber();
+		long index = it->lineNumber();
 
 		if (index == -1)
 			return;
 
-		QList<LDTriangle*> triangles = quad->splitToTriangles();
+		QList<LDTriangle*> triangles = it->splitToTriangles();
 
 		// Replace the quad with the first triangle and add the second triangle
 		// after the first one.
 		CurrentDocument()->setObject (index, triangles[0]);
 		CurrentDocument()->insertObj (index + 1, triangles[1]);
 		num++;
-	});
+	}
 
 	print ("%1 quadrilaterals split", num);
 	refresh();
@@ -595,13 +596,13 @@
 {
 	int num = 0;
 
-	LDIterate<LDCondLine> (Selection(), [&](LDCondLine* const& cnd)
+	for (LDObjectIterator<LDCondLine> it (Selection()); it.isValid(); ++it)
 	{
-		cnd->toEdgeLine();
+		it->toEdgeLine();
 		++num;
-	});
+	}
 
-	print (tr ("Demoted %1 conditional lines"), num);
+	print (tr ("Converted %1 conditional lines"), num);
 	refresh();
 }
 
--- a/src/ldObject.cpp	Sat Aug 29 19:21:49 2015 +0300
+++ b/src/ldObject.cpp	Sun Aug 30 03:04:39 2015 +0300
@@ -48,7 +48,8 @@
 	m_isHidden (false),
 	m_isSelected (false),
 	m_document (nullptr),
-	qObjListEntry (null)
+	qObjListEntry (null),
+	m_isDestroyed (false)
 {
 	if (document)
 		document->addObject (this);
@@ -78,22 +79,8 @@
 
 LDObject::~LDObject()
 {
-	// Don't bother during program termination
-	if (IsExiting() == false)
-	{
-		deselect();
-
-		// If this object was associated to a file, remove it off it now
-		if (document() != null)
-			document()->forgetObject (this);
-
-		// Delete the GL lists
-		if (g_win != null)
-			g_win->R()->forgetObject (this);
-
-		// Remove this object from the list of LDObjects
-		g_allObjects.erase (g_allObjects.find (id()));
-	}
+	if (not IsExiting() and not m_isDestroyed)
+		print ("Warning: Object #%1 was not destroyed before getting deleted\n", id());
 }
 
 // =============================================================================
@@ -314,6 +301,25 @@
 //
 void LDObject::destroy()
 {
+	// Don't bother during program termination (FIXME)
+	if (IsExiting() == false)
+	{
+		deselect();
+
+		// If this object was associated to a file, remove it off it now
+		if (document() != null)
+			document()->forgetObject (this);
+
+		// Delete the GL lists
+		if (g_win != null)
+			g_win->R()->forgetObject (this);
+
+		// Remove this object from the list of LDObjects
+		g_allObjects.erase (g_allObjects.find (id()));
+
+		m_isDestroyed = true;
+	}
+
 	delete this;
 }
 
--- a/src/ldObject.h	Sat Aug 29 19:21:49 2015 +0300
+++ b/src/ldObject.h	Sun Aug 30 03:04:39 2015 +0300
@@ -100,7 +100,6 @@
 
 public:
 	LDObject (LDDocument* document = nullptr);
-	virtual ~LDObject();
 
 	// This object as LDraw code
 	virtual QString				asText() const = 0;
@@ -189,13 +188,18 @@
 	static QString describeObjects (const LDObjectList& objs);
 	static LDObject* fromID (int id);
 	LDPolygon* getPolygon();
+	bool isDestroyed() const { return m_isDestroyed; }
 
 	// TODO: make this private!
 	QListWidgetItem* qObjListEntry;
 
+protected:
+	virtual ~LDObject();
+
 private:
 	Vertex m_coords[4];
-
+	bool m_isDestroyed;
+	
 	void chooseID();
 };
 
@@ -538,36 +542,4 @@
 	HighResolution = 48
 };
 
-QString PreferredLicenseText();
-
-template<typename T>
-inline void DynamicExecute (LDObject* obj, std::function<void (T*)> func)
-{
-	static_assert (std::is_base_of<LDObject, T>::value,
-		"DynamicExecute may only be used with LDObject-derivatives");
-
-	if (obj->type() == T::SubclassType)
-		func (static_cast<T*> (obj));
-}
-
-struct LDIterationBreakage {};
-
-template<typename T>
-inline void LDIterate (LDObjectList const& objs,
-	std::function<void (T*)> func)
-{
-	static_assert (std::is_base_of<LDObject, T>::value,
-		"LDIterate may only be used with LDObject-derivatives");
-
-	try
-	{
-		for (LDObject* const& obj : objs)
-			DynamicExecute<T> (obj, func);
-	}
-	catch (LDIterationBreakage) {}
-}
-
-inline void Break()
-{
-	throw LDIterationBreakage();
-}
+QString PreferredLicenseText();
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ldobjectiterator.h	Sun Aug 30 03:04:39 2015 +0300
@@ -0,0 +1,93 @@
+#pragma once
+#include "ldObject.h"
+#include "ldDocument.h"
+
+template<typename T>
+class LDObjectIterator
+{
+public:
+	LDObjectIterator (LDDocument* doc) :
+		m_list (doc->objects()),
+		m_i (-1)
+	{
+		seekTillValid();
+	}
+
+	LDObjectIterator (const LDObjectList& objs) :
+		m_list (objs),
+		m_i (-1)
+	{
+		seekTillValid();
+	}
+
+	bool outOfBounds() const
+	{
+		return m_i < 0 or m_i >= m_list.size();
+	}
+
+	T* get() const
+	{
+		return (T*) m_list[m_i];
+	}
+
+	bool isValid() const
+	{
+		return not outOfBounds() and get()->type() == T::SubclassType;
+	}
+
+	void seek (int i)
+	{
+		m_i = i;
+	}
+
+	void seekTillValid()
+	{
+		do ++m_i;
+		while (not outOfBounds() and not isValid());
+	}
+
+	void rewindTillValid()
+	{
+		do --m_i;
+		while (m_i >= 0 and not isValid());
+	}
+
+	int tell() const
+	{
+		return m_i;
+	}
+
+	T* operator*() const
+	{
+		return get();
+	}
+
+	T* operator->() const
+	{
+		return get();
+	}
+
+	void operator++()
+	{
+		seekTillValid();
+	}
+
+	void operator++ (int)
+	{
+		seekTillValid(); 
+	}
+
+	void operator--()
+	{
+		rewindTillValid();
+	}
+
+	void operator-- (int)
+	{
+		rewindTillValid();
+	}
+
+private:
+	const LDObjectList& m_list;
+	int m_i;
+};

mercurial