Refactor LDSubfile

Sat, 01 Jun 2013 22:01:27 +0300

author
Santeri Piippo <crimsondusk64@gmail.com>
date
Sat, 01 Jun 2013 22:01:27 +0300
changeset 269
2d71227f35cb
parent 268
778eed342ee4
child 270
f5f2353af0d9

Refactor LDSubfile

src/addObjectDialog.cpp file | annotate | diff | comparison | revisions
src/file.cpp file | annotate | diff | comparison | revisions
src/file.h file | annotate | diff | comparison | revisions
src/gui.cpp file | annotate | diff | comparison | revisions
src/gui_actions.cpp file | annotate | diff | comparison | revisions
src/gui_editactions.cpp file | annotate | diff | comparison | revisions
src/ldtypes.cpp file | annotate | diff | comparison | revisions
src/ldtypes.h file | annotate | diff | comparison | revisions
--- a/src/addObjectDialog.cpp	Sat Jun 01 21:36:03 2013 +0300
+++ b/src/addObjectDialog.cpp	Sat Jun 01 22:01:27 2013 +0300
@@ -138,7 +138,7 @@
 		
 		if (obj) {
 			LDSubfile* ref = static_cast<LDSubfile*> (obj);
-			le_subfileName->setText (ref->fileName);
+			le_subfileName->setText (ref->fileInfo ()->name ());
 		}
 		break;
 	
@@ -454,9 +454,8 @@
 			for (const Axis ax : g_Axes)
 				ref->setCoordinate (ax, dlg.dsb_coords[ax]->value ());
 			
-			ref->fileName = name;
 			ref->setTransform (transform);
-			ref->fileInfo = file;
+			ref->setFileInfo (file);
 		}
 		break;
 	
--- a/src/file.cpp	Sat Jun 01 21:36:03 2013 +0300
+++ b/src/file.cpp	Sat Jun 01 22:01:27 2013 +0300
@@ -681,11 +681,11 @@
 			CHECK_TOKEN_NUMBERS (1, 13)
 			
 			// Try open the file. Disable g_loadingMainFile temporarily since we're
-			// not loading the main file now, but the subfile
-			bool oldLoadingMainFile = g_loadingMainFile;
+			// not loading the main file now, but the subfile in question.
+			bool tmp = g_loadingMainFile;
 			g_loadingMainFile = false;
 			LDOpenFile* load = getFile (tokens[14]);
-			g_loadingMainFile = oldLoadingMainFile;
+			g_loadingMainFile = tmp;
 			
 			// If we cannot open the file, mark it an error
 			if (!load)
@@ -700,8 +700,7 @@
 				transform[i] = atof (tokens[i + 5]); // 5 - 13
 			
 			obj->setTransform (transform);
-			obj->fileName = tokens[14];
-			obj->fileInfo = load;
+			obj->setFileInfo (load);
 			return obj;
 		}
 	
@@ -789,23 +788,17 @@
 	if (!g_curfile)
 		return;
 	
-	// First, close all but the current open file.
-	for (LDOpenFile* file : g_loadedFiles)
-		if (file != g_curfile)
-			delete file;
-	
 	g_loadedFiles.clear ();
 	g_loadedFiles << g_curfile;
 	
 	// Go through all objects in the current file and reload the subfiles
 	for (LDObject* obj : g_curfile->objs ()) {
 		if (obj->getType() == LDObject::Subfile) {
-			// Note: ref->fileInfo is invalid right now since all subfiles were closed.
 			LDSubfile* ref = static_cast<LDSubfile*> (obj);
-			LDOpenFile* fileInfo = getFile (ref->fileName);
+			LDOpenFile* fileInfo = getFile (ref->fileInfo ()->name ());
 			
 			if (fileInfo)
-				ref->fileInfo = fileInfo;
+				ref->setFileInfo (fileInfo);
 			else {
 				// Couldn't load the file, mark it an error
 				ref->replace (new LDGibberish (ref->getContents (), "Could not open referred file"));
@@ -814,9 +807,12 @@
 		
 		// Reparse gibberish files. It could be that they are invalid because
 		// of loading errors. Circumstances may be different now.
-		if (obj->getType() == LDObject::Gibberish)
+		if (obj->getType () == LDObject::Gibberish)
 			obj->replace (parseLine (static_cast<LDGibberish*> (obj)->contents));
 	}
+	
+	// Close all files left unused
+	LDOpenFile::closeUnused ();
 }
 
 // =============================================================================
@@ -930,4 +926,51 @@
 void LDOpenFile::setObject (ulong idx, LDObject* obj) {
 	assert (idx < numObjs ());
 	m_objs[idx] = obj;
+}
+
+static vector<LDOpenFile*> getFilesUsed (LDOpenFile* node) {
+	vector<LDOpenFile*> filesUsed;
+	
+	for (LDObject* obj : *node) {
+		if (obj->getType () != LDObject::Subfile)
+			continue;
+		
+		LDSubfile* ref = static_cast<LDSubfile*> (obj);
+		filesUsed << ref->fileInfo ();
+		filesUsed << getFilesUsed (ref->fileInfo ());
+	}
+	
+	return filesUsed;
+}
+
+// =============================================================================
+// Find out which files are unused and close them.
+void LDOpenFile::closeUnused () {
+	vector<LDOpenFile*> filesUsed = getFilesUsed (g_curfile);
+	
+	// Also, anything that's explicitly opened must not be closed
+	for (LDOpenFile* file : g_loadedFiles)
+		if (file->implicit () == false)
+			filesUsed << file;
+	
+	// Remove duplicated entries
+	filesUsed.makeUnique ();
+	
+	// Close all open files that aren't in filesUsed
+	for (LDOpenFile* file : g_loadedFiles) {
+		bool isused = false;
+		
+		for (LDOpenFile* usedFile : filesUsed) {
+			if (file == usedFile) {
+				isused = true;
+				break;
+			}
+		}
+		
+		if (!isused)
+			delete file;
+	}
+	
+	g_loadedFiles.clear ();
+	g_loadedFiles << filesUsed;
 }
\ No newline at end of file
--- a/src/file.h	Sat Jun 01 21:36:03 2013 +0300
+++ b/src/file.h	Sat Jun 01 22:01:27 2013 +0300
@@ -48,12 +48,15 @@
 class LDOpenFile {
 	PROPERTY (str, name, setName)
 	PROPERTY (bool, implicit, setImplicit)
-	MUTABLE_READ_PROPERTY (vector<LDObject*>, objs)
+	MUTABLE_READ_PROPERTY (vector<LDObject*>, objs) // TODO: make this private!
 	PROPERTY (vector<LDObject*>, cache, setCache)
 	PROPERTY (long, savePos, setSavePos)
 	MUTABLE_READ_PROPERTY (History, history)
 	
 public:
+	typedef vector<LDObject*>::it it;
+	typedef vector<LDObject*>::c_it c_it;
+	
 	LDOpenFile ();
 	~LDOpenFile ();
 	
@@ -75,6 +78,13 @@
 	void insertObj (const ulong pos, LDObject* obj);
 	ulong numObjs () const { return m_objs.size (); }
 	void setObject (ulong idx, LDObject* obj);
+	
+	it begin () { return PROP_NAME (objs).begin (); }
+	c_it begin () const { return PROP_NAME (objs).begin (); }
+	it end () { return PROP_NAME (objs).end (); }
+	c_it end () const { return PROP_NAME (objs).end (); }
+	
+	static void closeUnused ();
 };
 
 // Close all current loaded files and start off blank.
--- a/src/gui.cpp	Sat Jun 01 21:36:03 2013 +0300
+++ b/src/gui.cpp	Sat Jun 01 22:01:27 2013 +0300
@@ -633,7 +633,7 @@
 			{
 				LDSubfile* ref = static_cast<LDSubfile*> (obj);
 				
-				descr.format ("%s %s, (", ref->fileName.chars (),
+				descr.format ("%s %s, (", ref->fileInfo ()->name ().chars (),
 					ref->position ().stringRep (true).chars ());
 				
 				for (short i = 0; i < 9; ++i)
--- a/src/gui_actions.cpp	Sat Jun 01 21:36:03 2013 +0300
+++ b/src/gui_actions.cpp	Sat Jun 01 22:01:27 2013 +0300
@@ -247,10 +247,10 @@
 	str refName;
 	
 	if (type == LDObject::Subfile) {
-		refName = static_cast<LDSubfile*> (g_win->sel ()[0])->fileName;
+		refName = static_cast<LDSubfile*> (g_win->sel ()[0])->fileInfo ()->name ();
 		
-		for (LDObject* pObj : g_win->sel ())
-			if (static_cast<LDSubfile*> (pObj)->fileName != refName)
+		for (LDObject* obj : g_win->sel ())
+			if (static_cast<LDSubfile*> (obj)->fileInfo ()->name () != refName)
 				return;
 	}
 	
@@ -259,7 +259,7 @@
 		if (obj->getType() != type)
 			continue;
 		
-		if (type == LDObject::Subfile && static_cast<LDSubfile*> (obj)->fileName != refName)
+		if (type == LDObject::Subfile && static_cast<LDSubfile*> (obj)->fileInfo ()->name () != refName)
 			continue;
 		
 		g_win->sel () << obj;
--- a/src/gui_editactions.cpp	Sat Jun 01 21:36:03 2013 +0300
+++ b/src/gui_editactions.cpp	Sat Jun 01 22:01:27 2013 +0300
@@ -174,8 +174,7 @@
 		prim->setPosition (rad->position ()); // inherit position
 		prim->setTransform (rad->transform ()); // inherit matrix
 		prim->setColor (rad->color ()); // inherit color
-		prim->fileName = name;
-		prim->fileInfo = file;
+		prim->setFileInfo (file);
 		
 		// Replace the radial with the primitive.
 		rad->replace (prim);
--- a/src/ldtypes.cpp	Sat Jun 01 21:36:03 2013 +0300
+++ b/src/ldtypes.cpp	Sat Jun 01 22:01:27 2013 +0300
@@ -81,7 +81,7 @@
 	str val = fmt ("1 %d %s ", color (), position ().stringRep (false).chars ());
 	val += transform ().stringRep ();
 	val += ' ';
-	val += fileName;
+	val += fileInfo ()->name ();
 	return val;
 }
 
@@ -262,14 +262,14 @@
 	vector<LDObject*> objs, objcache;
 	
 	// If we have this cached, just clone that
-	if (deep && fileInfo->cache ().size ()) {
-		for (LDObject* obj : fileInfo->cache ())
+	if (deep && fileInfo ()->cache ().size ()) {
+		for (LDObject* obj : fileInfo ()->cache ())
 			objs << obj->clone ();
 	} else {
 		if (!deep)
 			cache = false;
 		
-		for (LDObject* obj : fileInfo->objs ()) {
+		for (LDObject* obj : *fileInfo ()) {
 			// Skip those without schemantic meaning
 			switch (obj->getType ()) {
 			case LDObject::Comment:
@@ -313,7 +313,7 @@
 		}
 		
 		if (cache)
-			fileInfo->setCache (objcache);
+			fileInfo ()->setCache (objcache);
 	}
 	
 	// Transform the objects
--- a/src/ldtypes.h	Sat Jun 01 21:36:03 2013 +0300
+++ b/src/ldtypes.h	Sat Jun 01 22:01:27 2013 +0300
@@ -262,6 +262,8 @@
 // Represents a single code-1 subfile reference.
 // =============================================================================
 class LDSubfile : public LDObject, public LDMatrixObject {
+	PROPERTY (LDOpenFile*, fileInfo, setFileInfo)
+	
 public:
 	LDOBJ (Subfile)
 	LDOBJ_VERTICES (0)
@@ -269,9 +271,6 @@
 	LDOBJ_SCEMANTIC
 	LDOBJ_HAS_MATRIX
 	
-	str fileName; // Filename of the subpart (TODO: rid this too - use fileInfo->fileName instead)
-	LDOpenFile* fileInfo; // Pointer to opened file for this subfile. null if unopened.
-	
 	// Inlines this subfile. Note that return type is an array of heap-allocated
 	// LDObject-clones, they must be deleted one way or another.
 	vector<LDObject*> inlineContents (bool deep, bool cache);

mercurial