Sat, 01 Jun 2013 22:01:27 +0300
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);