- implicit documents are now auto-closed when rendered unused, in general, a LOT better document closing behavior

Thu, 19 Dec 2013 00:59:49 +0200

author
Santeri Piippo <crimsondusk64@gmail.com>
date
Thu, 19 Dec 2013 00:59:49 +0200
changeset 564
79b23e02dcf1
parent 563
10939452bf86
child 565
e403aad83f60

- implicit documents are now auto-closed when rendered unused, in general, a LOT better document closing behavior
- history should now behave properly for real

changelog.txt file | annotate | diff | comparison | revisions
src/document.cc file | annotate | diff | comparison | revisions
src/document.h file | annotate | diff | comparison | revisions
src/gldraw.cc file | annotate | diff | comparison | revisions
src/ldtypes.cc file | annotate | diff | comparison | revisions
src/ldtypes.h file | annotate | diff | comparison | revisions
src/main.cc file | annotate | diff | comparison | revisions
--- a/changelog.txt	Wed Dec 18 23:38:45 2013 +0200
+++ b/changelog.txt	Thu Dec 19 00:59:49 2013 +0200
@@ -10,13 +10,15 @@
 	the registry under Windows and into ~/.config/LDForge under Linux. Unfortunately this means settings get
 	lost during transition from version 0.2 and 0.3.
 - Added a new editing mode for drawing circles.
+- Major corrections to the primitive generator:
+	- Fixed: "Hi-Res" was not prepended to the names of 48/ primitives.
+	- Fixed: Checking the Hi-Res option would not allow segment values over 16.
+	- Added support for multiple spaces before the ring number.
 - Coordinate rounding now works properly, figures scientific notation and rounds subfile position and matrix.
 	Values are also now properly rounded instead of just floored, 1.2348 now rounds to 1.235 and not 1.234.
 	Subfile matrix values are rounded to 4 decimals, everything else to 3 decimals.
-- Corrections to the primitive generator:
-	- Fixed: "Hi-Res" was not prepended to the names of 48/ primitives.
-	- Fixed: Checking the Hi-Res option would not allow segment values over 16.
-	- Added support for multiple spaces before the ring number.
+- Implicitely-opened documents are now closed automatically when rendered unused, hopefully reducing memory
+	usage somewhat.
 - Changing to draw mode while in free camera now causes the camera to be changed to top.
 - Added config fields for default name/username/license. This data will be automatically filled
 	into forms that require such information.
--- a/src/document.cc	Wed Dec 18 23:38:45 2013 +0200
+++ b/src/document.cc	Thu Dec 19 00:59:49 2013 +0200
@@ -113,7 +113,8 @@
 // =============================================================================
 // -----------------------------------------------------------------------------
 LDDocument::LDDocument()
-{	setImplicit (true);
+{	setBeingDeleted (false);
+	setImplicit (true);
 	setSavePosition (-1);
 	setListItem (null);
 	setHistory (new History);
@@ -123,7 +124,14 @@
 // =============================================================================
 // -----------------------------------------------------------------------------
 LDDocument::~LDDocument()
-{	// Clear everything from the model
+{	// Remove this file from the list of files. This MUST be done FIRST, otherwise
+	// a ton of other functions will think this file is still valid when it is not!
+	g_loadedFiles.removeOne (this);
+
+	setBeingDeleted (true);
+	m_History->setIgnoring (true);
+
+	// Clear everything from the model
 	for (LDObject* obj : getObjects())
 		obj->deleteSelf();
 
@@ -133,9 +141,6 @@
 
 	delete m_History;
 
-	// Remove this file from the list of files
-	g_loadedFiles.removeOne (this);
-
 	// If we just closed the current file, we need to set the current
 	// file as something else.
 	if (this == getCurrentDocument())
@@ -155,7 +160,14 @@
 			newFile();
 	}
 
+	if (this == g_logoedStud)
+		g_logoedStud = null;
+	elif (this == g_logoedStud2)
+		g_logoedStud2 = null;
+
+	closeUnused();
 	g_win->updateDocumentList();
+	log ("Closed %1", getName());
 }
 
 // =============================================================================
@@ -909,9 +921,12 @@
 // -----------------------------------------------------------------------------
 void LDDocument::forgetObject (LDObject* obj)
 {	int idx = obj->getIndex();
+	obj->unselect();
 	assert (m_Objects[idx] == obj);
-	dlog ("id: %1, type: %2, code: %3", obj->getID(), obj->getType(), obj->raw());
-	getHistory()->add (new DelHistory (idx, obj));
+
+	if (!getHistory()->isIgnoring())
+		getHistory()->add (new DelHistory (idx, obj));
+
 	m_Objects.removeAt (idx);
 	obj->setFile (null);
 }
@@ -938,14 +953,16 @@
 		*m_History << new EditHistory (idx, oldcode, newcode);
 	}
 
+	m_Objects[idx]->unselect();
+	m_Objects[idx]->setFile (null);
 	obj->setFile (this);
 	m_Objects[idx] = obj;
 }
 
 // =============================================================================
 // -----------------------------------------------------------------------------
-static QList<LDDocument*> getFilesUsed (LDDocument* node)
-{	QList<LDDocument*> filesUsed;
+static void getFilesUsed (LDDocument* node, QList<LDDocument*>& filesUsed)
+{	filesUsed << node;
 
 	for (LDObject* obj : node->getObjects())
 	{	if (obj->getType() != LDObject::Subfile)
@@ -953,43 +970,44 @@
 
 		LDSubfile* ref = static_cast<LDSubfile*> (obj);
 		filesUsed << ref->getFileInfo();
-		filesUsed << getFilesUsed (ref->getFileInfo());
+		getFilesUsed (ref->getFileInfo(), filesUsed);
 	}
-
-	return filesUsed;
 }
 
 // =============================================================================
 // Find out which files are unused and close them.
 // -----------------------------------------------------------------------------
+static bool g_closingUnusedFiles = false;
+
 void LDDocument::closeUnused()
-{	QList<LDDocument*> filesUsed = getFilesUsed (getCurrentDocument());
+{	// Don't go here more than once at a time, otherwise we risk double-deletions
+	if (g_closingUnusedFiles)
+		return;
 
-	// Anything that's explicitly opened must not be closed
+	QList<LDDocument*> filesUsed;
+	g_closingUnusedFiles = true;
+
+	// Anything that's explicitly opened must not be closed.
+	// Also do not close anything used by anything explicit
 	for (LDDocument* file : g_loadedFiles)
 		if (!file->isImplicit())
-			filesUsed << file;
+			getFilesUsed (file, filesUsed);
+
+	// Savor the logoed studs if we use them
+	if (gl_logostuds && g_logoedStud && g_logoedStud2)
+	{	getFilesUsed (g_logoedStud, filesUsed);
+		getFilesUsed (g_logoedStud2, filesUsed);
+	}
 
 	// Remove duplicated entries
 	removeDuplicates (filesUsed);
 
 	// Close all open files that aren't in filesUsed
 	for (LDDocument* file : g_loadedFiles)
-	{	bool isused = false;
+		if (!filesUsed.contains (file))
+			delete file;
 
-		for (LDDocument* usedFile : filesUsed)
-		{	if (file == usedFile)
-			{	isused = true;
-				break;
-			}
-		}
-
-		if (!isused)
-			delete file;
-	}
-
-	g_loadedFiles.clear();
-	g_loadedFiles << filesUsed;
+	g_closingUnusedFiles = false;
 }
 
 // =============================================================================
@@ -1032,7 +1050,10 @@
 	// stud.dat -> stud-logo.dat
 	// stud2.dat -> stud-logo2.dat
 	if (gl_logostuds && (flags & LDSubfile::RendererInline))
-	{	if (getName() == "stud.dat" && g_logoedStud)
+	{	// Ensure logoed studs are loaded first
+		loadLogoedStuds();
+
+		if (getName() == "stud.dat" && g_logoedStud)
 			return g_logoedStud->inlineContents (flags);
 		elif (getName() == "stud2.dat" && g_logoedStud2)
 			return g_logoedStud2->inlineContents (flags);
@@ -1118,7 +1139,6 @@
 		g_win->R()->setFile (f);
 		g_win->R()->resetAllAngles();
 		g_win->R()->repaint();
-
 		log ("Changed file to %1", f->getShortName());
 	}
 }
@@ -1142,7 +1162,8 @@
 void LDDocument::closeInitialFile()
 {	if (
 		countExplicitFiles() == 2 &&
-		g_loadedFiles[0]->getName() == "" &&
+		g_loadedFiles[0]->getName().isEmpty() &&
+		g_loadedFiles[1]->getName().isEmpty() == false &&
 		!g_loadedFiles[0]->hasUnsavedChanges()
 	)
 		delete g_loadedFiles[0];
@@ -1151,13 +1172,16 @@
 // =============================================================================
 // -----------------------------------------------------------------------------
 void loadLogoedStuds()
-{	log ("Loading logoed studs...\n");
+{	if (g_logoedStud && g_logoedStud2)
+		return;
 
 	delete g_logoedStud;
 	delete g_logoedStud2;
 
 	g_logoedStud = openDocument ("stud-logo.dat", true);
 	g_logoedStud2 = openDocument ("stud2-logo.dat", true);
+
+	log (LDDocument::tr ("Logoed studs loaded.\n"));
 }
 
 // =============================================================================
--- a/src/document.h	Wed Dec 18 23:38:45 2013 +0200
+++ b/src/document.h	Thu Dec 19 00:59:49 2013 +0200
@@ -62,6 +62,7 @@
 		PROPERTY (public,		QList<LDObject*>,	Cache,			NO_OPS,		STOCK_WRITE)
 		PROPERTY (public,		long,					SavePosition,	NUM_OPS,		STOCK_WRITE)
 		PROPERTY (public,		QListWidgetItem*, ListItem,		NO_OPS,		STOCK_WRITE)
+		PROPERTY (private,	bool,					BeingDeleted,	BOOL_OPS,	STOCK_WRITE)
 
 	public:
 		LDDocument();
--- a/src/gldraw.cc	Wed Dec 18 23:38:45 2013 +0200
+++ b/src/gldraw.cc	Thu Dec 19 00:59:49 2013 +0200
@@ -209,7 +209,8 @@
 // =============================================================================
 // -----------------------------------------------------------------------------
 void GLRenderer::resetAllAngles()
-{	EFixedCamera oldcam = camera();
+{	/*
+	EFixedCamera oldcam = camera();
 
 	for (int i = 0; i < 7; ++i)
 	{	setCamera ((EFixedCamera) i);
@@ -217,6 +218,8 @@
 	}
 
 	setCamera (oldcam);
+	*/
+	resetAngles();
 }
 
 // =============================================================================
@@ -1823,7 +1826,8 @@
 // =============================================================================
 // -----------------------------------------------------------------------------
 void GLRenderer::zoomAllToFit()
-{	EFixedCamera oldcam = camera();
+{	/*
+	EFixedCamera oldcam = camera();
 
 	for (int i = 0; i < 7; ++i)
 	{	setCamera ((EFixedCamera) i);
@@ -1831,6 +1835,9 @@
 	}
 
 	setCamera (oldcam);
+	*/
+
+	zoomToFit();
 }
 
 // =============================================================================
--- a/src/ldtypes.cc	Wed Dec 18 23:38:45 2013 +0200
+++ b/src/ldtypes.cc	Thu Dec 19 00:59:49 2013 +0200
@@ -273,6 +273,13 @@
 
 // =============================================================================
 // -----------------------------------------------------------------------------
+LDSubfile::~LDSubfile()
+{	// The document this subfile referenced may be unused now, delete if needed.
+	LDDocument::closeUnused();
+}
+
+// =============================================================================
+// -----------------------------------------------------------------------------
 void LDObject::deleteSelf()
 {	// If this object was selected, unselect it now
 	if (isSelected())
--- a/src/ldtypes.h	Wed Dec 18 23:38:45 2013 +0200
+++ b/src/ldtypes.h	Thu Dec 19 00:59:49 2013 +0200
@@ -24,7 +24,6 @@
 
 #define LDOBJ(T) \
 protected: \
-	virtual ~LD##T() {} \
 	virtual LD##T* clone() override { \
 		return new LD##T (*this); \
 	} \
@@ -398,6 +397,9 @@
 		// Inlines this subfile. Note that return type is an array of heap-allocated
 		// LDObject copies, they must be deleted manually.
 		QList<LDObject*> inlineContents (InlineFlags flags);
+
+	protected:
+		~LDSubfile();
 };
 
 Q_DECLARE_OPERATORS_FOR_FLAGS (LDSubfile::InlineFlags)
--- a/src/main.cc	Wed Dec 18 23:38:45 2013 +0200
+++ b/src/main.cc	Thu Dec 19 00:59:49 2013 +0200
@@ -68,8 +68,6 @@
 
 	LDPaths::initPaths();
 	initColors();
-	loadLogoedStuds();
-
 	ForgeWindow* win = new ForgeWindow;
 	newFile();
 	win->show();

mercurial